- split the main MAC configuration (was TKN154P.nc) in two: one for beacon-enabled mode the other for nonbeacon-enabled mode (this decision has to be made at compile time now)
- added (serial) debugging functions (compile with "TKN154_DEBUG=1 make telosb" and use the java PrintfClient, see tinyos-2.x/apps/tests/TestPrintf/README.txt)
- improved readability, added comments
PFLAGS += -DIEEE154_EXTENDED_ADDRESS=$(IEEE154_EXTENDED_ADDRESS)
endif
+ifdef TKN154_DEBUG
+PFLAGS += -DTKN154_DEBUG
+CFLAGS += -I$(TOSDIR)/lib/printf
+PFLAGS += -DPRINTF_BUFFER_SIZE=1000
+endif
+
# parses the PLATFORM variable
include $(MAKERULES)
configuration TestAssociateAppC
{
} implementation {
- components MainC, LedsC, Ieee802154MacC as Ieee802154MacC;
+ components MainC, LedsC, Ieee802154BeaconEnabledC as MAC;
components TestCoordC as App;
MainC.Boot <- App;
App.Leds -> LedsC;
- App.MLME_RESET -> Ieee802154MacC;
- App.MLME_SET -> Ieee802154MacC;
- App.MLME_GET -> Ieee802154MacC;
+ App.MLME_RESET -> MAC;
+ App.MLME_SET -> MAC;
+ App.MLME_GET -> MAC;
- App.MLME_START -> Ieee802154MacC;
- App.MLME_ASSOCIATE -> Ieee802154MacC;
- App.MLME_DISASSOCIATE -> Ieee802154MacC;
- App.MLME_COMM_STATUS -> Ieee802154MacC;
- App.Frame -> Ieee802154MacC;
- App.IEEE154TxBeaconPayload -> Ieee802154MacC;
+ App.MLME_START -> MAC;
+ App.MLME_ASSOCIATE -> MAC;
+ App.MLME_DISASSOCIATE -> MAC;
+ App.MLME_COMM_STATUS -> MAC;
+ App.Frame -> MAC;
+ App.IEEE154TxBeaconPayload -> MAC;
}
uint16_t m_shortAddress;
event void Boot.booted() {
- call MLME_RESET.request(TRUE, BEACON_ENABLED_PAN);
+ call MLME_RESET.request(TRUE);
}
event void MLME_RESET.confirm(ieee154_status_t status)
configuration TestAssociateAppC
{
} implementation {
- components MainC, LedsC, Ieee802154MacC as Ieee802154MacC,
+ components MainC, LedsC, Ieee802154BeaconEnabledC as MAC,
new Timer62500C() as Timer;
components TestDeviceC as App;
MainC.Boot <- App;
App.Leds -> LedsC;
- App.MLME_RESET -> Ieee802154MacC;
- App.MLME_SET -> Ieee802154MacC;
- App.MLME_GET -> Ieee802154MacC;
+ App.MLME_RESET -> MAC;
+ App.MLME_SET -> MAC;
+ App.MLME_GET -> MAC;
App.DisassociateTimer -> Timer;
- App.MLME_SCAN -> Ieee802154MacC;
- App.MLME_SYNC -> Ieee802154MacC;
- App.MLME_BEACON_NOTIFY -> Ieee802154MacC;
- App.MLME_SYNC_LOSS -> Ieee802154MacC;
- App.MLME_ASSOCIATE -> Ieee802154MacC;
- App.MLME_DISASSOCIATE -> Ieee802154MacC;
- App.MLME_COMM_STATUS -> Ieee802154MacC;
- App.BeaconFrame -> Ieee802154MacC;
+ App.MLME_SCAN -> MAC;
+ App.MLME_SYNC -> MAC;
+ App.MLME_BEACON_NOTIFY -> MAC;
+ App.MLME_SYNC_LOSS -> MAC;
+ App.MLME_ASSOCIATE -> MAC;
+ App.MLME_DISASSOCIATE -> MAC;
+ App.MLME_COMM_STATUS -> MAC;
+ App.BeaconFrame -> MAC;
}
m_capabilityInformation.Reserved = 0;
m_capabilityInformation.SecurityCapability = 0;
m_capabilityInformation.AllocateAddress = 1;
- call MLME_RESET.request(TRUE, BEACON_ENABLED_PAN);
+ call MLME_RESET.request(TRUE);
}
event void MLME_RESET.confirm(ieee154_status_t status)
BEACON_ORDER = 5,
SUPERFRAME_ORDER = 5,
};
+//#define IEEE154_DEFAULT_TRANSMITPOWER_dBm -25
#endif
bool m_ledCount;
event void Boot.booted() {
- call MLME_RESET.request(TRUE, BEACON_ENABLED_PAN);
+ call MLME_RESET.request(TRUE);
}
event void MLME_RESET.confirm(ieee154_status_t status)
* @author: Jan Hauer <hauer@tkn.tu-berlin.de>
* ========================================================================
*/
-
+#include "app_profile.h"
configuration TestDataAppC
{
} implementation {
- components MainC, LedsC, Ieee802154MacC;
+ components MainC, LedsC, Ieee802154BeaconEnabledC as MAC;
components TestCoordReceiverC as App;
- App.MLME_START -> Ieee802154MacC;
- App.MCPS_DATA -> Ieee802154MacC;
- App.Frame -> Ieee802154MacC;
+ App.MLME_START -> MAC;
+ App.MCPS_DATA -> MAC;
+ App.Frame -> MAC;
MainC.Boot <- App;
App.Leds -> LedsC;
- App.MLME_RESET -> Ieee802154MacC;
- App.MLME_SET -> Ieee802154MacC;
- App.MLME_GET -> Ieee802154MacC;
- App.IEEE154TxBeaconPayload -> Ieee802154MacC;
+ App.MLME_RESET -> MAC;
+ App.MLME_SET -> MAC;
+ App.MLME_GET -> MAC;
+ App.IEEE154TxBeaconPayload -> MAC;
}
COMPONENT=TestDataAppC
+PFLAGS += -DIEEE154_BEACON_TX_DISABLED
CFLAGS += -I$(shell pwd)/..
include ../../Makefile.include
* @author: Jan Hauer <hauer@tkn.tu-berlin.de>
* ========================================================================
*/
-
+#include "app_profile.h"
configuration TestDataAppC
{
} implementation {
- components MainC, LedsC, Ieee802154MacC;
+ components MainC, LedsC, Ieee802154BeaconEnabledC as MAC;
components TestDeviceSenderC as App;
- App.MLME_SCAN -> Ieee802154MacC;
- App.MLME_SYNC -> Ieee802154MacC;
- App.MLME_BEACON_NOTIFY -> Ieee802154MacC;
- App.MLME_SYNC_LOSS -> Ieee802154MacC;
- App.MCPS_DATA -> Ieee802154MacC;
- App.Frame -> Ieee802154MacC;
- App.BeaconFrame -> Ieee802154MacC;
- App.Packet -> Ieee802154MacC;
+ App.MLME_SCAN -> MAC;
+ App.MLME_SYNC -> MAC;
+ App.MLME_BEACON_NOTIFY -> MAC;
+ App.MLME_SYNC_LOSS -> MAC;
+ App.MCPS_DATA -> MAC;
+ App.Frame -> MAC;
+ App.BeaconFrame -> MAC;
+ App.Packet -> MAC;
MainC.Boot <- App;
App.Leds -> LedsC;
- App.MLME_RESET -> Ieee802154MacC;
- App.MLME_SET -> Ieee802154MacC;
- App.MLME_GET -> Ieee802154MacC;
+ App.MLME_RESET -> MAC;
+ App.MLME_SET -> MAC;
+ App.MLME_GET -> MAC;
}
payloadRegion = call Packet.getPayload(&m_frame, m_payloadLen);
if (m_payloadLen <= call Packet.maxPayloadLength()){
memcpy(payloadRegion, payload, m_payloadLen);
- call MLME_RESET.request(TRUE, BEACON_ENABLED_PAN);
+ call MLME_RESET.request(TRUE);
}
}
0 // security
);
}
+ bool m_ready;
event message_t* MLME_BEACON_NOTIFY.indication (message_t* frame)
{
ieee154_phyCurrentPage_t page = call MLME_GET.phyCurrentPage();
ieee154_macBSN_t beaconSequenceNumber = call BeaconFrame.getBSN(frame);
+ if (m_ready)
+ post packetSendTask();
if (beaconSequenceNumber & 1)
call Leds.led2On();
else
NULL // security
);
post packetSendTask();
+ m_ready = TRUE;
} else
startApp();
}
&m_frame, // frame,
m_payloadLen, // payloadLength,
0, // msduHandle,
- TX_OPTIONS_ACK // TxOptions,
+ TX_OPTIONS_ACK // TxOptions,
) == IEEE154_SUCCESS)
m_sending = TRUE;
}
+ uint8_t m_useLeds = TRUE;
event void MCPS_DATA.confirm (
message_t *msg,
uint8_t msduHandle,
m_sending = FALSE;
if (status == IEEE154_SUCCESS && m_ledCount++ == 20){
m_ledCount = 0;
- call Leds.led1Toggle();
+ if (m_useLeds)
+ call Leds.led1Toggle();
}
post packetSendTask();
}
uint8_t ChannelPage,
ieee154_security_t *security)
{
- startApp();
+ m_useLeds = FALSE;
+ call Leds.led1Off();
+ //startApp();
}
event message_t* MCPS_DATA.indication (message_t* frame)
&deviceShortAddress, // DstAddr,
NULL // security
);
- call MLME_RESET.request(TRUE, BEACON_ENABLED_PAN);
+ call MLME_RESET.request(TRUE);
}
}
configuration TestIndirectAppC
{
} implementation {
- components MainC, LedsC, Ieee802154MacC;
+ components MainC, LedsC, Ieee802154BeaconEnabledC as MAC;
components TestCoordSenderC as App;
MainC.Boot <- App;
App.Leds -> LedsC;
- App.MLME_RESET -> Ieee802154MacC;
- App.MLME_SET -> Ieee802154MacC;
- App.MLME_GET -> Ieee802154MacC;
- App.MLME_START -> Ieee802154MacC;
- App.MCPS_DATA -> Ieee802154MacC;
- App.Frame -> Ieee802154MacC;
- App.IEEE154TxBeaconPayload -> Ieee802154MacC;
- App.Packet -> Ieee802154MacC;
+ App.MLME_RESET -> MAC;
+ App.MLME_SET -> MAC;
+ App.MLME_GET -> MAC;
+ App.MLME_START -> MAC;
+ App.MCPS_DATA -> MAC;
+ App.Frame -> MAC;
+ App.IEEE154TxBeaconPayload -> MAC;
+ App.Packet -> MAC;
}
void startApp();
event void Boot.booted() {
- call MLME_RESET.request(TRUE, BEACON_ENABLED_PAN);
+ call MLME_RESET.request(TRUE);
}
event void MLME_RESET.confirm(ieee154_status_t status)
{
// received a beacon frame during SCAN
ieee154_phyCurrentPage_t page = call MLME_GET.phyCurrentPage();
+ ieee154_macBSN_t beaconSequenceNumber = call BeaconFrame.getBSN(frame);
+
+ if (beaconSequenceNumber & 1)
+ call Leds.led2On();
+ else
+ call Leds.led2Off();
if (!m_isPANDescriptorValid && call BeaconFrame.parsePANDescriptor(
frame, RADIO_CHANNEL, page, &m_PANDescriptor) == SUCCESS){
configuration TestIndirectAppC
{
} implementation {
- components MainC, LedsC, Ieee802154MacC;
+ components MainC, LedsC, Ieee802154BeaconEnabledC as MAC;
components TestDeviceReceiverC as App;
MainC.Boot <- App;
App.Leds -> LedsC;
- App.MLME_RESET -> Ieee802154MacC;
- App.MLME_SET -> Ieee802154MacC;
- App.MLME_GET -> Ieee802154MacC;
- App.MLME_SCAN -> Ieee802154MacC;
- App.MLME_SYNC -> Ieee802154MacC;
- App.MLME_BEACON_NOTIFY -> Ieee802154MacC;
- App.MLME_SYNC_LOSS -> Ieee802154MacC;
- App.MCPS_DATA -> Ieee802154MacC;
- App.BeaconFrame -> Ieee802154MacC;
+ App.MLME_RESET -> MAC;
+ App.MLME_SET -> MAC;
+ App.MLME_GET -> MAC;
+ App.MLME_SCAN -> MAC;
+ App.MLME_SYNC -> MAC;
+ App.MLME_BEACON_NOTIFY -> MAC;
+ App.MLME_SYNC_LOSS -> MAC;
+ App.MCPS_DATA -> MAC;
+ App.BeaconFrame -> MAC;
}
COMPONENT=TestPromiscuousAppC
-PFLAGS += -DIEEE154_BEACON_TX_DISABLED -DIEEE154_BEACON_SYNC_DISABLED -DIEEE154_SCAN_DISABLED
PFLAGS += -DPRINTF_BUFFER_SIZE=1000
CFLAGS += -I$(TOSDIR)/lib/printf
CFLAGS += -DIEEE154_SCAN_DISABLED -DIEEE154_BEACON_SYNC_DISABLED -DIEEE154_BEACON_TX_DISABLED -DIEEE154_RXENABLE_DISABLED -DIEEE154_ASSOCIATION_DISABLED -DIEEE154_DISASSOCIATION_DISABLED -DIEEE154_COORD_REALIGNMENT_DISABLED -DIEEE154_COORD_BROADCAST_DISABLED
{
} implementation {
components MainC, TestPromiscuousC as App, LedsC,
- Ieee802154MacC as Ieee802154MacC;
+ Ieee802154BeaconEnabledC as MAC;
MainC.Boot <- App;
App.Leds -> LedsC;
- App.MLME_RESET -> Ieee802154MacC;
- App.MLME_SET -> Ieee802154MacC;
- App.MLME_GET -> Ieee802154MacC;
- App.MCPS_DATA -> Ieee802154MacC;
- App.Frame -> Ieee802154MacC;
- App.BeaconFrame -> Ieee802154MacC;
- App.PromiscuousMode -> Ieee802154MacC;
+ App.MLME_RESET -> MAC;
+ App.MLME_SET -> MAC;
+ App.MLME_GET -> MAC;
+ App.MCPS_DATA -> MAC;
+ App.Frame -> MAC;
+ App.BeaconFrame -> MAC;
+ App.PromiscuousMode -> MAC;
}
};
event void Boot.booted() {
- call MLME_RESET.request(TRUE, BEACON_ENABLED_PAN);
+ call MLME_RESET.request(TRUE);
}
event void MLME_RESET.confirm(ieee154_status_t status)
uint8_t m_beaconPayload[] = {0x01, 0x02, 0x03, 0x04, 0x05};
event void Boot.booted() {
- call MLME_RESET.request(TRUE, BEACON_ENABLED_PAN);
+ call MLME_RESET.request(TRUE);
}
event void MLME_RESET.confirm(ieee154_status_t status)
{
} implementation {
- components MainC, LedsC, Ieee802154MacC as Ieee802154MacC;
+ components MainC, LedsC, Ieee802154BeaconEnabledC as MAC;
components TestCoordC as App;
MainC.Boot <- App;
- App.MLME_START -> Ieee802154MacC;
- App.IEEE154TxBeaconPayload -> Ieee802154MacC;
+ App.MLME_START -> MAC;
+ App.IEEE154TxBeaconPayload -> MAC;
App.Leds -> LedsC;
- App.MLME_RESET -> Ieee802154MacC;
- App.MLME_SET -> Ieee802154MacC;
- App.MLME_GET -> Ieee802154MacC;
+ App.MLME_RESET -> MAC;
+ App.MLME_SET -> MAC;
+ App.MLME_GET -> MAC;
}
void startApp();
event void Boot.booted() {
- call MLME_RESET.request(TRUE, BEACON_ENABLED_PAN);
+ call MLME_RESET.request(TRUE);
}
event void MLME_RESET.confirm(ieee154_status_t status)
void startApp()
{
- ieee154_phyChannelsSupported_t supportedChannels;
+ ieee154_phyChannelsSupported_t scanChannels;
uint8_t scanDuration = BEACON_ORDER;
// set the short address to whatever was passed
// as a parameter to make system ("make install,X")
call MLME_SET.macShortAddress(TOS_NODE_ID);
- supportedChannels = call MLME_GET.phyChannelsSupported();
+ scanChannels = call MLME_GET.phyChannelsSupported();
+ //scanChannels = (uint32_t) 1 << RADIO_CHANNEL;
// setting the macAutoRequest attribute to TRUE means
// that during the scan beacons will not be signalled
call MLME_SET.macAutoRequest(TRUE);
call MLME_SCAN.request (
PASSIVE_SCAN, // ScanType
- supportedChannels, // ScanChannels
+ scanChannels, // ScanChannels
scanDuration, // ScanDuration
0x00, // ChannelPage
0, // EnergyDetectListNumEntries
{
} implementation {
- components MainC, LedsC, Ieee802154MacC as Ieee802154MacC;
+ components MainC, LedsC, Ieee802154BeaconEnabledC as MAC;
components TestDeviceC as App;
- App.MLME_SCAN -> Ieee802154MacC;
- App.MLME_SYNC -> Ieee802154MacC;
- App.MLME_BEACON_NOTIFY -> Ieee802154MacC;
- App.MLME_SYNC_LOSS -> Ieee802154MacC;
- App.BeaconFrame -> Ieee802154MacC;
+ App.MLME_SCAN -> MAC;
+ App.MLME_SYNC -> MAC;
+ App.MLME_BEACON_NOTIFY -> MAC;
+ App.MLME_SYNC_LOSS -> MAC;
+ App.BeaconFrame -> MAC;
MainC.Boot <- App;
App.Leds -> LedsC;
- App.MLME_RESET -> Ieee802154MacC;
- App.MLME_SET -> Ieee802154MacC;
- App.MLME_GET -> Ieee802154MacC;
+ App.MLME_RESET -> MAC;
+ App.MLME_SET -> MAC;
+ App.MLME_GET -> MAC;
#ifdef PRINTF_ENABLED
components PrintfC;
uses interface CC2420Strobe as SFLUSHRX;
uses interface CC2420Register as TXCTRL;
uses interface AMPacket;
-
uses interface Resource as SpiResource;
-
- uses interface Leds;
uses interface FrameUtility;
}
// Always read at least one byte from the RXFIFO before
// issuing the SFLUSHRX command strobe" (CC2420 Datasheet)
call CSN.clr();
- call RXFIFO_REGISTER.read(&dummy); // reading 1 byte would be enough...
+ call RXFIFO_REGISTER.read(&dummy); // reading the byte
call CSN.set();
call CSN.clr();
// "SFLUSHRX command strobe should be issued twice to ensure
async command bool CC2420Config.needsSync(){
atomic return m_needsSync;
}
+
/**
* Sync must be called to commit software parameters configured on
* the microcontroller (through the CC2420Config interface) to the
interface Alarm<T62500hz,uint32_t> as AckAlarm;
interface CaptureTime;
interface ReferenceTime;
- interface Leds;
}
}
CC2420Config = CC2420ControlP;
CC2420Power = CC2420ControlP;
FrameUtility = CC2420ControlP;
- CC2420ControlP.Leds = Leds;
components MainC;
MainC.SoftwareInit -> CC2420ControlP;
AckAlarm = CC2420TransmitP;
CaptureTime = CC2420TransmitP;
ReferenceTime = CC2420TransmitP;
- CC2420TransmitP.Leds = Leds;
MainC.SoftwareInit -> CC2420TransmitP;
CC2420TransmitP.CCA -> Pins.CCA;
CC2420TransmitP.CSN -> Pins.CSN;
CC2420TransmitP.SFD -> Pins.SFD;
CC2420TransmitP.CaptureSFD -> Interrupts.CaptureSFD;
+ CC2420TransmitP.FIFOP -> Pins.FIFOP;
+ CC2420TransmitP.FIFO -> Pins.FIFO;
CC2420TransmitP.ChipSpiResource -> Spi;
CC2420TransmitP.SNOP -> Spi.SNOP;
/**
* Read RSSI from the radio.
- * @return SUCCESS if RSSI was read successfulyy, FAIL otherwise.
+ * @return SUCCESS if RSSI was read successfully, FAIL otherwise.
*/
async command error_t rssi(int8_t *rssi);
*
* @param time at which the capture happened.
*/
- async command void sfd( ieee154_reftime_t *time );
+ async command void sfd( ieee154_timestamp_t *time );
/**
* Notification that the packet has been dropped by the radio
provides interface CC2420Receive; // to CC2420TransmitP for ACK
provides interface CC2420Rx; // to the driver
uses interface ReferenceTime;
- uses interface Leds;
uses interface FrameUtility;
uses interface CC2420Config;
}
components HplCC2420PinsC as Pins;
components HplCC2420InterruptsC as InterruptsC;
- CC2420ReceiveP.Leds = Leds;
CC2420AsyncSplitControl = CC2420ReceiveP;
CC2420Receive = CC2420ReceiveP;
CC2420Rx = CC2420ReceiveP;
uses interface FrameUtility;
uses interface CC2420Config;
uses interface CC2420Ram as RXFIFO_RAM;
-
- uses interface Leds;
}
implementation {
SACK_HEADER_LENGTH = 3,
};
- ieee154_reftime_t m_timestamp_queue[ TIMESTAMP_QUEUE_SIZE ];
- ieee154_reftime_t m_timestamp;
+ ieee154_timestamp_t m_timestamp_queue[ TIMESTAMP_QUEUE_SIZE ];
+ ieee154_timestamp_t m_timestamp;
norace bool m_timestampValid;
uint8_t m_timestamp_head;
// because we don't own the SPI...
return FAIL;
}
- if (m_state != S_STOPPED){
- call Leds.led0On();
- return FAIL;
- }
+ ASSERT(m_state == S_STOPPED);
reset_state();
m_state = S_STARTED;
call InterruptFIFOP.enableFallingEdge(); // ready!
task void stopContinueTask()
{
- if (receivingPacket)
- call Leds.led0On();
+ ASSERT(receivingPacket != TRUE);
call SpiResource.release(); // may fail
atomic m_state = S_STOPPED;
signal AsyncSplitControl.stopDone(SUCCESS);
* Start frame delimiter signifies the beginning/end of a packet
* See the CC2420 datasheet for details.
*/
- async command void CC2420Receive.sfd( ieee154_reftime_t *time ) {
+ async command void CC2420Receive.sfd( ieee154_timestamp_t *time ) {
if (m_state == S_STOPPED)
return;
if ( m_timestamp_size < TIMESTAMP_QUEUE_SIZE ) {
uint8_t tail = ( ( m_timestamp_head + m_timestamp_size ) %
TIMESTAMP_QUEUE_SIZE );
- memcpy(&m_timestamp_queue[ tail ], time, sizeof(ieee154_reftime_t) );
+ memcpy(&m_timestamp_queue[ tail ], time, sizeof(ieee154_timestamp_t) );
m_timestamp_size++;
}
}
atomic {
switch (m_state)
{
- case S_STOPPED: // this should never happen!
- call Leds.led0On();
- call SpiResource.release();
- break;
+ case S_STOPPED: ASSERT(0); break; // this should never happen!
default: receive();
}
}
}
if ( m_timestamp_size ) {
- if ( rxFrameLength > 10 ) {
+ if ( rxFrameLength > 4 ) {
//((ieee154_metadata_t*) m_rxFramePtr->metadata)->timestamp = m_timestamp_queue[ m_timestamp_head ];
- memcpy(&m_timestamp, &m_timestamp_queue[ m_timestamp_head ], sizeof(ieee154_reftime_t) );
+ memcpy(&m_timestamp, &m_timestamp_queue[ m_timestamp_head ], sizeof(ieee154_timestamp_t) );
m_timestampValid = TRUE;
m_timestamp_head = ( m_timestamp_head + 1 ) % TIMESTAMP_QUEUE_SIZE;
m_timestamp_size--;
uint8_t payloadLen = ((ieee154_header_t*) m_rxFramePtr->header)->length - m_mhrLen - 2;
ieee154_metadata_t *metadata = (ieee154_metadata_t*) m_rxFramePtr->metadata;
- atomic {
- if (m_state == S_STOPPED){
- call Leds.led0On();
- return;
- }
- }
+ atomic ASSERT(m_state != S_STOPPED);
((ieee154_header_t*) m_rxFramePtr->header)->length = m_rxFramePtr->data[payloadLen+1] & 0x7f; // temp. LQI
metadata->rssi = m_rxFramePtr->data[payloadLen];
metadata->linkQuality = ((ieee154_header_t*) m_rxFramePtr->header)->length; // copy back
* Receive a packet buffer, returning a buffer for the signaling
* component to use for the next reception.
*/
- event message_t* received(message_t *data, ieee154_reftime_t *timestamp);
+ event message_t* received(message_t *data, ieee154_timestamp_t *timestamp);
}
interface SplitControl;
interface RadioRx;
interface RadioTx;
+ interface SlottedCsmaCa;
+ interface UnslottedCsmaCa;
interface EnergyDetection;
interface RadioOff;
interface Set<bool> as RadioPromiscuousMode;
interface Timestamp;
+ interface GetNow<bool> as CCA;
} uses {
interface Notify<const void*> as PIBUpdate[uint8_t attributeID];
interface LocalTime<T62500hz>;
interface ReferenceTime;
interface ReliableWait;
interface TimeCalc;
- interface Leds;
interface Random;
}
} implementation {
SplitControl = PHY;
RadioRx = PHY;
RadioTx = PHY;
+ SlottedCsmaCa = PHY;
+ UnslottedCsmaCa = PHY;
RadioOff = PHY;
EnergyDetection = PHY;
PIBUpdate = PHY;
ReliableWait = PHY;
ReferenceTime = PHY;
TimeCalc = PHY;
+ CCA = PHY;
PHY.Random = Random;
- Leds = PHY.Leds;
components CC2420ControlTransmitC;
PHY.SpiResource -> CC2420ControlTransmitC;
PHY.CC2420Config -> CC2420ControlTransmitC;
CC2420ControlTransmitC.StartupAlarm = Alarm2;
FrameUtility = CC2420ControlTransmitC;
- Leds = CC2420ControlTransmitC;
PHY.TxControl -> CC2420ControlTransmitC;
PHY.CC2420Tx -> CC2420ControlTransmitC;
PHY.RxControl -> CC2420ReceiveC;
PHY.CC2420Rx -> CC2420ReceiveC.CC2420Rx;
ReferenceTime = CC2420ReceiveC;
- Leds = CC2420ReceiveC;
FrameUtility = CC2420ReceiveC;
CC2420ReceiveC.CC2420Config -> CC2420ControlTransmitC;
}
provides {
interface SplitControl;
+ interface RadioOff;
interface RadioRx;
interface RadioTx;
- interface RadioOff;
+ interface SlottedCsmaCa;
+ interface UnslottedCsmaCa;
interface EnergyDetection;
interface Set<bool> as RadioPromiscuousMode;
interface Timestamp;
+ interface GetNow<bool> as CCA;
} uses {
interface Notify<const void*> as PIBUpdate[uint8_t attributeID];
interface LocalTime<T62500hz> as LocalTime;
S_STOPPED,
S_STOPPING,
S_STARTING,
-
- S_RADIO_OFF,
S_ED,
+ S_RADIO_OFF,
S_RESERVE_RX_SPI,
- S_RX_PREPARED,
- S_RX_WAIT,
+ S_RX_PENDING,
S_RECEIVING,
S_OFF_PENDING,
- S_LOAD_TXFIFO,
- S_TX_LOADED,
- S_TX_WAIT,
- S_TX_ACTIVE,
- S_TX_CANCEL,
- S_TX_DONE,
+ S_LOAD_TXFIFO_NO_CSMA,
+ S_LOAD_TXFIFO_UNSLOTTED,
+ S_LOAD_TXFIFO_SLOTTED,
+ S_TX_PENDING,
+ S_TX_BACKOFF_UNSLOTTED,
+ S_TX_BACKOFF_SLOTTED,
+ S_TX_ACTIVE_NO_CSMA,
+ S_TX_ACTIVE_UNSLOTTED_CSMA,
+ S_TX_ACTIVE_SLOTTED_CSMA,
} m_state_t;
norace m_state_t m_state = S_STOPPED;
norace ieee154_txframe_t *m_txframe;
- norace error_t m_txError;
- norace ieee154_reftime_t m_txReferenceTime;
+ norace error_t m_txResult;
norace bool m_ackFramePending;
- uint32_t m_edDuration;
+ norace uint16_t m_remainingBackoff;
+ norace bool m_resume;
+ norace ieee154_csma_t *m_csma;
bool m_pibUpdated;
- norace uint8_t m_numCCA;
- ieee154_reftime_t *m_t0Tx;
- uint32_t m_dtMax;
- uint32_t m_dt;
- norace ieee154_csma_t *m_csmaParams;
- norace uint8_t m_txLockOnCCAFail;
- norace bool m_rxAfterTx = FALSE;
- norace bool m_stop = FALSE;
+ /* timing */
+ norace ieee154_timestamp_t *m_timestamp;
+ norace uint32_t m_dt;
+ norace union {
+ uint32_t regular;
+ ieee154_timestamp_t native;
+ } m_t0;
+
+ /* energy detection */
+ int8_t m_maxEnergy;
+ uint32_t m_edDuration;
+ uint32_t m_edStartTime;
+
+ /* task prototypes */
+ task void energyDetectionTask();
task void startDoneTask();
task void rxControlStopDoneTask();
- task void stopTask();
+ /* function prototypes */
uint8_t dBmToPA_LEVEL(int dbm);
void txDoneRxControlStopped();
void rxSpiReserved();
void txSpiReserved();
- void txDoneSpiReserved();
- void finishTx();
- void stopContinue();
+ void sendDoneSpiReserved();
void offSpiReserved();
void offStopRxDone();
- uint16_t generateRandomBackoff(uint8_t BE);
- void randomDelayUnslottedCsmaCa();
- void randomDelaySlottedCsmaCa(bool resume, uint16_t remainingBackoff);
- void sendDone(ieee154_reftime_t *referenceTime, bool ackPendingFlag, error_t error);
-
+ uint16_t getRandomBackoff(uint8_t BE);
+ void loadTxFrame(ieee154_txframe_t *frame);
+ void checkEnableRxForACK();
-/* ----------------------- StdControl Operations ----------------------- */
+ /* ----------------------- StdControl Operations ----------------------- */
command error_t SplitControl.start()
{
atomic {
if (m_state == S_RADIO_OFF)
return EALREADY;
- else {
- if (m_state != S_STOPPED)
- return FAIL;
- m_state = S_STARTING;
- }
+ else if (m_state != S_STOPPED)
+ return FAIL;
+ m_state = S_STARTING;
}
- return call SpiResource.request();
+ call SpiResource.request(); /* continue in startSpiReserved() */
+ return SUCCESS;
}
- void startReserved()
+ void startSpiReserved()
{
+ /* we own the SPI bus */
call CC2420Power.startVReg();
}
async event void CC2420Power.startOscillatorDone()
{
- // default configuration (addresses, etc) has been written
call CC2420Power.rfOff();
call CC2420Power.flushRxFifo();
call CC2420Tx.unlockChipSpi();
call CC2420Config.setTxPower(dBmToPA_LEVEL(IEEE154_DEFAULT_TRANSMITPOWER_dBm));
call CC2420Config.sync();
call SpiResource.release();
- m_stop = FALSE;
m_state = S_RADIO_OFF;
signal SplitControl.startDone(SUCCESS);
}
atomic {
if (m_state == S_STOPPED)
return EALREADY;
+ else if (m_state != S_RADIO_OFF)
+ return FAIL;
+ m_state = S_STOPPING;
}
- post stopTask();
+ call SpiResource.request();
return SUCCESS;
}
- task void stopTask()
+ void stopSpiReserved()
{
- atomic {
- if (m_state == S_RADIO_OFF)
- m_state = S_STOPPING;
- }
- if (m_state != S_STOPPING)
- post stopTask(); // spin - this should not happen, because the caller has switched radio off
- else
- stopContinue();
- }
-
- void stopContinue()
- {
- call SpiResource.request();
+ /* we own the SPI bus */
+ call CC2420Power.rfOff();
+ call CC2420Power.flushRxFifo();
+ call CC2420Power.stopOscillator();
+ call CC2420Power.stopVReg();
+ call CC2420Tx.unlockChipSpi();
+ call SpiResource.release();
+ m_state = S_STOPPED;
+ signal SplitControl.stopDone(SUCCESS);
}
- void stopReserved()
- {
- // we own the SPI bus
- atomic {
- call CC2420Power.rfOff();
- call CC2420Power.flushRxFifo();
- call CC2420Power.stopOscillator();
- call CC2420Power.stopVReg();
- call CC2420Tx.unlockChipSpi();
- call SpiResource.release();
- m_state = S_STOPPED;
- signal SplitControl.stopDone(SUCCESS);
- }
- }
+ /* ----------------------- Helpers / PIB Updates ----------------------- */
- uint16_t generateRandomBackoff(uint8_t BE)
+ /* Returns a random number [0,(2^BE) - 1] (uniform distr.) */
+ /* multiplied by backoff period time (in symbols) */
+ uint16_t getRandomBackoff(uint8_t BE)
{
- // return random number from [0,(2^BE) - 1] (uniform distr.)
uint16_t res = call Random.rand16();
uint16_t mask = 0xFFFF;
mask <<= BE;
mask = ~mask;
res &= mask;
- return res;
+ return (res * IEEE154_aUnitBackoffPeriod);
}
-/* ----------------------- PIB Updates ----------------------- */
-
- // input: power in dBm, output: PA_LEVEL parameter for cc2420 TXCTRL register
+ /* input: power in dBm, output: PA_LEVEL setting for CC2420 TXCTRL register */
uint8_t dBmToPA_LEVEL(int dBm)
{
uint8_t result;
- // the cc2420 has 8 discrete (documented) values - we take the closest
+ /* the cc2420 has 8 discrete (documented) values */
if (dBm >= 0)
result = 31;
else if (dBm > -2)
call CC2420Config.setPanCoordinator(*((ieee154_macPanCoordinator_t*) PIBAttributeValue));
break;
case IEEE154_phyTransmitPower:
- // lower 6 bits are twos-complement in dBm (range -32..+31 dBm)
+ /* lower 6 bits are twos-complement in dBm (range -32 to +31 dBm) */
txpower = (*((ieee154_phyTransmitPower_t*) PIBAttributeValue)) & 0x3F;
if (txpower & 0x20)
- txpower |= 0xC0; // make it negative, to be interpreted as int8_t
+ txpower |= 0xC0; /* make it negative, to be interpreted as int8_t */
call CC2420Config.setTxPower(dBmToPA_LEVEL((int8_t) txpower));
break;
case IEEE154_phyCCAMode:
call CC2420Config.setPromiscuousMode(val);
}
-/* ----------------------- Energy Detection ----------------------- */
+ /* ----------------------- Energy Detection ----------------------- */
command error_t EnergyDetection.start(uint32_t duration)
{
- error_t status = FAIL;
atomic {
- if (m_state == S_RADIO_OFF){
- m_state = S_ED;
- m_edDuration = duration;
- status = SUCCESS;
- }
+ if (m_state == S_ED)
+ return EALREADY;
+ else if (m_state != S_RADIO_OFF)
+ return FAIL;
+ m_state = S_ED;
}
- if (status == SUCCESS)
- call SpiResource.request(); // we will not give up the SPI until we're done
- return status;
+ m_edDuration = duration;
+ m_maxEnergy = -128 + 45; /* initialization (45 will be substracted below) */
+ call SpiResource.request();
+ return SUCCESS;
}
void edReserved()
{
- int8_t value, maxEnergy = -128;
- uint32_t start = call LocalTime.get();
- call CC2420Config.sync(); // put PIB changes into operation (if any)
+ call CC2420Config.sync(); /* put PIB changes into operation (if any) */
call CC2420Power.rxOn();
- // reading an RSSI value over SPI will usually almost
- // take as much time as 8 symbols, i.e. there's
- // no point using an Alarm here (but maybe a busy wait?)
- while (!call TimeCalc.hasExpired(start, m_edDuration)){
- if (call CC2420Power.rssi(&value) != SUCCESS)
- continue;
- if (value > maxEnergy)
- maxEnergy = value;
- }
- // P = RSSI_VAL + RSSI_OFFSET [dBm]
- // RSSI_OFFSET is approximately -45.
- if (maxEnergy > -128)
- maxEnergy -= 45;
- call CC2420Power.rfOff();
- call CC2420Power.flushRxFifo();
- m_state = S_RADIO_OFF;
- call SpiResource.release();
- signal EnergyDetection.done(SUCCESS, maxEnergy);
+ m_edStartTime = call LocalTime.get();
+ post energyDetectionTask();
}
-/* ----------------------- Transceiver Off ----------------------- */
-
- task void spinOffTask()
+ task void energyDetectionTask()
{
- uint8_t i;
- call Leds.led2On(); call Leds.led1On();
- for (i=0; i<65500U; i++) ;
- call Leds.led2Off(); call Leds.led1Off();
- for (i=0; i<65500U; i++) ;
- call RadioOff.off();
+ int8_t value;
+ if (call CC2420Power.rssi(&value) == SUCCESS)
+ if (value > m_maxEnergy)
+ m_maxEnergy = value;
+
+ if (call TimeCalc.hasExpired(m_edStartTime, m_edDuration)) {
+ /* P = RSSI_VAL + RSSI_OFFSET [dBm] */
+ /* RSSI_OFFSET is approximately -45. */
+ m_maxEnergy -= 45;
+ call CC2420Power.rfOff();
+ call CC2420Power.flushRxFifo();
+ call SpiResource.release();
+ m_state = S_RADIO_OFF;
+ signal EnergyDetection.done(SUCCESS, m_maxEnergy);
+ } else
+ post energyDetectionTask();
}
+ /* ----------------------- RadioOff ----------------------- */
+
async command error_t RadioOff.off()
{
atomic {
if (m_state == S_RADIO_OFF)
return EALREADY;
- if (m_state == S_RX_WAIT || m_state == S_TX_WAIT){
- post spinOffTask();
- return SUCCESS;
- } else if (m_state != S_RECEIVING && m_state != S_TX_LOADED && m_state != S_RX_PREPARED)
+ else if (m_state != S_RECEIVING)
return FAIL;
m_state = S_OFF_PENDING;
}
- call SpiResource.release(); // may fail
- if (call RxControl.stop() == EALREADY) // will trigger offStopRxDone()
- offStopRxDone();
+ ASSERT(call RxControl.stop() == SUCCESS);
return SUCCESS;
}
if (call SpiResource.immediateRequest() == SUCCESS)
offSpiReserved();
else
- call SpiResource.request(); // will trigger offSpiReserved()
+ call SpiResource.request(); /* will continue in offSpiReserved() */
}
void offSpiReserved()
return m_state == S_RADIO_OFF;
}
-/* ----------------------- Receive Operations ----------------------- */
+ /* ----------------------- RadioRx ----------------------- */
- async command error_t RadioRx.prepare()
+ async command error_t RadioRx.enableRx(uint32_t t0, uint32_t dt)
{
atomic {
- if (call RadioRx.isPrepared())
- return EALREADY;
- else if (m_state != S_RADIO_OFF)
+ if (m_state != S_RADIO_OFF)
return FAIL;
m_state = S_RESERVE_RX_SPI;
}
- if (call RxControl.start() != SUCCESS){
- m_state = S_RADIO_OFF;
- call Leds.led0On();
- return FAIL;
- } else {
- if (call SpiResource.immediateRequest() == SUCCESS) // will trigger rxSpiReserved()
- rxSpiReserved();
- else
- call SpiResource.request();
- }
+ m_t0.regular = t0;
+ m_dt = dt;
+ ASSERT(call RxControl.start() == SUCCESS);
+ if (call SpiResource.immediateRequest() == SUCCESS)
+ rxSpiReserved();
+ else
+ call SpiResource.request(); /* will continue in rxSpiReserved() */
return SUCCESS;
}
void rxSpiReserved()
{
- call CC2420Config.sync(); // put PIB changes into operation
- call TxControl.stop();
- call TxControl.start(); // for timestamping (SFD interrupt)
- m_state = S_RX_PREPARED;
- signal RadioRx.prepareDone(); // keep owning the SPI
- }
-
- async command bool RadioRx.isPrepared()
- {
- return m_state == S_RX_PREPARED;
- }
-
- async command error_t RadioRx.receive(ieee154_reftime_t *t0, uint32_t dt)
- {
+ call CC2420Config.sync(); /* put any pending PIB changes into operation */
+ call TxControl.stop(); /* reset Tx logic for timestamping (SFD interrupt) */
+ call TxControl.start();
atomic {
- if (m_state != S_RX_PREPARED){
- call Leds.led0On();
- return FAIL;
- }
- m_state = S_RX_WAIT;
- if (t0 != NULL)
- call ReliableWait.waitRx(t0, dt); // will signal waitRxDone() in time
- else
+ m_state = S_RX_PENDING;
+ if (call TimeCalc.hasExpired(m_t0.regular, m_dt))
signal ReliableWait.waitRxDone();
+ else
+ call ReliableWait.waitRx(m_t0.regular, m_dt); /* will signal waitRxDone() just in time */
}
- return SUCCESS;
}
async event void ReliableWait.waitRxDone()
{
atomic {
- if (call CC2420Power.rxOn() != SUCCESS)
- call Leds.led0On();
m_state = S_RECEIVING;
+ ASSERT(call CC2420Power.rxOn() == SUCCESS);
}
call CC2420Tx.lockChipSpi();
- call SpiResource.release();
+ call SpiResource.release();
+ signal RadioRx.enableRxDone();
}
- event message_t* CC2420Rx.received(message_t *frame, ieee154_reftime_t *timestamp)
+ event message_t* CC2420Rx.received(message_t *frame, ieee154_timestamp_t *timestamp)
{
if (m_state == S_RECEIVING)
return signal RadioRx.received(frame, timestamp);
}
async command bool RadioRx.isReceiving()
- {
+ {
return m_state == S_RECEIVING;
}
-/* ----------------------- Transmit Operations ----------------------- */
+ /* ----------------------- RadioTx ----------------------- */
- async command error_t RadioTx.load(ieee154_txframe_t *frame)
+ async command error_t RadioTx.transmit( ieee154_txframe_t *frame, const ieee154_timestamp_t *t0, uint32_t dt )
{
+ if( frame == NULL || frame->header == NULL ||
+ frame->payload == NULL || frame->metadata == NULL ||
+ (frame->headerLen + frame->payloadLen + 2) > IEEE154_aMaxPHYPacketSize )
+ return EINVAL;
+
atomic {
- if (m_state != S_RADIO_OFF && m_state != S_TX_LOADED)
+ if( m_state != S_RADIO_OFF )
return FAIL;
- m_txframe = frame;
- m_state = S_LOAD_TXFIFO;
+ m_state = S_LOAD_TXFIFO_NO_CSMA;
}
- if (call SpiResource.isOwner() || call SpiResource.immediateRequest() == SUCCESS)
- txSpiReserved();
- else
- call SpiResource.request(); // will trigger txSpiReserved()
+ m_txframe = frame;
+ if( t0 == NULL )
+ m_dt = 0;
+ else {
+ memcpy( &m_t0.native, t0, sizeof(ieee154_timestamp_t) );
+ m_dt = dt;
+ }
+ loadTxFrame(frame); /* will continue in loadDoneRadioTx() */
return SUCCESS;
}
- void txSpiReserved()
- {
- call CC2420Config.sync();
- call TxControl.start();
- if (call CC2420Tx.loadTXFIFO(m_txframe) != SUCCESS)
- call Leds.led0On();
- }
-
- async event void CC2420Tx.loadTXFIFODone(ieee154_txframe_t *data, error_t error)
- {
- if (m_state != S_LOAD_TXFIFO || error != SUCCESS)
- call Leds.led0On();
- m_state = S_TX_LOADED;
- signal RadioTx.loadDone(); // we keep owning the SPI
- }
-
- async command ieee154_txframe_t* RadioTx.getLoadedFrame()
+ void loadDoneRadioTx()
{
- if (m_state == S_TX_LOADED)
- return m_txframe;
- else
- return NULL;
- }
-
- async command error_t RadioTx.transmit(ieee154_reftime_t *t0, uint32_t dt)
- {
- // transmit without CCA
+ /* frame was loaded into TXFIFO */
atomic {
- if (m_state != S_TX_LOADED)
- return FAIL;
- m_numCCA = 0;
- m_state = S_TX_WAIT;
- if (t0 != NULL)
- call ReliableWait.waitTx(t0, dt); // will signal waitTxDone() in time
- else
+ m_state = S_TX_PENDING;
+ if (m_dt == 0)
signal ReliableWait.waitTxDone();
+ else
+ call ReliableWait.waitTx(&m_t0.native, m_dt); /* will signal waitTxDone() just in time */
}
- return SUCCESS;
}
- void checkEnableRxForACK()
+ async event void ReliableWait.waitTxDone()
{
- // the packet is currently being transmitted, check if we need the receive logic ready
- bool ackRequest = (m_txframe->header->mhr[MHR_INDEX_FC1] & FC1_ACK_REQUEST) ? TRUE : FALSE;
- if (ackRequest){
- // ATTENTION: here the SpiResource is released if ACK is expected
- // (so Rx part of the driver can take over)
- call SpiResource.release();
- if (call RxControl.start() != SUCCESS)
- call Leds.led0On();
+ atomic {
+ ASSERT(m_state == S_TX_PENDING);
+ m_state = S_TX_ACTIVE_NO_CSMA;
+ ASSERT(call CC2420Tx.send(FALSE) == SUCCESS); /* transmit without CCA, this must succeed */
+ checkEnableRxForACK();
}
}
- async event void ReliableWait.waitTxDone()
+ inline void txDoneRadioTx(ieee154_txframe_t *frame, ieee154_timestamp_t *timestamp, error_t result)
{
- atomic {
- m_state = S_TX_ACTIVE;
- if (call CC2420Tx.send(FALSE) == SUCCESS) // transmit without CCA, this must succeed
- checkEnableRxForACK();
- else
- call Leds.led0On();
- }
+ /* transmission completed */
+ signal RadioTx.transmitDone(frame, timestamp, result);
}
- async command error_t RadioTx.transmitUnslottedCsmaCa(ieee154_csma_t *csmaParams)
+ /* ----------------------- UnslottedCsmaCa ----------------------- */
+
+ async command error_t UnslottedCsmaCa.transmit(ieee154_txframe_t *frame, ieee154_csma_t *csma)
{
- // transmit with single CCA
+ if( frame == NULL || frame->header == NULL ||
+ frame->payload == NULL || frame->metadata == NULL ||
+ (frame->headerLen + frame->payloadLen + 2) > IEEE154_aMaxPHYPacketSize )
+ return EINVAL;
atomic {
- if (m_state != S_TX_LOADED)
+ if( m_state != S_RADIO_OFF )
return FAIL;
- m_csmaParams = csmaParams;
- m_numCCA = 1;
- randomDelayUnslottedCsmaCa();
+ m_state = S_LOAD_TXFIFO_UNSLOTTED;
}
+ m_txframe = frame;
+ m_csma = csma;
+ loadTxFrame(frame); /* will continue in nextIterationUnslottedCsma() */
return SUCCESS;
}
- void randomDelayUnslottedCsmaCa()
+ void nextIterationUnslottedCsma()
{
- // wait random delay (unslotted CSMA-CA)
- uint16_t dtTx = generateRandomBackoff(m_csmaParams->BE) * 20;
- call ReferenceTime.getNow(m_t0Tx, 0);
- m_state = S_TX_WAIT;
- call ReliableWait.waitBackoff(m_t0Tx, dtTx);
+ /* wait for a random time of [0,(2^BE) - 1] backoff slots */
+ uint16_t backoff = getRandomBackoff(m_csma->BE);
+ m_state = S_TX_BACKOFF_UNSLOTTED;
+ call ReliableWait.waitBackoff(backoff); /* will continue in waitBackoffDoneUnslottedCsma() */
}
- void waitBackoffUnslottedCsmaCaDone()
+ void waitBackoffDoneUnslottedCsma()
{
+ /* backoff finished, try to transmit now */
int8_t dummy;
+ ieee154_txframe_t *frame = NULL;
+ ieee154_csma_t *csma = NULL;
+
atomic {
- // CC2420 needs to be in an Rx state for STXONCCA strobe
- // note: the receive logic of the CC2420 driver is not yet started,
- // i.e. we will not (yet) receive any packets
+ /* The CC2420 needs to be in an Rx mode for STXONCCA strobe */
+ /* Note: the receive logic of the CC2420 driver is not yet */
+ /* started, i.e. we cannot (yet) receive any packets */
call CC2420Power.rxOn();
- m_state = S_TX_ACTIVE;
- // wait for CC2420 Rx to calibrate + CCA valid time
+ m_state = S_TX_ACTIVE_UNSLOTTED_CSMA;
+
+ /* wait for CC2420 Rx to calibrate + CCA valid time */
while (call CC2420Power.rssi(&dummy) != SUCCESS)
;
- // call ReliableWait.busyWait(40);
- // transmit with single CCA (STXONCCA strobe)
- if (call CC2420Tx.send(TRUE) == SUCCESS){
+
+ /* transmit with a single CCA done in hardware (STXONCCA strobe) */
+ if (call CC2420Tx.send(TRUE) == SUCCESS) {
+ /* frame is being sent now, do we need Rx logic ready for an ACK? */
checkEnableRxForACK();
} else {
- // channel is busy
+ /* channel is busy */
call CC2420Power.rfOff();
- call CC2420Power.flushRxFifo(); // we might have (accidentally) caught something during CCA
- m_state = S_TX_LOADED;
- m_csmaParams->NB += 1;
- if (m_csmaParams->NB > m_csmaParams->macMaxCsmaBackoffs){
- // CSMA-CA failure, note: we keep owning the SPI,
- // our state is back to S_TX_LOADED, the MAC may try to retransmit
- signal RadioTx.transmitUnslottedCsmaCaDone(m_txframe, FALSE, m_csmaParams, FAIL);
+ /* we might have accidentally caught something during CCA, flush it out */
+ call CC2420Power.flushRxFifo();
+ m_csma->NB += 1;
+ if (m_csma->NB > m_csma->macMaxCsmaBackoffs) {
+ /* CSMA-CA failure, we're done. The MAC may decide to retransmit. */
+ frame = m_txframe;
+ csma = m_csma;
+ /* continue below */
} else {
- // next iteration of unslotted CSMA-CA
- m_csmaParams->BE += 1;
- if (m_csmaParams->BE > m_csmaParams->macMaxBE)
- m_csmaParams->BE = m_csmaParams->macMaxBE;
- randomDelayUnslottedCsmaCa();
+ /* Retry -> next iteration of the unslotted CSMA-CA */
+ m_csma->BE += 1;
+ if (m_csma->BE > m_csma->macMaxBE)
+ m_csma->BE = m_csma->macMaxBE;
+ nextIterationUnslottedCsma();
}
}
}
+ if (frame != NULL) {
+ call CC2420Tx.unlockChipSpi();
+ call TxControl.stop();
+ call SpiResource.release();
+ m_state = S_RADIO_OFF;
+ signal UnslottedCsmaCa.transmitDone(frame, csma, FALSE, FAIL);
+ }
+ }
+
+ inline void txDoneUnslottedCsma(ieee154_txframe_t *frame, ieee154_csma_t *csma, bool ackPendingFlag, error_t result)
+ {
+ /* transmission completed */
+ signal UnslottedCsmaCa.transmitDone(frame, csma, ackPendingFlag, result);
}
- async command error_t RadioTx.transmitSlottedCsmaCa(ieee154_reftime_t *slot0Time, uint32_t dtMax,
- bool resume, uint16_t remainingBackoff, ieee154_csma_t *csmaParams)
+ /* ----------------------- SlottedCsmaCa ----------------------- */
+
+ /* The slotted CSMA-CA requires very exact timing, because transmissions
+ * must start on 320 us backoff boundaries. Because it is accessed over SPI
+ * the CC2420 is not good at meeting these timing requirements, so consider
+ * the "SlottedCsmaCa"-code below as experimental. */
+
+ async command error_t SlottedCsmaCa.transmit(ieee154_txframe_t *frame, ieee154_csma_t *csma,
+ const ieee154_timestamp_t *slot0Time, uint32_t dtMax, bool resume, uint16_t remainingBackoff)
{
- // slotted CSMA-CA requires very exact timing (transmission on
- // 320 us backoff boundary), even if we have a sufficiently precise and
- // accurate clock the CC2420 is not the right radio for
- // this task because it is accessed over SPI. The code below relies on
- // platform-specific busy-wait functions that must be adjusted
- // (through measurements) such that they meet the timing constraints
+ if( frame == NULL || frame->header == NULL || slot0Time == NULL ||
+ frame->payload == NULL || frame->metadata == NULL ||
+ (frame->headerLen + frame->payloadLen + 2) > IEEE154_aMaxPHYPacketSize)
+ return EINVAL;
atomic {
- if (m_state != S_TX_LOADED)
+ if( m_state != S_RADIO_OFF )
return FAIL;
- m_csmaParams = csmaParams;
- m_numCCA = 2;
- m_t0Tx = slot0Time;
- m_dtMax = dtMax;
- randomDelaySlottedCsmaCa(resume, remainingBackoff);
+ m_state = S_LOAD_TXFIFO_SLOTTED;
}
+ m_txframe = frame;
+ m_csma = csma;
+ memcpy( &m_t0.native, slot0Time, sizeof(ieee154_timestamp_t) );
+ m_dt = dtMax;
+ m_resume = resume;
+ m_remainingBackoff = remainingBackoff;
+ loadTxFrame(frame); /* will continue in nextIterationSlottedCsma() */
return SUCCESS;
}
- void randomDelaySlottedCsmaCa(bool resume, uint16_t remainingBackoff)
+ void nextIterationSlottedCsma()
{
- uint16_t dtTx;
+ uint32_t dtTxTarget;
+ uint16_t backoff;
+ ieee154_txframe_t *frame = NULL;
+ ieee154_csma_t *csma = NULL;
+
atomic {
- dtTx = call TimeCalc.timeElapsed(call ReferenceTime.toLocalTime(m_t0Tx), call LocalTime.get());
- dtTx += (20 - (dtTx % 20)); // round to backoff boundary
- if (resume)
- dtTx += remainingBackoff;
- else
- dtTx = dtTx + (generateRandomBackoff(m_csmaParams->BE) * 20);
- dtTx += 40; // two backoff periods for the two CCA, the actual tx is scheduled for = m_t0Tx + dtTx
- if (dtTx > m_dtMax){
- uint16_t remaining = dtTx - m_dtMax;
- if (remaining >= 40)
- remaining -= 40; // substract the two CCA (they don't count for the backoff)
- else
- remaining = 0;
- signal RadioTx.transmitSlottedCsmaCaDone(m_txframe, NULL, FALSE, remaining, m_csmaParams, ERETRY);
+ if (m_resume) {
+ backoff = m_remainingBackoff;
+ m_resume = FALSE;
+ } else
+ backoff = getRandomBackoff(m_csma->BE);
+ dtTxTarget = call TimeCalc.timeElapsed(call ReferenceTime.toLocalTime(&m_t0.native), call LocalTime.get());
+ dtTxTarget += backoff;
+ if (dtTxTarget > m_dt) {
+ /* frame doesn't fit into remaining CAP */
+ uint32_t overlap = dtTxTarget - m_dt;
+ overlap = overlap + (IEEE154_aUnitBackoffPeriod - (overlap % IEEE154_aUnitBackoffPeriod));
+ backoff = overlap;
+ frame = m_txframe;
+ csma = m_csma;
} else {
- m_state = S_TX_WAIT;
- call ReliableWait.waitBackoff(m_t0Tx, dtTx);
+ /* backoff now */
+ m_state = S_TX_BACKOFF_SLOTTED;
+ call ReliableWait.waitBackoff(backoff); /* will continue in waitBackoffDoneSlottedCsma() */
}
}
+ if (frame != NULL) { /* frame didn't fit in the remaining CAP */
+ call CC2420Tx.unlockChipSpi();
+ call TxControl.stop();
+ call SpiResource.release();
+ m_state = S_RADIO_OFF;
+ signal SlottedCsmaCa.transmitDone(frame, csma, FALSE, backoff, ERETRY);
+ }
}
- void waitBackoffSlottedCsmaCaDone()
+ void waitBackoffDoneSlottedCsma()
{
- bool cca;
- uint16_t dtTx=0;
int8_t dummy;
+ bool ccaFailure = FALSE;
+ error_t result = FAIL;
+ ieee154_txframe_t *frame = NULL;
+ ieee154_csma_t *csma = NULL;
+
atomic {
- // CC2420 needs to be in an Rx state for STXONCCA strobe
- // note: the receive logic of the CC2420 driver is not yet started,
- // i.e. we will not (yet) receive any packets
+ /* The CC2420 needs to be in an Rx mode for STXONCCA strobe */
+ /* Note: the receive logic of the CC2420 driver is not yet */
+ /* started, i.e. we cannot (yet) receive any packets */
call CC2420Power.rxOn();
- m_state = S_TX_ACTIVE;
- // wait for CC2420 Rx to calibrate + CCA valid time
+ m_state = S_TX_ACTIVE_SLOTTED_CSMA;
+
+ /* wait for CC2420 Rx to calibrate + CCA valid time */
while (call CC2420Power.rssi(&dummy) != SUCCESS)
;
- // perform CCA on slot boundary (or rather 8 symbols after)
- call ReliableWait.busyWaitSlotBoundaryCCA(m_t0Tx, &dtTx); // platform-specific implementation
- cca = call CC2420Tx.cca();
- if (cca && dtTx <= m_dtMax){
- // Tx in following slot (STXONCCA)
- call ReliableWait.busyWaitSlotBoundaryTx(m_t0Tx, dtTx+20); // platform-specific implementation
- if (call CC2420Tx.send(TRUE) == SUCCESS){
+
+ /* perform CCA on slot boundary (i.e. 8 symbols after backoff bounday); */
+ /* this platform-specific command is supposed to return just in time, so */
+ /* that the frame will be transmitted exactly on the next backoff boundary */
+ if (call ReliableWait.ccaOnBackoffBoundary(&m_t0.native)) {
+ /* first CCA succeeded */
+ if (call CC2420Tx.send(TRUE) == SUCCESS) {
+ /* frame is being sent now, do we need Rx logic ready for an ACK? */
checkEnableRxForACK();
return;
} else
- cca = FALSE;
- }
- // did not transmit the frame
+ ccaFailure = TRUE; /* second CCA failed */
+ } else
+ ccaFailure = TRUE; /* first CCA failed */
+
+ /* did not transmit the frame */
call CC2420Power.rfOff();
- call CC2420Power.flushRxFifo(); // we might have (accidentally) caught something
- m_state = S_TX_LOADED;
- if (dtTx > m_dtMax)
- // frame didn't fit into remaining CAP, this can only
- // be because we couldn't meet the time-constraints
- // (in principle the frame should have fitted)
- signal RadioTx.transmitSlottedCsmaCaDone(m_txframe, NULL, FALSE, 0, m_csmaParams, ERETRY);
- else {
- // CCA failed
- m_csmaParams->NB += 1;
- if (m_csmaParams->NB > m_csmaParams->macMaxCsmaBackoffs){
- // CSMA-CA failure, note: we keep owning the SPI
- signal RadioTx.transmitSlottedCsmaCaDone(m_txframe, NULL, FALSE, 0, m_csmaParams, FAIL);
+ call CC2420Power.flushRxFifo(); /* we might have (accidentally) caught something */
+ m_state = S_LOAD_TXFIFO_SLOTTED;
+ if (ccaFailure) {
+ m_csma->NB += 1;
+ if (m_csma->NB > m_csma->macMaxCsmaBackoffs) {
+ /* CSMA-CA failure, we're done. The MAC may decide to retransmit. */
+ frame = m_txframe;
+ csma = m_csma;
+ result = FAIL;
} else {
- // next iteration of slotted CSMA-CA
- m_csmaParams->BE += 1;
- if (m_csmaParams->BE > m_csmaParams->macMaxBE)
- m_csmaParams->BE = m_csmaParams->macMaxBE;
- randomDelaySlottedCsmaCa(FALSE, 0);
+ /* next iteration of slotted CSMA-CA */
+ m_csma->BE += 1;
+ if (m_csma->BE > m_csma->macMaxBE)
+ m_csma->BE = m_csma->macMaxBE;
+ nextIterationSlottedCsma();
}
+ } else {
+ /* frame didn't fit into remaining CAP, this can only happen */
+ /* if the runtime overhead was too high. this should actually not happen. */
+ /* (in principle the frame should have fitted, because we checked before) */
+ frame = m_txframe;
+ csma = m_csma;
+ result = ERETRY;
}
}
+ if (frame != NULL) {
+ call CC2420Tx.unlockChipSpi();
+ call TxControl.stop();
+ call SpiResource.release();
+ m_state = S_RADIO_OFF;
+ signal SlottedCsmaCa.transmitDone(frame, csma, FALSE, 0, result);
+ }
}
- async event void ReliableWait.waitBackoffDone()
+ inline void txDoneSlottedCsmaCa(ieee154_txframe_t *frame, ieee154_csma_t *csma,
+ bool ackPendingFlag, uint16_t remainingBackoff, error_t result)
{
- if (m_numCCA == 1)
- waitBackoffUnslottedCsmaCaDone();
+ /* transmission completed */
+ signal SlottedCsmaCa.transmitDone(frame, csma, ackPendingFlag, remainingBackoff, result);
+ }
+
+ /* ----------------------- Common Tx Operations ----------------------- */
+
+ void loadTxFrame(ieee154_txframe_t *frame)
+ {
+ if (call SpiResource.isOwner() || call SpiResource.immediateRequest() == SUCCESS)
+ txSpiReserved();
else
- waitBackoffSlottedCsmaCaDone();
+ call SpiResource.request(); /* will continue in txSpiReserved() */
}
- async event void CC2420Tx.transmissionStarted( ieee154_txframe_t *frame )
+ void txSpiReserved()
{
- uint8_t frameType = frame->header->mhr[0] & FC1_FRAMETYPE_MASK;
- uint8_t token = frame->headerLen;
- signal Timestamp.transmissionStarted(frameType, frame->handle, frame->payload, token);
+ call CC2420Config.sync();
+ call TxControl.start();
+ ASSERT(call CC2420Tx.loadTXFIFO(m_txframe) == SUCCESS);
}
- async event void CC2420Tx.transmittedSFD(uint32_t time, ieee154_txframe_t *frame)
+ async event void CC2420Tx.loadTXFIFODone(ieee154_txframe_t *data, error_t error)
{
- uint8_t frameType = frame->header->mhr[0] & FC1_FRAMETYPE_MASK;
- uint8_t token = frame->headerLen;
- signal Timestamp.transmittedSFD(time, frameType, frame->handle, frame->payload, token);
+ atomic {
+ switch (m_state)
+ {
+ case S_LOAD_TXFIFO_NO_CSMA: loadDoneRadioTx(); break;
+ case S_LOAD_TXFIFO_UNSLOTTED: nextIterationUnslottedCsma(); break;
+ case S_LOAD_TXFIFO_SLOTTED: nextIterationSlottedCsma(); break;
+ default: ASSERT(0); break;
+ }
+ }
}
- async command void Timestamp.modifyMACPayload(uint8_t token, uint8_t offset, uint8_t* buf, uint8_t len )
+ void checkEnableRxForACK()
{
- if (m_state == S_TX_ACTIVE)
- call CC2420Tx.modify(offset+1+token, buf, len);
+ /* A frame is currently being transmitted, check if we */
+ /* need the Rx logic ready for the ACK */
+ bool ackRequest = (m_txframe->header->mhr[MHR_INDEX_FC1] & FC1_ACK_REQUEST) ? TRUE : FALSE;
+ if (ackRequest) {
+ /* release SpiResource and start Rx logic, so the latter */
+ /* can take over after Tx is finished to receive the ACK */
+ call SpiResource.release();
+ ASSERT(call RxControl.start() == SUCCESS);
+ }
}
- async event void CC2420Tx.sendDone(ieee154_txframe_t *frame, ieee154_reftime_t *referenceTime,
- bool ackPendingFlag, error_t error)
+ async event void CC2420Tx.sendDone(ieee154_txframe_t *frame,
+ ieee154_timestamp_t *timestamp, bool ackPendingFlag, error_t result)
{
- if (!call SpiResource.isOwner()){
- // this can only happen if an ack was requested and we gave up the SPI
- bool wasAckRequested = (frame->header->mhr[MHR_INDEX_FC1] & FC1_ACK_REQUEST) ? TRUE : FALSE;
- if (!wasAckRequested)
- call Leds.led0On(); // internal error!
- memcpy(&m_txReferenceTime, referenceTime, sizeof(ieee154_reftime_t));
- m_ackFramePending = ackPendingFlag;
- m_txError = error;
- if (call RxControl.stop() != SUCCESS) // will trigger txDoneRxControlStopped()
- call Leds.led0On();
+ m_timestamp = timestamp;
+ m_ackFramePending = ackPendingFlag;
+ m_txResult = result;
+ if (!call SpiResource.isOwner()) {
+ /* this means an ACK was requested and during the transmission */
+ /* we released the Spi to allow the Rx part to take over */
+ ASSERT((frame->header->mhr[MHR_INDEX_FC1] & FC1_ACK_REQUEST));
+ ASSERT(call RxControl.stop() == SUCCESS); /* will continue in txDoneRxControlStopped() */
} else
- sendDone(referenceTime, ackPendingFlag, error);
+ sendDoneSpiReserved();
}
void txDoneRxControlStopped()
{
- // get SPI to switch radio off
+ /* get the Spi to switch radio off */
if (call SpiResource.isOwner() || call SpiResource.immediateRequest() == SUCCESS)
- txDoneSpiReserved();
+ sendDoneSpiReserved();
else
- call SpiResource.request(); // will trigger txDoneSpiReserved()
- }
-
- void txDoneSpiReserved()
- {
- sendDone(&m_txReferenceTime, m_ackFramePending, m_txError);
+ call SpiResource.request(); /* will continue in sendDoneSpiReserved() */
}
- void sendDone(ieee154_reftime_t *referenceTime, bool ackPendingFlag, error_t error)
+ void sendDoneSpiReserved()
{
- uint8_t numCCA = m_numCCA;
- // transmission complete, we're owning the SPI, Rx logic is disabled
+ /* transmission completed, we're owning the Spi, Rx logic is disabled */
+ m_state_t state = m_state;
+ ieee154_txframe_t *frame = m_txframe;
+ ieee154_csma_t *csma = m_csma;
+
call CC2420Power.rfOff();
call CC2420Power.flushRxFifo();
- switch (error)
+ call CC2420Tx.unlockChipSpi();
+ call TxControl.stop();
+ call SpiResource.release();
+ m_state = S_RADIO_OFF;
+
+ if (state == S_TX_ACTIVE_NO_CSMA)
+ txDoneRadioTx(frame, m_timestamp, m_txResult);
+ else if (state == S_TX_ACTIVE_UNSLOTTED_CSMA)
+ txDoneUnslottedCsma(frame, csma, m_ackFramePending, m_txResult);
+ else if (state == S_TX_ACTIVE_SLOTTED_CSMA)
+ txDoneSlottedCsmaCa(frame, csma, m_ackFramePending, m_remainingBackoff, m_txResult);
+ else
+ ASSERT(0);
+ }
+
+ async event void CC2420Tx.transmissionStarted( ieee154_txframe_t *frame )
+ {
+ uint8_t frameType = frame->header->mhr[0] & FC1_FRAMETYPE_MASK;
+ uint8_t token = frame->headerLen;
+ signal Timestamp.transmissionStarted(frameType, frame->handle, frame->payload, token);
+ }
+
+ async event void CC2420Tx.transmittedSFD( uint32_t time, ieee154_txframe_t *frame )
+ {
+ uint8_t frameType = frame->header->mhr[0] & FC1_FRAMETYPE_MASK;
+ uint8_t token = frame->headerLen;
+ signal Timestamp.transmittedSFD( time, frameType, frame->handle, frame->payload, token );
+ }
+
+ async command void Timestamp.modifyMACPayload( uint8_t token, uint8_t offset, uint8_t* buf, uint8_t len )
+ {
+ if (m_state == S_TX_ACTIVE_NO_CSMA ||
+ m_state == S_TX_ACTIVE_SLOTTED_CSMA ||
+ m_state == S_LOAD_TXFIFO_UNSLOTTED )
+ call CC2420Tx.modify( offset+1+token, buf, len );
+ }
+
+ async event void ReliableWait.waitBackoffDone()
+ {
+ switch (m_state)
{
- case SUCCESS:
- m_state = S_RADIO_OFF;
- break;
- case ENOACK:
- m_state = S_TX_LOADED;
- break;
- default:
- call Leds.led0On(); // internal error!
- break;
+ case S_TX_BACKOFF_SLOTTED: waitBackoffDoneSlottedCsma(); break;
+ case S_TX_BACKOFF_UNSLOTTED: waitBackoffDoneUnslottedCsma(); break;
+ default: ASSERT(0); break;
}
- if (error == SUCCESS){
- call CC2420Tx.unlockChipSpi();
- call TxControl.stop();
- call SpiResource.release();
- m_state = S_RADIO_OFF;
- } else
- m_state = S_TX_LOADED;
- if (numCCA == 0)
- signal RadioTx.transmitDone(m_txframe, referenceTime);
- else if (numCCA == 1)
- signal RadioTx.transmitUnslottedCsmaCaDone(m_txframe, ackPendingFlag, m_csmaParams, error);
- else
- signal RadioTx.transmitSlottedCsmaCaDone(m_txframe, referenceTime, ackPendingFlag, 0, m_csmaParams, error);
}
-/* ----------------------- RxControl ----------------------- */
+ /* ----------------------- RxControl ----------------------- */
async event void RxControl.stopDone(error_t error)
{
task void rxControlStopDoneTask()
{
- if (m_stop && m_state != S_STOPPING)
- return;
switch (m_state)
{
- case S_OFF_PENDING: offStopRxDone(); break;
- case S_TX_ACTIVE: txDoneRxControlStopped(); break;
- case S_STOPPING: stopContinue(); break;
- default: // huh ?
- call Leds.led0On(); break;
+ case S_OFF_PENDING: offStopRxDone(); break;
+ case S_TX_ACTIVE_NO_CSMA: /* fall through */
+ case S_TX_ACTIVE_UNSLOTTED_CSMA: /* fall through */
+ case S_TX_ACTIVE_SLOTTED_CSMA: txDoneRxControlStopped(); break;
+ default: ASSERT(0); break;
}
}
-/* ----------------------- SPI Bus Arbitration ----------------------- */
+ /* ----------------------- SPI Bus Arbitration ----------------------- */
event void SpiResource.granted()
{
switch (m_state)
{
- case S_STARTING: startReserved(); break;
- case S_ED: edReserved(); break;
- case S_RESERVE_RX_SPI: rxSpiReserved(); break;
- case S_LOAD_TXFIFO: txSpiReserved(); break;
- case S_TX_ACTIVE: txDoneSpiReserved(); break;
- case S_STOPPING: stopReserved(); break;
- case S_OFF_PENDING: offSpiReserved(); break;
- default: // huh ?
- call Leds.led0On(); break;
+ case S_STARTING: startSpiReserved(); break;
+ case S_ED: edReserved(); break;
+ case S_RESERVE_RX_SPI: rxSpiReserved(); break;
+ case S_LOAD_TXFIFO_NO_CSMA: /* fall through */
+ case S_LOAD_TXFIFO_UNSLOTTED: /* fall through */
+ case S_LOAD_TXFIFO_SLOTTED: txSpiReserved(); break;
+ case S_TX_ACTIVE_NO_CSMA: /* fall through */
+ case S_TX_ACTIVE_UNSLOTTED_CSMA: /* fall through */
+ case S_TX_ACTIVE_SLOTTED_CSMA: sendDoneSpiReserved(); break;
+ case S_STOPPING: stopSpiReserved(); break;
+ case S_OFF_PENDING: offSpiReserved(); break;
+ default: ASSERT(0); break;
}
}
+ async command bool CCA.getNow()
+ {
+ return call CC2420Tx.cca();
+ }
+
+ default event void SplitControl.startDone(error_t error) {}
+ default event void SplitControl.stopDone(error_t error) {}
+
+ default async event void UnslottedCsmaCa.transmitDone(ieee154_txframe_t *frame,
+ ieee154_csma_t *csma, bool ackPendingFlag, error_t result) {}
+ default async event void SlottedCsmaCa.transmitDone(ieee154_txframe_t *frame, ieee154_csma_t *csma,
+ bool ackPendingFlag, uint16_t remainingBackoff, error_t result) {}
- default event void SplitControl.startDone(error_t error){}
- default event void SplitControl.stopDone(error_t error){}
- default async event void Timestamp.transmissionStarted(uint8_t frameType, uint8_t msduHandle, uint8_t *msdu, uint8_t token){}
- default async event void Timestamp.transmittedSFD(uint32_t time, uint8_t frameType, uint8_t msduHandle, uint8_t *msdu, uint8_t token){}
+ default async event void Timestamp.transmissionStarted(uint8_t frameType, uint8_t msduHandle, uint8_t *msdu, uint8_t token) {}
+ default async event void Timestamp.transmittedSFD(uint32_t time, uint8_t frameType, uint8_t msduHandle, uint8_t *msdu, uint8_t token) {}
}
uses interface GeneralIO as CCA;
uses interface GeneralIO as CSN;
uses interface GeneralIO as SFD;
+ uses interface GeneralIO as FIFO;
+ uses interface GeneralIO as FIFOP;
uses interface ChipSpiResource;
uses interface CC2420Fifo as TXFIFO;
};
norace ieee154_txframe_t *m_frame;
- ieee154_reftime_t m_timestamp;
+ ieee154_timestamp_t m_timestamp;
cc2420_transmit_state_t m_state = S_STOPPED;
return FAIL; // channel busy
} else {
m_state = S_SFD;
+ m_frame->metadata->timestamp = IEEE154_INVALID_TIMESTAMP; // pessimistic
call BackoffAlarm.start(CC2420_ABORT_PERIOD);
return SUCCESS;
}
sfdHigh = TRUE;
call CaptureSFD.captureFallingEdge();
// timestamp denotes time of first bit (chip) of PPDU on the channel
- call CaptureTime.convert(time, &m_timestamp, -10); // offset: -10 for 5 bytes (preamble+SFD)
- m_frame->metadata->timestamp = call ReferenceTime.toLocalTime(&m_timestamp);
+ // offset: -10 for 5 bytes (preamble+SFD)
+ if (call CaptureTime.convert(time, &m_timestamp, -10) == SUCCESS)
+ m_frame->metadata->timestamp = call ReferenceTime.toLocalTime(&m_timestamp);
call BackoffAlarm.stop();
if ( call SFD.get() ) {
break;
/** Fall Through because the next interrupt was already received */
default:
+ // The CC2420 is in receive mode.
if ( !m_receiving ) {
sfdHigh = TRUE;
call CaptureSFD.captureFallingEdge();
sfdHigh = FALSE;
call CaptureSFD.captureRisingEdge();
m_receiving = FALSE;
-#ifdef TKN154_PIERCEBOARD
- if ( time - m_prev_time < 10*30 ) {
-#else
- if ( time - m_prev_time < 10 ) {
-#endif
+ if (!call CaptureTime.isValidTimestamp(m_prev_time, time))
call CC2420Receive.sfd_dropped();
- }
break;
}
}
void signalDone( bool ackFramePending, error_t err ) {
+ ieee154_timestamp_t *txTime = &m_timestamp;
atomic m_state = S_STARTED;
- signal CC2420Tx.sendDone( m_frame, &m_timestamp, ackFramePending, err );
+ if (m_frame->metadata->timestamp == IEEE154_INVALID_TIMESTAMP)
+ txTime = NULL;
+ signal CC2420Tx.sendDone( m_frame, txTime, ackFramePending, err );
call ChipSpiResource.attemptRelease();
}
async event void loadTXFIFODone(ieee154_txframe_t *data, error_t error );
async command error_t send(bool cca);
- async event void sendDone(ieee154_txframe_t *frame, ieee154_reftime_t *referenceTime,
+ async event void sendDone(ieee154_txframe_t *frame, ieee154_timestamp_t *referenceTime,
bool ackPendingFlag, error_t error);
async command bool cca();
* @param time capture time
* @param localTime capture time converted to local time + offset symbols
* @param offset time in symbols (16 us) to add to capture time
+ * @return SUCCESS if conversion was made successfully, FAIL otherwise
*/
- async command void convert(uint16_t time, ieee154_reftime_t *localTime, int16_t offset);
+ async command error_t convert(uint16_t time, ieee154_timestamp_t *localTime, int16_t offset);
+
+ /**
+ * Tells whether the timestamp is valid. On the CC2420 an SFD transition
+ * does not necessarily mean that the packet is put in the RXFIFO.
+ * This command should return FALSE iff the time between the rising SFD
+ * and the falling SFD is too short for the smallest possible frame, i.e.
+ * ACK frame (see CC2420 datasheet for details on SFD timing).
+ *
+ * @param risingSFDTime capture time of rising SFD
+ * @param fallingSFDTime capture time of falling SFD
+ * @return FALSE if time offset is too small for a valid packet
+ */
+ async command bool isValidTimestamp(uint16_t risingSFDTime, uint16_t fallingSFDTime);
}
interface ReferenceTime
{
/**
- * Gets current reference time plus dt symbols.
+ * Gets current time and adds dt symbols.
*/
- async command void getNow(ieee154_reftime_t* reftime, uint16_t dt);
+ async command void getNow(ieee154_timestamp_t* time, uint16_t dt);
/**
* Converts reference time to local time.
*/
- async command uint32_t toLocalTime(ieee154_reftime_t* refTime);
+ async command uint32_t toLocalTime(const ieee154_timestamp_t* time);
}
*/
interface ReliableWait
{
- async command void busyWait(uint16_t dt);
- async command void waitRx(ieee154_reftime_t *t0, uint16_t dt);
+ async command void waitRx(uint32_t t0, uint32_t dt);
async event void waitRxDone();
- async command void waitTx(ieee154_reftime_t *t0, uint16_t dt);
+ async command void waitTx(ieee154_timestamp_t *t0, uint32_t dt);
async event void waitTxDone();
- async command void waitBackoff(ieee154_reftime_t *t0, uint16_t dt);
+ async command void waitBackoff(uint32_t dt);
async event void waitBackoffDone();
-
- async command void busyWaitSlotBoundaryCCA(ieee154_reftime_t *t0, uint16_t *dt);
- async command void busyWaitSlotBoundaryTx(ieee154_reftime_t *t0, uint16_t dt);
+ async command bool ccaOnBackoffBoundary(ieee154_timestamp_t *slot0);
}
/**
* Modify (overwrite) the contents of the MAC payload. This command must
* only be called in the context of a <code>transmittedSFD()<\code> event and it
- * should return fast. Note: the smaller offset is the faster
+ * should return fast. Note: the smaller the offset is the faster
* <code>transmittedSFD()<\code> must be finished (offset of zero might not work).
*
* @param token the token signalled by <code>transmittedSFD()<\code>
interface FrameUtility;
interface IEEE154Frame as Frame;
interface Get<uint64_t> as LocalExtendedAddress;
- interface Ieee802154Debug as Debug;
}
}
implementation
return SUCCESS;
}
-/* ------------------- MLME_ASSOCIATE Request ------------------- */
+ /* ------------------- MLME_ASSOCIATE Request ------------------- */
command ieee154_status_t MLME_ASSOCIATE.request (
uint8_t LogicalChannel,
uint16_t CoordPANID,
ieee154_address_t CoordAddress,
ieee154_CapabilityInformation_t CapabilityInformation,
- ieee154_security_t *security
- )
+ ieee154_security_t *security)
{
ieee154_status_t status = IEEE154_SUCCESS;
ieee154_txframe_t *txFrame=0;
status = IEEE154_INVALID_PARAMETER;
else if (m_associationOngoing || !(txFrame = call TxFramePool.get()))
status = IEEE154_TRANSACTION_OVERFLOW;
- else if (!(txControl = call TxControlPool.get())){
+ else if (!(txControl = call TxControlPool.get())) {
call TxFramePool.put(txFrame);
status = IEEE154_TRANSACTION_OVERFLOW;
}
- if (status == IEEE154_SUCCESS){
+ if (status == IEEE154_SUCCESS) {
m_assocRespStatus = IEEE154_NO_DATA;
m_shortAddress = 0xFFFF;
call MLME_SET.phyCurrentChannel(LogicalChannel);
txFrame->payload = m_payloadAssocRequest;
txFrame->payloadLen = 2;
m_associationOngoing = TRUE;
- if ((status = call AssociationRequestTx.transmit(txFrame)) != IEEE154_SUCCESS){
+ if ((status = call AssociationRequestTx.transmit(txFrame)) != IEEE154_SUCCESS) {
m_associationOngoing = FALSE;
call TxFramePool.put(txFrame);
call TxControlPool.put(txControl);
}
}
- call Debug.log(DEBUG_LEVEL_INFO, AssociateP_REQUEST, status, 0, 0);
+ dbg_serial("AssociationP", "MLME_ASSOCIATE.request -> result: %lu\n", (uint32_t) status);
return status;
}
{
call TxControlPool.put((ieee154_txcontrol_t*) ((uint8_t*) txFrame->header - offsetof(ieee154_txcontrol_t, header)));
call TxFramePool.put(txFrame);
- if (status != IEEE154_SUCCESS){
+ if (status != IEEE154_SUCCESS) {
+ dbg_serial("AssociationP", "transmitDone() failed!\n");
m_associationOngoing = FALSE;
signal MLME_ASSOCIATE.confirm(0xFFFF, status, 0);
} else {
call ResponseTimeout.startOneShot(call MLME_GET.macResponseWaitTime()*IEEE154_aBaseSuperframeDuration);
- call Debug.log(DEBUG_LEVEL_INFO, AssociateP_SETTIMER,
- call MLME_GET.macResponseWaitTime()*IEEE154_aBaseSuperframeDuration, 0, 0);
+ dbg_serial("AssociationP", "transmitDone() ok, waiting for %lu\n",
+ (uint32_t) (call MLME_GET.macResponseWaitTime() * IEEE154_aBaseSuperframeDuration));
}
- call Debug.log(DEBUG_LEVEL_INFO, AssociateP_TXDONE, status, 0, 0);
}
event void ResponseTimeout.fired()
else
call FrameUtility.copyCoordExtendedAddressLE(coordAddress);
if (call DataRequest.poll(m_coordAddrMode, call MLME_GET.macPANId(),
- coordAddress, ADDR_MODE_EXTENDED_ADDRESS) != IEEE154_SUCCESS){
+ coordAddress, ADDR_MODE_EXTENDED_ADDRESS) != IEEE154_SUCCESS) {
m_shortAddress = 0xFFFF;
m_assocRespStatus = IEEE154_TRANSACTION_OVERFLOW;
signal DataRequest.pollDone();
event message_t* AssociationResponseExtracted.received(message_t* frame, ieee154_txframe_t *txFrame)
{
uint8_t *payload = (uint8_t *) &frame->data;
- if (m_associationOngoing){
+ if (m_associationOngoing) {
m_shortAddress = *((nxle_uint16_t*) (payload + 1));
m_assocRespStatus = *(payload + 3);
}
event void DataRequest.pollDone()
{
- if (m_associationOngoing){
- call Debug.log(DEBUG_LEVEL_INFO, AssociateP_POLL_DONE, m_payloadAssocRequest[0], m_assocRespStatus, 0);
+ if (m_associationOngoing) {
call ResponseTimeout.stop();
m_associationOngoing = FALSE;
signal MLME_ASSOCIATE.confirm(m_shortAddress, m_assocRespStatus, 0);
+ dbg_serial("AssociationP", "confirm: %lx, %lu\n",
+ (uint32_t) m_shortAddress, (uint32_t) m_assocRespStatus);
}
}
-/* ------------------- MLME_ASSOCIATE Response ------------------- */
+ /* ------------------- MLME_ASSOCIATE Response ------------------- */
event message_t* AssociationRequestRx.received(message_t* frame)
{
uint64_t deviceAddress,
uint16_t assocShortAddress,
ieee154_association_status_t status,
- ieee154_security_t *security
- )
+ ieee154_security_t *security)
{
uint8_t i;
ieee154_status_t txStatus = IEEE154_SUCCESS;
break;
if (i == MAX_PENDING_ASSOC_RESPONSES || !(txFrame = call TxFramePool.get()))
txStatus = IEEE154_TRANSACTION_OVERFLOW;
- else if (!(txControl = call TxControlPool.get())){
+ else if (!(txControl = call TxControlPool.get())) {
call TxFramePool.put(txFrame);
txStatus = IEEE154_TRANSACTION_OVERFLOW;
} else {
*((nxle_uint16_t*) &txFrame->payload[1]) = assocShortAddress;
txFrame->payload[3] = status;
txFrame->payloadLen = 4;
- if ((txStatus = call AssociationResponseTx.transmit(txFrame)) != IEEE154_SUCCESS){
+ if ((txStatus = call AssociationResponseTx.transmit(txFrame)) != IEEE154_SUCCESS) {
txFrame->payload[0] = S_IDLE;
call TxFramePool.put(txFrame);
call TxControlPool.put(txControl);
status, 0);
}
-/* ------------------- Defaults ------------------- */
+ /* ------------------- Defaults ------------------- */
default event void MLME_ASSOCIATE.indication (
uint64_t DeviceAddress,
ieee154_CapabilityInformation_t CapabilityInformation,
- ieee154_security_t *security
- ){}
+ ieee154_security_t *security) {}
default event void MLME_ASSOCIATE.confirm (
uint16_t AssocShortAddress,
uint8_t status,
- ieee154_security_t *security
- ){}
+ ieee154_security_t *security) {}
default event void MLME_COMM_STATUS.indication (
uint16_t PANId,
uint8_t SrcAddrMode,
uint8_t DstAddrMode,
ieee154_address_t DstAddr,
ieee154_status_t status,
- ieee154_security_t *security
- ){}
+ ieee154_security_t *security) {}
}
* ========================================================================
*/
+/**
+ * This module is responsible for periodic beacon tracking in a
+ * beacon-enabled PAN.
+ */
#include "TKN154_MAC.h"
-#include "TKN154_DEBUG.h"
module BeaconSynchronizeP
{
interface MLME_SYNC;
interface MLME_BEACON_NOTIFY;
interface MLME_SYNC_LOSS;
+ interface SuperframeStructure as IncomingSF;
interface GetNow<bool> as IsTrackingBeacons;
- interface GetNow<uint32_t> as CapStart;
- interface GetNow<ieee154_reftime_t*> as CapStartRefTime;
- interface GetNow<uint32_t> as CapLen;
- interface GetNow<uint32_t> as CapEnd;
- interface GetNow<uint32_t> as CfpEnd;
- interface GetNow<uint32_t> as CfpLen;
- interface GetNow<uint32_t> as BeaconInterval;
- interface GetNow<bool> as IsBLEActive;
- interface GetNow<uint16_t> as BLELen;
- interface GetNow<uint8_t*> as GtsField;
- interface GetNow<uint32_t> as SfSlotDuration;
- interface GetNow<uint8_t> as FinalCapSlot;
- interface GetNow<uint8_t> as NumGtsSlots;
- interface GetNow<bool> as IsRxBroadcastPending;
+ interface StdControl as TrackSingleBeacon;
}
uses
{
interface MLME_GET;
interface MLME_SET;
interface FrameUtility;
- interface Notify<bool> as FindBeacon;
interface IEEE154BeaconFrame as BeaconFrame;
interface Alarm<TSymbolIEEE802154,uint32_t> as TrackAlarm;
interface RadioRx as BeaconRx;
interface RadioOff;
- interface GetNow<bool> as IsBeaconEnabledPAN;
interface DataRequest;
interface FrameRx as CoordRealignmentRx;
interface Resource as Token;
interface TimeCalc;
interface IEEE154Frame as Frame;
interface Leds;
- interface Ieee802154Debug as Debug;
}
}
implementation
{
+ /* state variables */
+ norace bool m_tracking;
+ bool m_stopTracking ;
+ norace uint8_t m_numBeaconsLost;
+ norace uint8_t m_state;
+ norace bool m_bufferBusy;
- enum {
- S_PREPARE = 0,
- S_RXNOW = 1,
- S_RADIO_OFF = 2,
- S_FIRST_SCAN= 3,
-
- RX_DURATION = 1000, // listen for a beacon for RX_DURATION symbols
- RX_LAG = 100, // start to listen for a RX_LAG before expected arrival
- };
-
- norace bool m_tracking = FALSE;
- norace bool m_updatePending = FALSE;
+ /* buffers for the parameters of the MLME-SYNC request */
+ norace bool m_updatePending;
uint8_t m_updateLogicalChannel;
bool m_updateTrackBeacon;
- bool m_stopTracking = FALSE;
- bool m_internalRequest = FALSE;
- norace uint8_t m_numBeaconsLost;
- message_t m_beaconBuffer;
- norace message_t *m_beaconBufferPtr = &m_beaconBuffer;
- norace bool m_beaconSwapBufferReady = TRUE;
+ /* variables that describe the current configuration */
norace uint32_t m_beaconInterval;
norace uint32_t m_dt;
norace uint32_t m_lastBeaconRxTime;
- norace ieee154_reftime_t m_lastBeaconRxRefTime;
- norace uint8_t m_state;
+ norace ieee154_timestamp_t m_lastBeaconRxRefTime;
norace uint8_t m_beaconOrder;
+ message_t m_beacon;
+ norace message_t *m_beaconPtr = &m_beacon;
+
+ /* variables that describe the latest superframe */
norace uint32_t m_sfSlotDuration;
- norace uint8_t m_finalCapSlot;
+ norace bool m_framePendingBit;
+ norace uint8_t m_numCapSlots;
norace uint8_t m_numGtsSlots;
- norace uint16_t m_BLELen;
- norace bool m_broadcastPending;
+ norace uint16_t m_battLifeExtDuration;
uint8_t m_gtsField[1+1+3*7];
+
+ enum {
+ S_PREPARE = 0,
+ S_RECEIVING = 1,
+ S_RADIO_OFF = 2,
+ S_INITIAL_SCAN= 3,
+
+ };
+
+ /* function/task prototypes */
task void processBeaconTask();
- void getNextBeacon();
+ void trackNextBeacon();
task void signalGrantedTask();
command error_t Reset.init()
{
- if (call Token.isOwner()){
- call Leds.led0On(); // internal error
- return FAIL;
- }
+ // reset this component. will only be called
+ // while we're not owning the token
if (m_tracking || m_updatePending)
signal MLME_SYNC_LOSS.indication(
IEEE154_BEACON_LOSS,
return SUCCESS;
}
-/* ----------------------- MLME-SYNC ----------------------- */
-/*
- * Allows to synchronize with a coordinator.
- */
+ /* ----------------------- MLME-SYNC ----------------------- */
+ /*
+ * Allows to synchronize with the beacons from a coordinator.
+ */
command ieee154_status_t MLME_SYNC.request (
uint8_t logicalChannel,
uint8_t channelPage,
bool trackBeacon)
{
+ error_t status = IEEE154_SUCCESS;
uint32_t supportedChannels = IEEE154_SUPPORTED_CHANNELS;
uint32_t currentChannelBit = 1;
currentChannelBit <<= logicalChannel;
if (!(currentChannelBit & supportedChannels) || (call MLME_GET.macPANId() == 0xFFFF) ||
- (channelPage != IEEE154_SUPPORTED_CHANNELPAGE) || !call IsBeaconEnabledPAN.getNow())
- return IEEE154_INVALID_PARAMETER;
-
- call Debug.log(DEBUG_LEVEL_INFO,0, logicalChannel, channelPage, trackBeacon);
- if (!trackBeacon && m_tracking){
- // stop tracking after next received beacon
- m_stopTracking = TRUE;
- } else {
- m_stopTracking = FALSE;
- m_updateLogicalChannel = logicalChannel;
- m_updateTrackBeacon = trackBeacon;
- m_internalRequest = FALSE;
- m_updatePending = TRUE;
- call Debug.log(DEBUG_LEVEL_INFO,1, 0, 0, 0);
- atomic {
- // if we are tracking then we'll get the Token automatically,
- // otherwise request it now
- if (!m_tracking && !call Token.isOwner())
- call Token.request();
+ (channelPage != IEEE154_SUPPORTED_CHANNELPAGE) || !IEEE154_BEACON_ENABLED_PAN)
+ status = IEEE154_INVALID_PARAMETER;
+ else {
+ if (!trackBeacon && m_tracking) {
+ // stop tracking after next received beacon
+ m_stopTracking = TRUE;
+ } else {
+ m_stopTracking = FALSE;
+ m_updateLogicalChannel = logicalChannel;
+ m_updateTrackBeacon = trackBeacon;
+ m_updatePending = TRUE;
+ atomic {
+ // if we are tracking then we'll get the Token automatically,
+ // otherwise request it now
+ if (!m_tracking && !call Token.isOwner())
+ call Token.request();
+ }
}
}
- call Debug.flush();
- return IEEE154_SUCCESS;
- }
-
- event void FindBeacon.notify( bool val )
- {
- call Debug.log(DEBUG_LEVEL_IMPORTANT,20, m_tracking, m_updatePending, 0);
- if (!m_tracking && !m_updatePending && !call Token.isOwner()){
- // find a single beacon now (treat this like a user request)
- m_updateLogicalChannel = call MLME_GET.phyCurrentChannel();
- m_updateTrackBeacon = FALSE;
- m_updatePending = TRUE;
- m_internalRequest = TRUE;
- call Token.request();
- }
+ dbg_serial("BeaconSynchronizeP", "MLME_SYNC.request -> result: %lu\n", (uint32_t) status);
+ return status;
}
event void Token.granted()
{
- call Debug.log(DEBUG_LEVEL_INFO,2, m_lastBeaconRxTime+m_beaconInterval,
- m_beaconInterval, (m_updatePending<<1)+m_tracking);
- if (m_updatePending){
- m_state = S_FIRST_SCAN;
+ dbg_serial("BeaconSynchronizeP","Got token, expecting beacon in %lu\n",
+ (uint32_t) ((m_lastBeaconRxTime + m_dt) - call TrackAlarm.getNow()));
+ if (m_updatePending) {
+ dbg_serial("BeaconSynchronizeP", "Preparing initial scan\n");
+ m_state = S_INITIAL_SCAN;
m_updatePending = FALSE;
m_beaconOrder = call MLME_GET.macBeaconOrder();
if (m_beaconOrder >= 15)
m_beaconInterval = ((uint32_t) 1 << m_beaconOrder) * (uint32_t) IEEE154_aBaseSuperframeDuration;
m_dt = m_beaconInterval;
m_numBeaconsLost = IEEE154_aMaxLostBeacons; // will be reset when beacon is received
- call Debug.log(DEBUG_LEVEL_INFO,3, call MLME_GET.macCoordShortAddress(),
- call MLME_GET.macPANId(), m_updateLogicalChannel);
}
- getNextBeacon();
- call Debug.flush();
+ trackNextBeacon();
+ }
+
+ async event void TokenTransferred.transferred()
+ {
+ dbg_serial("BeaconSynchronizeP","Token.transferred(), expecting beacon in %lu symbols.\n",
+ (uint32_t) ((m_lastBeaconRxTime + m_dt) - call TrackAlarm.getNow()));
+ if (call IsTokenRequested.getNow()) {
+ // some other component needs the token - we give it up for now,
+ // but make another request to get it back later
+ dbg_serial("BeaconSynchronizeP", "Token is requested, releasing it now.\n");
+ call Token.request();
+ call Token.release();
+ } else if (m_updatePending)
+ post signalGrantedTask();
+ else
+ trackNextBeacon();
}
- void getNextBeacon()
+
+ task void signalGrantedTask()
+ {
+ signal Token.granted();
+ }
+
+ void trackNextBeacon()
{
bool missed = FALSE;
- if (m_state != S_FIRST_SCAN){
+
+ if (m_state != S_INITIAL_SCAN) {
// we have received at least one previous beacon
m_state = S_PREPARE;
- if (!m_tracking){
+ if (!m_tracking) {
// nothing to do, just give up the token
- call Debug.log(DEBUG_LEVEL_INFO,4, 0, 0, 0);
+ dbg_serial("BeaconSynchronizeP", "Stop tracking.\n");
call Token.release();
return;
}
- while (call TimeCalc.hasExpired(m_lastBeaconRxTime, m_dt)){ // missed a beacon!
+ while (call TimeCalc.hasExpired(m_lastBeaconRxTime, m_dt)) { // missed a beacon!
+ dbg_serial("BeaconSynchronizeP", "Missed a beacon, expected it: %lu, now: %lu\n",
+ m_lastBeaconRxTime + m_dt, call TrackAlarm.getNow());
missed = TRUE;
- call Debug.log(DEBUG_LEVEL_IMPORTANT,5, m_lastBeaconRxTime, m_dt, missed);
m_dt += m_beaconInterval;
m_numBeaconsLost++;
}
- if (m_numBeaconsLost >= IEEE154_aMaxLostBeacons){
- call Debug.log(DEBUG_LEVEL_IMPORTANT,19, m_numBeaconsLost, m_dt, missed);
+ if (m_numBeaconsLost >= IEEE154_aMaxLostBeacons) {
+ dbg_serial("BeaconSynchronizeP", "Missed too many beacons.\n");
post processBeaconTask();
return;
}
- if (missed){
+ if (missed) {
+ // let other components get a chance to use the radio
call Token.request();
- call Debug.log(DEBUG_LEVEL_IMPORTANT,6, m_lastBeaconRxTime, m_dt, missed);
+ dbg_serial("BeaconSynchronizeP", "Allowing other components to get the token.\n");
call Token.release();
return;
}
}
- if (!call RadioOff.isOff())
- call RadioOff.off();
- else
+ if (call RadioOff.isOff())
signal RadioOff.offDone();
- }
-
- async event void TokenTransferred.transferred()
- {
- if (call IsTokenRequested.getNow()){
- // some other component needs the token - we give it up for now,
- // but make another request to get it back later
- call Token.request();
- call Token.release();
- } else if (m_updatePending)
- post signalGrantedTask();
else
- getNextBeacon();
+ ASSERT(call RadioOff.off() == SUCCESS);
}
- task void signalGrantedTask()
+ async event void RadioOff.offDone()
{
- signal Token.granted();
+ uint32_t delay = IEEE154_RADIO_RX_DELAY + IEEE154_MAX_BEACON_JITTER(m_beaconOrder);
+
+ if (m_state == S_INITIAL_SCAN) {
+ // initial scan
+ call BeaconRx.enableRx(0, 0);
+ } else if (m_state == S_PREPARE) {
+ if (!call TimeCalc.hasExpired(m_lastBeaconRxTime - delay, m_dt))
+ call TrackAlarm.startAt(m_lastBeaconRxTime - delay, m_dt);
+ else
+ signal TrackAlarm.fired();
+ } else {
+ post processBeaconTask();
+ }
}
- async event void TrackAlarm.fired()
+ async event void BeaconRx.enableRxDone()
{
- call Debug.log(DEBUG_LEVEL_INFO,7, m_state,m_lastBeaconRxTime,m_dt);
switch (m_state)
{
+ case S_INITIAL_SCAN:
+ m_state = S_RECEIVING;
+ call TrackAlarm.start((((uint32_t) 1 << m_beaconOrder) + (uint32_t) 1) *
+ (uint32_t) IEEE154_aBaseSuperframeDuration * (uint32_t) IEEE154_aMaxLostBeacons);
+ break;
case S_PREPARE:
- call BeaconRx.prepare();
+ m_state = S_RECEIVING;
+ dbg_serial("BeaconSynchronizeP","Rx enabled, expecting beacon in %lu symbols.\n",
+ (uint32_t) ((m_lastBeaconRxTime + m_dt) - call TrackAlarm.getNow()));
+ call TrackAlarm.startAt(m_lastBeaconRxTime, m_dt + IEEE154_MAX_BEACON_LISTEN_TIME(m_beaconOrder));
break;
- case S_RADIO_OFF:
- call RadioOff.off();
+ default:
+ ASSERT(0);
break;
}
}
- async event void BeaconRx.prepareDone()
+ async event void TrackAlarm.fired()
{
- error_t result;
- if (m_state == S_FIRST_SCAN){
- m_state = S_RADIO_OFF;
- atomic {
- call BeaconRx.receive(NULL, 0);
- call TrackAlarm.start((((uint32_t) 1 << m_beaconOrder) + (uint32_t) 1) *
- (uint32_t) IEEE154_aBaseSuperframeDuration * (uint32_t) IEEE154_aMaxLostBeacons);
- }
+ if (m_state == S_PREPARE) {
+ uint32_t maxBeaconJitter = IEEE154_MAX_BEACON_JITTER(m_beaconOrder);
+ if (maxBeaconJitter > m_dt)
+ maxBeaconJitter = m_dt; // receive immediately
+ call BeaconRx.enableRx(m_lastBeaconRxTime, m_dt - maxBeaconJitter);
} else {
- m_state = S_RADIO_OFF;
- result = call BeaconRx.receive(&m_lastBeaconRxRefTime, m_dt-RX_LAG);
- //__nesc_enable_interrupt();
- call Debug.log(DEBUG_LEVEL_INFO,8, m_lastBeaconRxTime, 0,(m_lastBeaconRxTime+m_dt) - call TrackAlarm.getNow());
- if (result != SUCCESS)
- call Debug.log(DEBUG_LEVEL_CRITICAL,9, result, 0, 0);
- call TrackAlarm.startAt(m_lastBeaconRxTime, m_dt + RX_DURATION);
+ ASSERT(m_state == S_RECEIVING && call RadioOff.off() == SUCCESS);
}
}
- event message_t* BeaconRx.received(message_t *frame, ieee154_reftime_t *timestamp)
+ event message_t* BeaconRx.received(message_t *frame, const ieee154_timestamp_t *timestamp)
{
- uint8_t *mhr = MHR(frame);
- call Debug.log(DEBUG_LEVEL_INFO,10,*((nxle_uint32_t*) &mhr[MHR_INDEX_ADDRESS]),
- mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK,mhr[MHR_INDEX_SEQNO]);
- if (!m_beaconSwapBufferReady || !call FrameUtility.isBeaconFromCoord(frame))
+ if (m_bufferBusy || !call FrameUtility.isBeaconFromCoord(frame))
{
- call Debug.log(DEBUG_LEVEL_IMPORTANT,11, m_beaconSwapBufferReady, 0, 0);
+ if (m_bufferBusy) {
+ dbg_serial("BeaconSynchronizeP", "Got another beacon, dropping it.\n");}
+ else
+ dbg_serial("BeaconSynchronizeP", "Got a beacon, but not from my coordinator.\n");
return frame;
} else {
- error_t resultOff;
- message_t *tmp = m_beaconBufferPtr;
- call TrackAlarm.stop();
- m_beaconSwapBufferReady = FALSE;
- m_beaconBufferPtr = frame;
- resultOff = call RadioOff.off();
- if (timestamp != NULL){
- memcpy(&m_lastBeaconRxRefTime, timestamp, sizeof(ieee154_reftime_t));
- call Debug.log(DEBUG_LEVEL_INFO,23,0, 0, resultOff);
+ message_t *tmp = m_beaconPtr;
+ m_bufferBusy = TRUE;
+ m_beaconPtr = frame;
+ if (timestamp != NULL)
+ memcpy(&m_lastBeaconRxRefTime, timestamp, sizeof(ieee154_timestamp_t));
+ if (m_state == S_RECEIVING) {
+ call TrackAlarm.stop(); // may fail
+ call RadioOff.off(); // may fail
}
return tmp;
}
}
- async event void RadioOff.offDone()
- {
- if (m_state == S_FIRST_SCAN)
- call BeaconRx.prepare();
- else if (m_state == S_PREPARE){
- if (!call TimeCalc.hasExpired(m_lastBeaconRxTime, m_dt - IEEE154_RADIO_RX_PREPARE_DELAY))
- call TrackAlarm.startAt(m_lastBeaconRxTime, m_dt - IEEE154_RADIO_RX_PREPARE_DELAY);
- else
- signal TrackAlarm.fired();
- } else {
- post processBeaconTask();
- }
- }
-
task void processBeaconTask()
{
- // valid beacon timestamp is pre-condition for slotted CSMA-CA
- if (m_beaconSwapBufferReady || !call Frame.isTimestampValid(m_beaconBufferPtr)){
- // missed a beacon!
- if (!m_beaconSwapBufferReady)
- call Debug.log(DEBUG_LEVEL_IMPORTANT, 21,m_numBeaconsLost,m_beaconSwapBufferReady,m_lastBeaconRxTime);
+ // if we received a beacon from our coordinator then it is processed now
+ if (!m_bufferBusy || !call Frame.isTimestampValid(m_beaconPtr)) {
+ // missed a beacon or received a beacon with invalid timestamp
+ if (!m_bufferBusy)
+ dbg_serial("BeaconSynchronizeP", "No beacon received!\n");
else
- call Debug.log(DEBUG_LEVEL_IMPORTANT, 12,m_numBeaconsLost,m_beaconSwapBufferReady,m_lastBeaconRxTime);
- m_sfSlotDuration = 0; // CAP len will be 0
- m_numBeaconsLost++;
+ dbg_serial("BeaconSynchronizeP", "Beacon has invalid timestamp!\n");
+
+ m_numBeaconsLost += 1;
m_dt += m_beaconInterval;
- m_beaconSwapBufferReady = TRUE;
- if (m_numBeaconsLost >= IEEE154_aMaxLostBeacons){
+ m_bufferBusy = FALSE;
+
+ if (m_numBeaconsLost >= IEEE154_aMaxLostBeacons) {
+ // lost too many beacons, give up!
m_tracking = FALSE;
- call Debug.log(DEBUG_LEVEL_IMPORTANT, 13,m_internalRequest,0,0);
- call Leds.led2Off();
- if (m_internalRequest){
- call TokenToCap.transfer();
- return;
- } else
- signal MLME_SYNC_LOSS.indication(
+ dbg_serial("BeaconSynchronizeP", "MLME_SYNC_LOSS!\n");
+ signal MLME_SYNC_LOSS.indication(
IEEE154_BEACON_LOSS,
call MLME_GET.macPANId(),
call MLME_GET.phyCurrentChannel(),
call MLME_GET.phyCurrentPage(),
- NULL // security
- );
+ NULL);
} else
call Token.request(); // make another request again (before giving the token up)
- call Debug.log(DEBUG_LEVEL_INFO,14, 0, 0, 0);
+
call Token.release();
} else {
// got the beacon!
- uint8_t *payload = (uint8_t *) m_beaconBufferPtr->data;
+ uint8_t *payload = (uint8_t *) m_beaconPtr->data;
ieee154_macAutoRequest_t autoRequest = call MLME_GET.macAutoRequest();
uint8_t pendAddrSpecOffset = 3 + (((payload[2] & 7) > 0) ? 1 + (payload[2] & 7) * 3: 0); // skip GTS
uint8_t pendAddrSpec = payload[pendAddrSpecOffset];
uint8_t *beaconPayload = payload + pendAddrSpecOffset + 1;
- uint8_t beaconPayloadSize = call BeaconFrame.getBeaconPayloadLength(m_beaconBufferPtr);
+ uint8_t beaconPayloadSize = call BeaconFrame.getBeaconPayloadLength(m_beaconPtr);
uint8_t pendingAddrMode = ADDR_MODE_NOT_PRESENT;
uint8_t coordBeaconOrder;
- uint8_t *mhr = MHR(m_beaconBufferPtr);
- uint8_t frameLen = ((uint8_t*) m_beaconBufferPtr)[0] & FRAMECTL_LENGTH_MASK;
+ uint8_t *mhr = MHR(m_beaconPtr);
+ uint8_t frameLen = ((uint8_t*) m_beaconPtr)[0] & FRAMECTL_LENGTH_MASK;
uint8_t gtsFieldLength;
- uint32_t timestamp = call Frame.getTimestamp(m_beaconBufferPtr);
+ uint32_t timestamp = call Frame.getTimestamp(m_beaconPtr);
+
+ dbg_serial("BeaconSynchronizeP", "Got beacon, timestamp: %lu, offset to previous: %lu\n",
+ (uint32_t) timestamp, (uint32_t) (timestamp - m_lastBeaconRxTime));
- call Debug.log(DEBUG_LEVEL_INFO, 15, m_lastBeaconRxTime, timestamp, mhr[2]);
m_numGtsSlots = (payload[2] & 7);
gtsFieldLength = 1 + ((m_numGtsSlots > 0) ? 1 + m_numGtsSlots * 3: 0);
m_lastBeaconRxTime = timestamp;
- m_finalCapSlot = (payload[1] & 0x0F);
+ m_numCapSlots = (payload[1] & 0x0F) + 1;
m_sfSlotDuration = (((uint32_t) 1) << ((payload[0] & 0xF0) >> 4)) * IEEE154_aBaseSlotDuration;
memcpy(m_gtsField, &payload[2], gtsFieldLength);
// check for battery life extension
- if (payload[1] & 0x10){
+ if (payload[1] & 0x10) {
// BLE is active; calculate the time offset from slot0
- m_BLELen = IEEE154_SHR_DURATION + frameLen * IEEE154_SYMBOLS_PER_OCTET;
+ m_battLifeExtDuration = IEEE154_SHR_DURATION + frameLen * IEEE154_SYMBOLS_PER_OCTET;
if (frameLen > IEEE154_aMaxSIFSFrameSize)
- m_BLELen += call MLME_GET.macMinLIFSPeriod();
+ m_battLifeExtDuration += call MLME_GET.macMinLIFSPeriod();
else
- m_BLELen += call MLME_GET.macMinSIFSPeriod();
- m_BLELen = m_BLELen + call MLME_GET.macBattLifeExtPeriods() * 20;
+ m_battLifeExtDuration += call MLME_GET.macMinSIFSPeriod();
+ m_battLifeExtDuration = m_battLifeExtDuration + call MLME_GET.macBattLifeExtPeriods() * 20;
} else
- m_BLELen = 0;
- m_broadcastPending = mhr[MHR_INDEX_FC1] & FC1_FRAME_PENDING ? TRUE : FALSE;
+ m_battLifeExtDuration = 0;
+
+ m_framePendingBit = mhr[MHR_INDEX_FC1] & FC1_FRAME_PENDING ? TRUE : FALSE;
coordBeaconOrder = (payload[0] & 0x0F);
m_dt = m_beaconInterval = ((uint32_t) 1 << coordBeaconOrder) * (uint32_t) IEEE154_aBaseSuperframeDuration;
- if (m_stopTracking){
+
+ if (m_stopTracking) {
m_tracking = FALSE;
- call Debug.log(DEBUG_LEVEL_INFO,16, 0, 0, 0);
- if (m_updatePending) // there is already a new request pending...
+ dbg_serial("BeaconSynchronizeP", "Stop tracking.\n");
+ if (m_updatePending) // there is already a new request ...
call Token.request();
call Token.release();
} else {
- call Debug.log(DEBUG_LEVEL_INFO,17, 0, 0, 0);
- call TokenToCap.transfer(); // borrow Token to CAP/CFP module, we'll get it back afterwards
+ dbg_serial("BeaconSynchronizeP", "Handing over to CAP.\n");
+ call TokenToCap.transfer();
}
if (pendAddrSpec & PENDING_ADDRESS_SHORT_MASK)
beaconPayload += (pendAddrSpec & PENDING_ADDRESS_SHORT_MASK) * 2;
if (pendAddrSpec & PENDING_ADDRESS_EXT_MASK)
beaconPayload += ((pendAddrSpec & PENDING_ADDRESS_EXT_MASK) >> 4) * 8;
+
// check for pending data (once we signal MLME_BEACON_NOTIFY we cannot
- // touch the frame anymore)
+ // touch this frame anymore!)
if (autoRequest)
- pendingAddrMode = call BeaconFrame.isLocalAddrPending(m_beaconBufferPtr);
- if (pendingAddrMode != ADDR_MODE_NOT_PRESENT){
+ pendingAddrMode = call BeaconFrame.isLocalAddrPending(m_beaconPtr);
+ if (pendingAddrMode != ADDR_MODE_NOT_PRESENT) {
// the coord has pending data
uint8_t CoordAddrMode;
uint16_t CoordPANId;
CoordPANId = *((nxle_uint16_t*) &(mhr[MHR_INDEX_ADDRESS]));
call DataRequest.poll(CoordAddrMode, CoordPANId, CoordAddress, SrcAddrMode);
}
+
// Beacon Tracking: update state
- call Debug.log(DEBUG_LEVEL_INFO, 18, m_lastBeaconRxTime, m_beaconInterval, 0);
m_numBeaconsLost = 0;
// TODO: check PAN ID conflict here?
if (!autoRequest || beaconPayloadSize)
- m_beaconBufferPtr = signal MLME_BEACON_NOTIFY.indication(m_beaconBufferPtr);
- m_beaconSwapBufferReady = TRUE;
+ m_beaconPtr = signal MLME_BEACON_NOTIFY.indication(m_beaconPtr);
+ m_bufferBusy = FALSE;
}
+ dbg_serial_flush();
}
- async command bool IsTrackingBeacons.getNow(){ return m_tracking;}
-
- default event message_t* MLME_BEACON_NOTIFY.indication (message_t* frame){return frame;}
+ command error_t TrackSingleBeacon.start()
+ {
+ // Track a single beacon now
+ if (!m_tracking && !m_updatePending && !call Token.isOwner()) {
+ // find a single beacon now (treat this like a user request)
+ m_updateLogicalChannel = call MLME_GET.phyCurrentChannel();
+ m_updateTrackBeacon = FALSE;
+ m_stopTracking = TRUE;
+ m_updatePending = TRUE;
+ call Token.request();
+ }
+ return SUCCESS;
+ }
- default event void MLME_SYNC_LOSS.indication (
- ieee154_status_t lossReason,
- uint16_t panID,
- uint8_t logicalChannel,
- uint8_t channelPage,
- ieee154_security_t *security){}
+ command error_t TrackSingleBeacon.stop()
+ {
+ // will stop automatically after beacon was tracked/not found
+ return FAIL;
+ }
- event void DataRequest.pollDone(){}
-
- async command uint8_t* GtsField.getNow() { return m_gtsField; }
- async command uint32_t SfSlotDuration.getNow() { return m_sfSlotDuration; }
- async command uint8_t FinalCapSlot.getNow() { return m_finalCapSlot; }
- async command uint32_t CapStart.getNow() { return m_lastBeaconRxTime; }
- async command ieee154_reftime_t* CapStartRefTime.getNow() { return &m_lastBeaconRxRefTime; }
- async command uint32_t CapLen.getNow() { return call SfSlotDuration.getNow() * (call FinalCapSlot.getNow() + 1);}
- async command uint32_t CapEnd.getNow()
+ /* ----------------------- SF Structure, etc. ----------------------- */
+
+ async command uint32_t IncomingSF.sfStartTime()
+ {
+ return m_lastBeaconRxTime;
+ }
+
+ async command uint16_t IncomingSF.sfSlotDuration()
+ {
+ return m_sfSlotDuration;
+ }
+
+ async command uint8_t IncomingSF.numCapSlots()
{
- return call CapStart.getNow() + call CapLen.getNow();
+ return m_numCapSlots;
}
- async command uint32_t CfpEnd.getNow()
+
+ async command uint8_t IncomingSF.numGtsSlots()
{
- return call CapStart.getNow() + call SfSlotDuration.getNow() * IEEE154_aNumSuperframeSlots;
+ return m_numGtsSlots;
}
- async command uint32_t CfpLen.getNow()
+
+ async command uint16_t IncomingSF.battLifeExtDuration()
{
- return call SfSlotDuration.getNow() * (15 - call FinalCapSlot.getNow());
+ return m_battLifeExtDuration;
}
- async command uint32_t BeaconInterval.getNow()
+
+ async command const uint8_t* IncomingSF.gtsFields()
{
- return m_beaconInterval;
+ return m_gtsField;
}
- async command uint8_t NumGtsSlots.getNow() { return m_numGtsSlots; }
- async command bool IsBLEActive.getNow(){ return m_BLELen>0;}
- async command uint16_t BLELen.getNow(){ return m_BLELen;}
- async command bool IsRxBroadcastPending.getNow() { return m_broadcastPending; }
+
+ async command uint16_t IncomingSF.guardTime()
+ {
+ return IEEE154_MAX_BEACON_JITTER(m_beaconOrder) + IEEE154_RADIO_RX_DELAY;
+ }
+
+ async command const ieee154_timestamp_t* IncomingSF.sfStartTimeRef()
+ {
+ return &m_lastBeaconRxRefTime;
+ }
+
+ async command bool IncomingSF.isBroadcastPending()
+ {
+ return m_framePendingBit;
+ }
+
+ async command bool IsTrackingBeacons.getNow()
+ {
+ return m_tracking;
+ }
+
+ event void DataRequest.pollDone() {}
+
+ default event message_t* MLME_BEACON_NOTIFY.indication (message_t* frame) {return frame;}
+ default event void MLME_SYNC_LOSS.indication (
+ ieee154_status_t lossReason,
+ uint16_t panID,
+ uint8_t logicalChannel,
+ uint8_t channelPage,
+ ieee154_security_t *security) {}
event message_t* CoordRealignmentRx.received(message_t* frame)
{
panID, // PANId
payload[5], // LogicalChannel,
call Frame.getPayloadLength(frame) == 9 ? payload[8] : call MLME_GET.phyCurrentPage(),
- NULL
- );
+ NULL);
return frame;
}
}
* ========================================================================
*/
+/**
+ * This module is responsible for periodic beacon transmission in a
+ * beacon-enabled PAN.
+ */
+
#include "TKN154_MAC.h"
#include "TKN154_PHY.h"
module BeaconTransmitP
{
interface Init as Reset;
interface MLME_START;
- interface WriteBeaconField as SuperframeSpecWrite;
- interface GetNow<bool> as IsSendingBeacons;
- interface GetNow<uint32_t> as CapStart;
- interface GetNow<ieee154_reftime_t*> as CapStartRefTime;
- interface GetNow<uint32_t> as CapLen;
- interface GetNow<uint32_t> as CapEnd;
- interface GetNow<uint32_t> as CfpEnd;
- interface GetNow<uint32_t> as CfpLen;
- interface GetNow<bool> as IsBLEActive;
- interface GetNow<uint16_t> as BLELen;
- interface GetNow<uint8_t*> as GtsField;
- interface GetNow<uint32_t> as SfSlotDuration;
- interface GetNow<uint32_t> as BeaconInterval;
- interface GetNow<uint8_t> as FinalCapSlot;
- interface GetNow<uint8_t> as NumGtsSlots;
- interface GetNow<bool> as BeaconFramePendingBit;
interface IEEE154TxBeaconPayload;
+ interface SuperframeStructure as OutgoingSF;
+ interface GetNow<bool> as IsSendingBeacons;
} uses {
interface Notify<bool> as GtsSpecUpdated;
interface Notify<bool> as PendingAddrSpecUpdated;
interface Notify<const void*> as PIBUpdate[uint8_t attributeID];
- interface Alarm<TSymbolIEEE802154,uint32_t> as BeaconTxAlarm;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as BeaconSendAlarm;
interface Timer<TSymbolIEEE802154> as BeaconPayloadUpdateTimer;
interface RadioOff;
- interface GetNow<bool> as IsBeaconEnabledPAN;
interface RadioTx as BeaconTx;
interface MLME_GET;
interface MLME_SET;
interface WriteBeaconField as PendingAddrWrite;
interface FrameUtility;
interface GetNow<bool> as IsTrackingBeacons;
- interface GetNow<uint32_t> as LastBeaconRxTime;
- interface GetNow<ieee154_reftime_t*> as LastBeaconRxRefTime;
- interface Ieee802154Debug as Debug;
+ interface SuperframeStructure as IncomingSF;
interface Set<ieee154_macSuperframeOrder_t> as SetMacSuperframeOrder;
interface Set<ieee154_macBeaconTxTime_t> as SetMacBeaconTxTime;
interface Set<ieee154_macPanCoordinator_t> as SetMacPanCoordinator;
}
implementation
{
+ /* state variables */
+ norace uint8_t m_requestBitmap;
+ norace uint8_t m_txState;
+ uint8_t m_payloadState;
+ norace bool m_txOneBeaconImmediately;
+
+ /* variables that describe the current superframe configuration */
+ norace uint32_t m_startTime;
+ norace uint8_t m_beaconOrder;
+ norace uint8_t m_superframeOrder;
+ norace uint32_t m_beaconInterval;
+ norace uint32_t m_previousBeaconInterval;
+ norace uint32_t m_dt;
+ norace uint8_t m_bsn;
+ norace uint32_t m_lastBeaconTxTime;
+ norace ieee154_timestamp_t m_lastBeaconTxRefTime;
+ norace ieee154_macBattLifeExtPeriods_t m_battLifeExtPeriods;
+
+ /* variables that describe the latest superframe */
+ norace uint32_t m_sfSlotDuration;
+ norace bool m_framePendingBit;
+ norace uint8_t m_numCapSlots;
+ norace uint8_t m_numGtsSlots;
+ norace uint16_t m_battLifeExtDuration;
+ uint8_t m_gtsField[1+1+3*7];
+
+ /* variables that describe the beacon (payload) */
+ norace ieee154_txframe_t m_beaconFrame;
+ ieee154_header_t m_header;
+ ieee154_metadata_t m_metadata;
+ void *m_updateBeaconPayload;
+ uint8_t m_updateBeaconOffset;
+ uint8_t m_updateBeaconLength;
+ uint8_t m_beaconPayloadLen;
+ uint8_t m_pendingAddrLen;
+ uint8_t m_pendingGtsLen;
+
+ /* buffers for the parameters of the MLME-START request */
+ uint16_t m_updatePANId;
+ uint8_t m_updateLogicalChannel;
+ uint32_t m_updateStartTime;
+ norace uint8_t m_updateBeaconOrder;
+ uint8_t m_updateSuperframeOrder;
+ bool m_updatePANCoordinator;
+ bool m_updateBatteryLifeExtension;
enum {
MAX_BEACON_PAYLOAD_SIZE = IEEE154_aMaxBeaconOverhead + IEEE154_aMaxBeaconPayloadLength,
S_TX_LOCKED = 1,
S_TX_WAITING = 2,
};
-
- norace ieee154_txframe_t m_beaconFrame;
- ieee154_header_t m_header;
uint8_t m_payload[MAX_BEACON_PAYLOAD_SIZE];
- ieee154_metadata_t m_metadata;
- uint8_t m_gtsField[1+1+3*7];
-
- void *m_updateBeaconPayload;
- uint8_t m_updateBeaconOffset;
- uint8_t m_updateBeaconLength;
- uint8_t m_beaconPayloadLen;
- uint8_t m_pendingAddrLen;
- uint8_t m_pendingGtsLen;
-
- norace uint8_t m_requests; // TODO: check why norace?
- norace uint8_t m_txState;
- uint8_t m_payloadState;
- norace bool m_txOneBeaconImmediately;
-
- uint16_t m_PANId;
- norace uint32_t m_startTime;
- uint8_t m_logicalChannel;
- norace uint8_t m_beaconOrder;
- norace uint8_t m_superframeOrder;
- ieee154_macBattLifeExt_t m_batteryLifeExtension;
- bool m_PANCoordinator;
- norace uint32_t m_beaconInterval;
- norace uint32_t m_previousBeaconInterval;
- norace uint32_t m_dt;
- norace uint8_t m_bsn;
- norace uint32_t m_lastBeaconTxTime;
- norace ieee154_reftime_t m_lastBeaconTxRefTime;
- norace uint32_t m_coordCapLen;
- norace uint32_t m_coordCfpEnd;
- norace uint32_t m_sfSlotDuration;
- norace uint8_t m_finalCAPSlot;
- norace uint8_t m_numGtsSlots;
- norace uint16_t m_BLELen;
- norace ieee154_macBattLifeExtPeriods_t m_battLifeExtPeriods;
- norace bool m_framePendingBit;
-
- uint16_t m_updatePANId;
- uint8_t m_updateLogicalChannel;
- uint32_t m_updateStartTime;
- norace uint8_t m_updateBeaconOrder;
- uint8_t m_updateSuperframeOrder;
- bool m_updatePANCoordinator;
- bool m_updateBatteryLifeExtension;
+ /* function/task prototypes */
task void txDoneTask();
task void signalStartConfirmSuccessTask();
void prepareNextBeaconTransmission();
command error_t Reset.init()
{
+ // reset this component, will only be called while we're not owning the token
+ // TODO: check to signal MLME_START.confirm ?
m_beaconFrame.header = &m_header;
m_beaconFrame.headerLen = 0;
m_beaconFrame.payload = m_payload;
m_beaconFrame.payloadLen = 0;
m_beaconFrame.metadata = &m_metadata;
- m_updateBeaconPayload = 0;
+ m_updateBeaconPayload = NULL;
m_updateBeaconLength = 0;
- m_requests = m_payloadState = m_txState = 0;
- m_PANCoordinator = FALSE;
+ m_requestBitmap = m_payloadState = m_txState = 0;
m_beaconPayloadLen = m_pendingAddrLen = m_pendingGtsLen = 0;
m_gtsField[0] = 0;
- m_finalCAPSlot = 15;
+ m_numCapSlots = 0;
+ m_numGtsSlots = 0;
m_beaconOrder = 15;
call BeaconPayloadUpdateTimer.stop();
- call BeaconTxAlarm.stop();
+ call BeaconSendAlarm.stop();
return SUCCESS;
}
-/* ----------------------- MLME-START ----------------------- */
-/* "The MLME-START.request primitive allows the PAN coordinator to initiate a
- * new PAN or to begin using a new superframe configuration. This primitive may
- * also be used by a device already associated with an existing PAN to begin
- * using a new superframe configuration." (IEEE 802.15.4-2006 Sect. 7.1.14.1)
- **/
+ /* ----------------------- MLME-START ----------------------- */
+ /* "The MLME-START.request primitive allows the PAN coordinator to initiate a
+ * new PAN or to begin using a new superframe configuration. This primitive may
+ * also be used by a device already associated with an existing PAN to begin
+ * using a new superframe configuration." (IEEE 802.15.4-2006 Sect. 7.1.14.1)
+ **/
command ieee154_status_t MLME_START.request (
uint16_t panID,
ieee154_security_t *coordRealignSecurity,
ieee154_security_t *beaconSecurity)
{
- ieee154_macShortAddress_t shortAddress = call MLME_GET.macShortAddress();
ieee154_status_t status = IEEE154_SUCCESS;
+ ieee154_macShortAddress_t shortAddress = call MLME_GET.macShortAddress();
+ // check parameters
if ((coordRealignSecurity && coordRealignSecurity->SecurityLevel) ||
(beaconSecurity && beaconSecurity->SecurityLevel))
status = IEEE154_UNSUPPORTED_SECURITY;
status = IEEE154_TRACKING_OFF;
else if (startTime && 0xFF000000)
status = IEEE154_INVALID_PARAMETER;
- else if (m_requests & (REQUEST_CONFIRM_PENDING | REQUEST_UPDATE_SF))
+ else if (m_requestBitmap & (REQUEST_CONFIRM_PENDING | REQUEST_UPDATE_SF))
status = IEEE154_TRANSACTION_OVERFLOW;
- else if ((call IsBeaconEnabledPAN.getNow() && beaconOrder == 15) ||
- (!call IsBeaconEnabledPAN.getNow() && beaconOrder < 15))
- status = IEEE154_INVALID_PARAMETER;
else {
- // new configuration *will* be put in operation
- status = IEEE154_SUCCESS;
+
+ // New configuration *will* be put in operation, we'll buffer
+ // the parameters now, and continue once we get the token.
if (panCoordinator)
- startTime = 0; // start immediately
- call Debug.log(DEBUG_LEVEL_INFO, 0, logicalChannel, beaconOrder, superframeOrder);
- if (beaconOrder == 15){
- // beaconless PAN
- superframeOrder = 15;
- }
+ startTime = 0; // start immediately
+ if (beaconOrder == 15)
+ superframeOrder = 15; // beaconless PAN
m_updatePANId = panID;
m_updateLogicalChannel = logicalChannel;
m_updateStartTime = startTime;
m_updateSuperframeOrder = superframeOrder;
m_updatePANCoordinator = panCoordinator;
m_updateBatteryLifeExtension = batteryLifeExtension;
- m_requests = (REQUEST_CONFIRM_PENDING | REQUEST_UPDATE_SF); // lock
+ m_requestBitmap = (REQUEST_CONFIRM_PENDING | REQUEST_UPDATE_SF); // lock
+
if (coordRealignment)
- m_requests |= REQUEST_REALIGNMENT;
- if (m_beaconOrder == 15) // only request token if we're not already transmitting beacons
- call Token.request(); // otherwise we'll get it eventually and update the superframe then
+ m_requestBitmap |= REQUEST_REALIGNMENT;
+ if (m_beaconOrder == 15) {
+ // We're not already transmitting beacons, i.e. we have to request the token
+ // (otherwise we'd get the token "automatically" for the next scheduled beacon).
+ call Token.request();
+ }
+ // We'll continue the MLME_START operation in continueStartRequest() once we have the token
}
+ dbg_serial("BeaconTransmitP", "MLME_START.request -> result: %lu\n", (uint32_t) status);
return status;
}
bool isShortAddr;
// (1) coord realignment?
- if (m_requests & REQUEST_REALIGNMENT){
+ if (m_requestBitmap & REQUEST_REALIGNMENT) {
ieee154_txframe_t *realignmentFrame = call GetSetRealignmentFrame.get();
- m_requests &= ~REQUEST_REALIGNMENT;
- if (realignmentFrame == NULL){
+ m_requestBitmap &= ~REQUEST_REALIGNMENT;
+ if (realignmentFrame == NULL) {
// allocation failed!
- m_requests = 0;
+ m_requestBitmap = 0;
signal MLME_START.confirm(IEEE154_TRANSACTION_OVERFLOW);
return;
}
*((nxle_uint16_t*) &realignmentFrame->payload[6]) = 0xFFFF;
realignmentFrame->payloadLen = 8;
- if (m_beaconOrder < 15){
+ if (m_beaconOrder < 15) {
// we're already transmitting beacons; the realignment frame
// must be sent (broadcast) after the next beacon
- if (call RealignmentBeaconEnabledTx.transmit(realignmentFrame) != IEEE154_SUCCESS){
- m_requests = 0;
+ if (call RealignmentBeaconEnabledTx.transmit(realignmentFrame) != IEEE154_SUCCESS) {
+ m_requestBitmap = 0;
call GetSetRealignmentFrame.set(realignmentFrame);
signal MLME_START.confirm(IEEE154_TRANSACTION_OVERFLOW);
} else {
// the next beacon - the result will be signalled in
// RealignmentBeaconEnabledTx.transmitDone(). Only then the superframe
// structure is updated and MLME_START.confirm signalled.
- m_requests |= REQUEST_REALIGNMENT_DONE_PENDING; // lock
+ m_requestBitmap |= REQUEST_REALIGNMENT_DONE_PENDING; // lock
}
} else {
// send realignment frame in unslotted csma-ca now
- if (call RealignmentNonBeaconEnabledTx.transmit(realignmentFrame) != IEEE154_SUCCESS){
- m_requests = 0;
+ if (call RealignmentNonBeaconEnabledTx.transmit(realignmentFrame) != IEEE154_SUCCESS) {
+ m_requestBitmap = 0;
call GetSetRealignmentFrame.set(realignmentFrame);
signal MLME_START.confirm(IEEE154_TRANSACTION_OVERFLOW);
} else {
// be signalled in RealignmentNonBeaconEnabledTx.transmitDone(). Only
// then the superframe structure is updated and MLME_START.confirm
// signalled.
- m_requests |= REQUEST_REALIGNMENT_DONE_PENDING; // lock
+ m_requestBitmap |= REQUEST_REALIGNMENT_DONE_PENDING; // lock
}
}
return;
m_startTime = m_updateStartTime;
m_txOneBeaconImmediately = FALSE;
m_previousBeaconInterval = 0;
- if (m_startTime){
- m_lastBeaconTxRefTime = *call LastBeaconRxRefTime.getNow();
- m_lastBeaconTxTime = call LastBeaconRxTime.getNow();
+ if (m_startTime) {
+ memcpy(&m_lastBeaconTxRefTime, call IncomingSF.sfStartTimeRef(), sizeof(ieee154_timestamp_t));
+ m_lastBeaconTxTime = call IncomingSF.sfStartTime();
} else {
// no StartTime defined by next higher layer - but
// if a realignment frame was transmitted, the next
// beacon tx time must take the old BI into consideration
- if (m_requests & REQUEST_REALIGNMENT_DONE_PENDING)
+ if (m_requestBitmap & REQUEST_REALIGNMENT_DONE_PENDING)
m_previousBeaconInterval = m_beaconInterval;
else
m_txOneBeaconImmediately = TRUE;
}
- m_PANId = m_updatePANId;
- m_logicalChannel = m_updateLogicalChannel;
m_beaconOrder = m_updateBeaconOrder;
m_superframeOrder = m_updateSuperframeOrder;
- m_PANCoordinator = m_updatePANCoordinator;
- if (m_beaconOrder < 15){
- m_batteryLifeExtension = m_updateBatteryLifeExtension;
+ if (m_beaconOrder < 15) {
m_beaconInterval = ((uint32_t) 1 << m_updateBeaconOrder) * IEEE154_aBaseSuperframeDuration;
} else {
- m_batteryLifeExtension = FALSE;
m_beaconInterval = 0;
}
+ m_dt = m_beaconInterval;
m_txState = S_TX_IDLE;
m_bsn = call MLME_GET.macBSN()+1;
m_battLifeExtPeriods = call MLME_GET.macBattLifeExtPeriods();
// (3) update PIB
call MLME_SET.macBeaconOrder(m_beaconOrder);
call SetMacSuperframeOrder.set(m_superframeOrder);
- call MLME_SET.macPANId(m_PANId);
- call MLME_SET.phyCurrentChannel(m_logicalChannel);
+ call MLME_SET.macPANId(m_updatePANId);
+ call MLME_SET.phyCurrentChannel(m_updateLogicalChannel);
if (m_beaconOrder < 15)
- call MLME_SET.macBattLifeExt(m_batteryLifeExtension);
- call SetMacPanCoordinator.set(m_PANCoordinator);
+ call MLME_SET.macBattLifeExt(m_updateBatteryLifeExtension);
+ call SetMacPanCoordinator.set(m_updatePANCoordinator);
// (4) assemble beacon header and payload
shortAddress = call MLME_GET.macShortAddress();
m_beaconFrame.header->mhr[MHR_INDEX_FC1] = FC1_FRAMETYPE_BEACON;
m_beaconFrame.header->mhr[MHR_INDEX_FC2] = isShortAddr ? FC2_SRC_MODE_SHORT : FC2_SRC_MODE_EXTENDED;
offset = MHR_INDEX_ADDRESS;
- *((nxle_uint16_t*) &m_beaconFrame.header->mhr[offset]) = m_PANId;
+ *((nxle_uint16_t*) &m_beaconFrame.header->mhr[offset]) = m_updatePANId;
offset += sizeof(ieee154_macPANId_t);
- if (isShortAddr){
+ if (isShortAddr) {
*((nxle_uint16_t*) &m_beaconFrame.header->mhr[offset]) = shortAddress;
offset += sizeof(ieee154_macShortAddress_t);
} else {
m_payloadState |= MODIFIED_SPECS_MASK; // update beacon payload
signal BeaconPayloadUpdateTimer.fired(); // assemble initial beacon payload
- if (m_beaconOrder < 15){
+ if (m_beaconOrder < 15) {
// beacon-enabled PAN, signal confirm after next
// beacon has been transmitted (see MSC, Fig. 38)
- m_requests = REQUEST_CONFIRM_PENDING;
+ m_requestBitmap = REQUEST_CONFIRM_PENDING;
} else {
// beaconless PAN, we're done
- m_requests = 0;
+ m_requestBitmap = 0;
signal MLME_START.confirm(IEEE154_SUCCESS);
}
}
event void Token.granted()
{
- call Debug.flush();
- call Debug.log(DEBUG_LEVEL_INFO, 1, m_lastBeaconTxTime, m_beaconInterval, m_requests);
- if (m_requests & REQUEST_REALIGNMENT_DONE_PENDING){
+ dbg_serial("BeaconSynchronizeP","Got token, will Tx beacon in %lu\n",
+ (uint32_t) ((m_lastBeaconTxTime + m_dt) - call BeaconSendAlarm.getNow()));
+ if (m_requestBitmap & REQUEST_REALIGNMENT_DONE_PENDING) {
// unlikely to occur: we have not yet received a done()
// event after sending out a realignment frame
+ dbg_serial("BeaconTransmitP", "Realignment pending (request: %lu) !\n", (uint32_t) m_requestBitmap);
post grantedTask(); // spin
return;
- }
- if (m_requests & REQUEST_UPDATE_SF){
- m_requests &= ~REQUEST_UPDATE_SF;
+ } else if (m_requestBitmap & REQUEST_UPDATE_SF) {
+ dbg_serial("BeaconTransmitP","Putting new superframe spec into operation\n");
+ m_requestBitmap &= ~REQUEST_UPDATE_SF;
continueStartRequest();
- call Debug.log(DEBUG_LEVEL_INFO, 2, 0, 0, 0);
}
if (call RadioOff.isOff())
prepareNextBeaconTransmission();
else
- call RadioOff.off();
+ ASSERT(call RadioOff.off() == SUCCESS); // will continue in prepareNextBeaconTransmission()
}
async event void TokenTransferred.transferred()
{
- if (call IsTokenRequested.getNow()){
- // some other component needs the token - we give it up for now,
- // but make another request to get it back later
+ if (call IsTokenRequested.getNow()) {
+ // some other component needs the token - we give it up for now,
+ // but before make another request to get it back afterwards
+ dbg_serial("BeaconTransmitP", "Token is requested, releasing it now.\n");
call Token.request();
call Token.release();
} else
void prepareNextBeaconTransmission()
{
- if (m_txState == S_TX_LOCKED){
+ if (m_txState == S_TX_LOCKED) {
// have not had time to finish processing the last sent beacon
+ dbg_serial("BeaconTransmitP", "Token was returned too fast!\n");
post grantedTask();
- call Debug.log(DEBUG_LEVEL_IMPORTANT, 3, 0, 0, 0);
- return;
- } else if (m_beaconOrder == 15){
+ } else if (m_beaconOrder == 15) {
+ // we're not sending any beacons!?
+ dbg_serial("BeaconTransmitP", "Stop sending beacons.\n");
call Token.release();
} else {
+ // get ready for next beacon transmission
atomic {
+ uint32_t delay = IEEE154_RADIO_TX_DELAY;
m_txState = S_TX_WAITING;
- if (m_txOneBeaconImmediately){
- signal BeaconTxAlarm.fired();
+ if (m_txOneBeaconImmediately) {
+ // transmit the beacon now
+ dbg_serial("BeaconTransmitP", "Sending a beacon immediately.\n");
+ signal BeaconSendAlarm.fired();
return;
- } else if (m_startTime != 0){
- // a new sf spec was put into operation, with a user-defined StartTime
+ } else if (m_startTime != 0) {
+ // a new sf spec was put into operation, with a user-defined StartTime
// here m_lastBeaconTxTime is actually the last time a beacon was received
+
+ dbg_serial("BeaconTransmitP", "First beacon to be sent at %lu.\n", m_startTime);
m_dt = m_startTime;
m_startTime = 0;
- } else if (m_previousBeaconInterval != 0){
- // a new sf spec was put into operation, after a realignment frame was
+ } else if (m_previousBeaconInterval != 0) {
+ // a new sf spec was put into operation, after a realignment frame
// broadcast; the next beacon time should still be calculated using the
// old BI (one last time)
+
+ dbg_serial("BeaconTransmitP", "Sending beacon after realignment dt=%lu.\n", m_previousBeaconInterval);
m_dt = m_previousBeaconInterval;
m_previousBeaconInterval = 0;
- if (m_requests & REQUEST_CONFIRM_PENDING){
+ if (m_requestBitmap & REQUEST_CONFIRM_PENDING) {
// only now the next higher layer is to be informed
- m_requests &= ~REQUEST_CONFIRM_PENDING;
+ m_requestBitmap &= ~REQUEST_CONFIRM_PENDING;
post signalStartConfirmSuccessTask();
}
- } else {
- // the usual case: next beacon tx time = last time + BI
- m_dt = m_beaconInterval;
}
- while (call TimeCalc.hasExpired(m_lastBeaconTxTime, m_dt)){ // skipped a beacon
- call Debug.log(DEBUG_LEVEL_IMPORTANT, 4, m_lastBeaconTxTime, m_dt, 0);
+
+ // The next beacon should be transmitted at time m_lastBeaconTxTime + m_dt, where m_dt
+ // is typically the beacon interval. First we check if we're still in time.
+ while (call TimeCalc.hasExpired(m_lastBeaconTxTime, m_dt)) {
+ // too late, we need to skip a beacon!
+ dbg_serial("BeaconTransmitP", "Skipping a beacon: scheduled=%lu, now=%lu.\n",
+ (uint32_t) m_lastBeaconTxTime + m_dt, (uint32_t) call BeaconSendAlarm.getNow());
m_dt += m_beaconInterval;
}
- if (m_dt < IEEE154_RADIO_TX_PREPARE_DELAY)
- m_dt = IEEE154_RADIO_TX_PREPARE_DELAY;
- // don't call BeaconTx.load just yet, otherwise the next
- // higher layer cannot modify the beacon payload anymore;
- // rather, set an alarm
- call BeaconTxAlarm.startAt(m_lastBeaconTxTime, m_dt - IEEE154_RADIO_TX_PREPARE_DELAY);
+ if (!call TimeCalc.hasExpired(m_lastBeaconTxTime - delay, m_dt)) {
+ // don't load the beacon frame in the radio just yet - rather set a timer and
+ // give the next higher layer the chance to modify the beacon payload
+ call BeaconSendAlarm.startAt(m_lastBeaconTxTime - delay, m_dt);
+ } else
+ signal BeaconSendAlarm.fired();
}
}
}
- async event void BeaconTxAlarm.fired()
+ task void signalStartConfirmSuccessTask()
{
- atomic {
- switch (m_txState)
- {
- case S_TX_WAITING:
- m_txState = S_TX_LOCKED;
- if (call IsBroadcastReady.getNow())
- m_beaconFrame.header->mhr[MHR_INDEX_FC1] |= FC1_FRAME_PENDING;
- else
- m_beaconFrame.header->mhr[MHR_INDEX_FC1] &= ~FC1_FRAME_PENDING;
- m_beaconFrame.header->mhr[MHR_INDEX_SEQNO] = m_bsn; // update beacon seqno
- call Debug.log(DEBUG_LEVEL_INFO, 5, 0, m_lastBeaconTxTime, 0);
- call BeaconTx.load(&m_beaconFrame);
- break;
- case S_TX_LOCKED:
- call Debug.log(DEBUG_LEVEL_INFO, 6, m_lastBeaconTxTime, m_dt, 0);
- call BeaconTx.transmit(&m_lastBeaconTxRefTime, m_dt);
- break;
- }
- }
+ signal MLME_START.confirm(SUCCESS);
}
- async event void BeaconTx.loadDone()
+ async event void BeaconSendAlarm.fired()
{
- atomic {
- call Debug.log(DEBUG_LEVEL_INFO, 7, 0, m_lastBeaconTxTime, 0);
- if (m_txOneBeaconImmediately){
- m_txOneBeaconImmediately = FALSE;
- call BeaconTx.transmit(NULL, 0); // now!
- } else
- call BeaconTxAlarm.startAt(m_lastBeaconTxTime, m_dt - IEEE154_RADIO_TX_SEND_DELAY);
+ // start/schedule beacon transmission
+ ieee154_timestamp_t *timestamp = &m_lastBeaconTxRefTime;
+ m_txState = S_TX_LOCKED;
+
+ if (call IsBroadcastReady.getNow())
+ m_beaconFrame.header->mhr[MHR_INDEX_FC1] |= FC1_FRAME_PENDING;
+ else
+ m_beaconFrame.header->mhr[MHR_INDEX_FC1] &= ~FC1_FRAME_PENDING;
+
+ m_beaconFrame.header->mhr[MHR_INDEX_SEQNO] = m_bsn; // update beacon seqno
+ if (m_txOneBeaconImmediately) {
+ m_txOneBeaconImmediately = FALSE;
+ timestamp = NULL;
}
+ call BeaconTx.transmit(&m_beaconFrame, timestamp, m_dt);
+ dbg_serial("BeaconTransmitP","Beacon Tx scheduled for %lu.\n", (uint32_t) (*timestamp + m_dt));
}
- async event void BeaconTx.transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime)
+
+ async event void BeaconTx.transmitDone(ieee154_txframe_t *frame, const ieee154_timestamp_t *timestamp, error_t result)
{
- // Coord CAP has just started...
+ // The beacon frame was transmitted, i.e. the CAP has just started
+ // update the state then pass the token on to the next component
+
uint8_t gtsFieldLength;
- // Sec. 7.5.1.1: "start of slot 0 is defined as the point at which
- // the first symbol of the beacon PPDU is transmitted"
- call Debug.log(DEBUG_LEVEL_INFO, 8, frame->metadata->timestamp, m_lastBeaconTxTime, m_dt);
- m_lastBeaconTxTime = frame->metadata->timestamp;
- memcpy(&m_lastBeaconTxRefTime, txTime, sizeof(ieee154_reftime_t));
+
+ ASSERT(result == SUCCESS); // must succeed, we're sending without CCA or ACK request
+ if (timestamp != NULL) {
+ m_lastBeaconTxTime = frame->metadata->timestamp;
+ memcpy(&m_lastBeaconTxRefTime, timestamp, sizeof(ieee154_timestamp_t));
+ m_dt = m_beaconInterval; // transmit the next beacon at m_lastBeaconTxTime + m_dt
+ dbg_serial("BeaconTransmitP", "Beacon Tx success at %lu\n", (uint32_t) m_lastBeaconTxTime);
+ } else {
+ // Timestamp is invalid; this is bad. We need the beacon timestamp for the
+ // slotted CSMA-CA, because it defines slot reference time. We can't use this superframe
+ // TODO: check if this was the initial beacon (then m_lastBeaconTxRefTime is invalid)
+ dbg_serial("BeaconTransmitP", "Invalid timestamp!\n");
+ m_dt += m_beaconInterval;
+ call Token.request();
+ call Token.release();
+ return;
+ }
+
+ // update superframe-related variables
m_numGtsSlots = (frame->payload[2] & 0x07);
gtsFieldLength = 1 + ((m_numGtsSlots > 0) ? 1 + m_numGtsSlots * 3: 0);
- m_finalCAPSlot = (frame->payload[1] & 0x0F);
+ m_numCapSlots = (frame->payload[1] & 0x0F) + 1;
m_sfSlotDuration = (((uint32_t) 1) << ((frame->payload[0] & 0xF0) >> 4)) * IEEE154_aBaseSlotDuration;
+
if (frame->header->mhr[0] & FC1_FRAME_PENDING)
m_framePendingBit = TRUE;
else
m_framePendingBit = FALSE;
memcpy(m_gtsField, &frame->payload[2], gtsFieldLength);
- if (frame->payload[1] & 0x10){
- // BLE is active; calculate the time offset from slot0
- m_BLELen = IEEE154_SHR_DURATION +
+ if (frame->payload[1] & 0x10) {
+ // BLE is active; calculate the time offset from slot 0
+ m_battLifeExtDuration = IEEE154_SHR_DURATION +
(frame->headerLen + frame->payloadLen + 2) * IEEE154_SYMBOLS_PER_OCTET;
if (frame->headerLen + frame->payloadLen + 2 > IEEE154_aMaxSIFSFrameSize)
- m_BLELen += IEEE154_MIN_LIFS_PERIOD;
+ m_battLifeExtDuration += IEEE154_MIN_LIFS_PERIOD;
else
- m_BLELen += IEEE154_MIN_SIFS_PERIOD;
- m_BLELen = m_BLELen + m_battLifeExtPeriods * 20;
+ m_battLifeExtDuration += IEEE154_MIN_SIFS_PERIOD;
+ m_battLifeExtDuration = m_battLifeExtDuration + m_battLifeExtPeriods * 20;
} else
- m_BLELen = 0;
- call TokenToBroadcast.transfer(); // borrow Token to Broadcast/CAP/CFP module, we'll get it back afterwards
+ m_battLifeExtDuration = 0;
+ call TokenToBroadcast.transfer();
post txDoneTask();
}
call SetMacBeaconTxTime.set(m_lastBeaconTxTime); // start of slot0, ie. first preamble byte of beacon
call BeaconPayloadUpdateTimer.startOneShotAt(m_lastBeaconTxTime,
(m_beaconInterval>BEACON_PAYLOAD_UPDATE_INTERVAL) ? (m_beaconInterval - BEACON_PAYLOAD_UPDATE_INTERVAL): 0);
- if (m_requests & REQUEST_CONFIRM_PENDING){
- m_requests &= ~REQUEST_CONFIRM_PENDING;
+ if (m_requestBitmap & REQUEST_CONFIRM_PENDING) {
+ m_requestBitmap &= ~REQUEST_CONFIRM_PENDING;
signal MLME_START.confirm(IEEE154_SUCCESS);
}
m_txState = S_TX_IDLE;
signal IEEE154TxBeaconPayload.beaconTransmitted();
- call Debug.flush();
+ dbg_serial_flush();
}
-/* ----------------------- Beacon Payload ----------------------- */
-/*
- * All access to the payload fields in the beacon happen
- * through a set of temporary variables/flags, and just before
- * the frame is loaded into the radio these changes are
- * propagated into the actual payload portion of the beacon frame.
- */
+ /* ----------------------- Beacon Payload ----------------------- */
+ /*
+ * All access to the payload fields in the beacon happen
+ * through a set of temporary variables/flags, and just before
+ * the frame is loaded into the radio these changes are
+ * written into the actual payload portion of the beacon frame.
+ */
command error_t IEEE154TxBeaconPayload.setBeaconPayload(void *beaconPayload, uint8_t length)
{
// in this order the MAC payload is updated:
// (1) pending addresses
// (2) GTS spec
- // (3) sf spec
+ // (3) SF spec
// (4) beacon payload (if there's enough time)
uint8_t len=0, *beaconSpecs = &m_payload[IEEE154_aMaxBeaconOverhead]; // going backwards
- uint8_t beaconPayloadUpdated = 0, numGtsSlots = 15 - m_finalCAPSlot;
+ uint8_t beaconPayloadUpdated = 0, numGtsSlots = m_numGtsSlots;
atomic {
if (m_txState == S_TX_LOCKED)
{
- call Debug.log(DEBUG_LEVEL_IMPORTANT, 10, 0, 0, m_txState);
+ dbg_serial("BeaconTransmitP", "BeaconPayloadUpdateTimer fired too late!\n");
return; // too late !
}
- if (m_payloadState & MODIFIED_PENDING_ADDR_FIELD){
+
+ // (1) update pending addresses
+ if (m_payloadState & MODIFIED_PENDING_ADDR_FIELD) {
len = call PendingAddrWrite.getLength();
beaconSpecs -= len;
call PendingAddrWrite.write(beaconSpecs, len);
- if (len != m_pendingAddrLen){
+ if (len != m_pendingAddrLen) {
m_pendingAddrLen = len;
m_payloadState |= MODIFIED_SPECS_MASK; // need to rewrite specs before
}
} else
beaconSpecs -= m_pendingAddrLen;
- if (m_payloadState & MODIFIED_GTS_FIELD){
+
+ // (2) update GTS spec
+ if (m_payloadState & MODIFIED_GTS_FIELD) {
len = call GtsInfoWrite.getLength();
beaconSpecs -= len;
call GtsInfoWrite.write(beaconSpecs, len);
numGtsSlots = getNumGtsSlots(beaconSpecs);
- if (len != m_pendingGtsLen || ((15-numGtsSlots) != m_finalCAPSlot)){
+ if (len != m_pendingGtsLen || ((15-numGtsSlots) != m_numCapSlots-1)) {
m_pendingGtsLen = len;
m_payloadState |= MODIFIED_SPECS_MASK; // need to rewrite specs before
}
} else
beaconSpecs -= m_pendingGtsLen;
+
+ // (3) update SF spec
beaconSpecs -= 2; // sizeof SF Spec
- if (m_payloadState & MODIFIED_SF_SPEC){
- call SuperframeSpecWrite.write(beaconSpecs, 2);
- beaconSpecs[1] &= 0xF0; // clear FinalCAPSlot field
+ if (m_payloadState & MODIFIED_SF_SPEC) {
+ beaconSpecs[0] = m_beaconOrder | (m_superframeOrder << 4);
+ beaconSpecs[1] = 0;
+ if (call MLME_GET.macAssociationPermit())
+ beaconSpecs[1] |= SF_SPEC2_ASSOCIATION_PERMIT;
+ if (call MLME_GET.macPanCoordinator())
+ beaconSpecs[1] |= SF_SPEC2_PAN_COORD;
beaconSpecs[1] |= ((15-numGtsSlots) & 0x0F); // update FinalCAPSlot field
}
m_beaconFrame.payloadLen = (m_pendingAddrLen + m_pendingGtsLen + 2) + m_beaconPayloadLen;
m_beaconFrame.payload = beaconSpecs;
m_payloadState &= ~MODIFIED_SPECS_MASK; // clear flags
- } // end atomic (give BeaconTxAlarm.fired() the chance to execute)
+ } // end atomic (give BeaconSendAlarm.fired() the chance to execute)
+
signal IEEE154TxBeaconPayload.aboutToTransmit();
+
atomic {
+ // (4) try to update beacon payload
if (m_txState == S_TX_LOCKED)
{
- call Debug.log(DEBUG_LEVEL_INFO, 11, 0, 0, m_txState);
+ dbg_serial("BeaconTransmitP", "Not enough time for beacon payload update!\n");
return; // too late !
}
- if (m_payloadState & MODIFIED_BEACON_PAYLOAD){
+ if (m_payloadState & MODIFIED_BEACON_PAYLOAD) {
memcpy(&m_payload[IEEE154_aMaxBeaconOverhead + m_updateBeaconOffset],
m_updateBeaconPayload, m_updateBeaconLength);
beaconPayloadUpdated = (m_payloadState & MODIFIED_BEACON_PAYLOAD_MASK);
m_beaconFrame.payloadLen = (m_pendingAddrLen + m_pendingGtsLen + 2) + m_beaconPayloadLen;
m_payloadState &= ~MODIFIED_BEACON_PAYLOAD_MASK;
}
- if (beaconPayloadUpdated){
+ if (beaconPayloadUpdated) {
if ((beaconPayloadUpdated & MODIFIED_BEACON_PAYLOAD_NEW))
signal IEEE154TxBeaconPayload.setBeaconPayloadDone(m_updateBeaconPayload, m_updateBeaconLength);
else
}
}
-/* ----------------------- SuperframeSpec ----------------------- */
-
- command uint8_t SuperframeSpecWrite.write(uint8_t *superframeSpecField, uint8_t maxlen)
- {
- if (call SuperframeSpecWrite.getLength() > maxlen)
- return 0;
- superframeSpecField[0] = m_beaconOrder | (m_superframeOrder << 4);
- superframeSpecField[1] = m_finalCAPSlot;
- if (m_PANCoordinator)
- superframeSpecField[1] |= SF_SPEC2_PAN_COORD;
- if (call MLME_GET.macAssociationPermit())
- superframeSpecField[1] |= SF_SPEC2_ASSOCIATION_PERMIT;
- return 2;
- }
-
- command uint8_t SuperframeSpecWrite.getLength()
- {
- return 2;
- }
-
-/* ----------------------- Realignment ----------------------- */
-/* In beacon-enabled mode a realignment frame was broadcast in the CAP
- * immediately after the beacon was transmitted. In non-beacon-enabled mode a
- * realignment frame was sent using unslotted CSMA. In both cases, if the
- * transmission was successful, the superframe spec must be updated now.
- **/
+ /* ----------------------- Realignment ----------------------- */
+ /* In beaconenabled mode a realignment frame is broadcast in the CAP
+ * immediately after the beacon was transmitted. In non-beaconenabled mode a
+ * realignment frame is sent using unslotted CSMA. In both cases, if the
+ * transmission was successful, the superframe spec should be updated now.
+ **/
event void RealignmentBeaconEnabledTx.transmitDone(ieee154_txframe_t *frame, ieee154_status_t status)
{
void finishRealignment(ieee154_txframe_t *frame, ieee154_status_t status)
{
call GetSetRealignmentFrame.set(frame);
- if (status == IEEE154_SUCCESS){
+ if (status == IEEE154_SUCCESS) {
continueStartRequest();
- m_requests &= ~REQUEST_REALIGNMENT_DONE_PENDING; // unlock
+ m_requestBitmap &= ~REQUEST_REALIGNMENT_DONE_PENDING; // unlock
// signal confirm where we calculate the next beacon transmission time
} else {
- m_requests = 0;
+ m_requestBitmap = 0;
signal MLME_START.confirm(status);
}
}
-/* ----------------------- BeaconRequest ----------------------- */
+ /* ----------------------- BeaconRequest ----------------------- */
event message_t* BeaconRequestRx.received(message_t* frame)
{
- if (m_beaconOrder == 15){
+ if (m_beaconOrder == 15) {
// transmit the beacon frame using unslotted CSMA-CA
// TODO
}
return frame;
}
-/* ----------------------- Defaults, etc. ----------------------- */
+ /* ----------------------- SF Structure, etc. ----------------------- */
- task void signalStartConfirmSuccessTask()
- {
- signal MLME_START.confirm(SUCCESS);
+ async command uint32_t OutgoingSF.sfStartTime()
+ {
+ return m_lastBeaconTxTime;
}
- async command bool IsSendingBeacons.getNow()
+ async command uint16_t OutgoingSF.sfSlotDuration()
{
- return (m_beaconOrder < 15) || ((m_requests & REQUEST_CONFIRM_PENDING) && m_updateBeaconOrder < 15);
+ return m_sfSlotDuration;
}
- async command uint32_t BeaconInterval.getNow() { return m_beaconInterval; }
- async command uint32_t CapStart.getNow() { return m_lastBeaconTxTime; }
- async command ieee154_reftime_t* CapStartRefTime.getNow() { return &m_lastBeaconTxRefTime; }
- async command uint32_t CapLen.getNow() { return call SfSlotDuration.getNow() * (call FinalCapSlot.getNow() + 1);}
- async command uint32_t CapEnd.getNow()
+ async command uint8_t OutgoingSF.numCapSlots()
{
- return call CapStart.getNow() + call CapLen.getNow();
+ return m_numCapSlots;
}
- async command uint32_t CfpEnd.getNow()
+
+ async command uint8_t OutgoingSF.numGtsSlots()
{
- return call CapStart.getNow() + call SfSlotDuration.getNow() * IEEE154_aNumSuperframeSlots;
+ return m_numGtsSlots;
}
- async command uint32_t CfpLen.getNow()
+
+ async command uint16_t OutgoingSF.battLifeExtDuration()
{
- return call SfSlotDuration.getNow() * (15 - call FinalCapSlot.getNow());
+ return m_battLifeExtDuration;
}
- async command bool IsBLEActive.getNow(){ return m_BLELen>0;}
- async command uint16_t BLELen.getNow(){ return m_BLELen;}
- async command bool BeaconFramePendingBit.getNow(){ return m_framePendingBit;}
-
- async command uint8_t* GtsField.getNow() { return m_gtsField; }
- async command uint32_t SfSlotDuration.getNow() { return m_sfSlotDuration; }
- async command uint8_t FinalCapSlot.getNow() { return m_finalCAPSlot; }
- async command uint8_t NumGtsSlots.getNow() { return m_numGtsSlots; }
- async event void BeaconTx.transmitUnslottedCsmaCaDone(ieee154_txframe_t *frame,
- bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result){}
- async event void BeaconTx.transmitSlottedCsmaCaDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime,
- bool ackPendingFlag, uint16_t remainingBackoff, ieee154_csma_t *csmaParams, error_t result){}
+ async command const uint8_t* OutgoingSF.gtsFields()
+ {
+ return m_gtsField;
+ }
- default event void MLME_START.confirm (
- ieee154_status_t status
- ){}
+ async command uint16_t OutgoingSF.guardTime()
+ {
+ return IEEE154_MAX_BEACON_JITTER(m_beaconOrder) + IEEE154_RADIO_TX_DELAY;
+ }
- default event void IEEE154TxBeaconPayload.setBeaconPayloadDone(void *beaconPayload, uint8_t length){}
+ async command const ieee154_timestamp_t* OutgoingSF.sfStartTimeRef()
+ {
+ return &m_lastBeaconTxRefTime;
+ }
- default event void IEEE154TxBeaconPayload.modifyBeaconPayloadDone(uint8_t offset, void *buffer, uint8_t bufferLength){}
+ async command bool OutgoingSF.isBroadcastPending()
+ {
+ return m_framePendingBit;
+ }
- default event void IEEE154TxBeaconPayload.aboutToTransmit(){}
+ async command bool IsSendingBeacons.getNow()
+ {
+ return (m_beaconOrder < 15) || ((m_requestBitmap & REQUEST_CONFIRM_PENDING) && m_updateBeaconOrder < 15);
+ }
- default event void IEEE154TxBeaconPayload.beaconTransmitted(){}
+ default event void MLME_START.confirm(ieee154_status_t status) {}
+ default event void IEEE154TxBeaconPayload.setBeaconPayloadDone(void *beaconPayload, uint8_t length) {}
+ default event void IEEE154TxBeaconPayload.modifyBeaconPayloadDone(uint8_t offset, void *buffer, uint8_t bufferLength) {}
+ default event void IEEE154TxBeaconPayload.aboutToTransmit() {}
+ default event void IEEE154TxBeaconPayload.beaconTransmitted() {}
}
interface FrameTxNow as CapTransmitNow;
interface ResourceTransfer as TokenToCap;
interface ResourceTransferred as TokenTransferred;
- interface GetNow<bool> as BeaconFramePendingBit;
+ interface SuperframeStructure as OutgoingSF;
interface Leds;
}
}
command ieee154_status_t RealignmentTx.transmit(ieee154_txframe_t *frame)
{
atomic {
- if (!m_realignmentFrame){
+ if (!m_realignmentFrame) {
m_realignmentFrame = frame;
return IEEE154_SUCCESS;
} else
async event void TokenTransferred.transferred()
{
// CAP has started - are there any broadcast frames to be transmitted?
- if (call BeaconFramePendingBit.getNow()){
+ if (call OutgoingSF.isBroadcastPending()) {
ieee154_txframe_t *broadcastFrame = m_realignmentFrame;
if (broadcastFrame == NULL)
broadcastFrame = m_queueHead;
- if (broadcastFrame){
- m_lock = TRUE;
- call CapTransmitNow.transmitNow(broadcastFrame);
- } else
- call Leds.led0On(); // internal error!
+ ASSERT(broadcastFrame != NULL);
+ m_lock = TRUE;
+ call CapTransmitNow.transmitNow(broadcastFrame);
}
call TokenToCap.transfer();
}
{
if (!m_lock)
return;
- if (m_transmittedFrame == m_realignmentFrame){
+ if (m_transmittedFrame == m_realignmentFrame) {
m_realignmentFrame = NULL;
signal RealignmentTx.transmitDone(m_transmittedFrame, m_status);
- } else if (m_transmittedFrame == m_queueHead){
+ } else if (m_transmittedFrame == m_queueHead) {
call Queue.dequeue();
m_queueHead = call Queue.head();
signal BroadcastDataFrame.transmitDone(m_transmittedFrame, m_status);
ORPHAN_RESPONSE,
BEACON_REALIGNMENT,
};
+
uint8_t m_payload[9];
bool m_busy = FALSE;
void destroyRealignmentFrame(ieee154_txframe_t *frame);
call Frame.getSrcAddr(frame, &srcAddress) == SUCCESS)
signal MLME_ORPHAN.indication (
srcAddress.extendedAddress,
- NULL // security
- );
+ NULL);
return frame;
}
uint64_t OrphanAddress,
uint16_t ShortAddress,
bool AssociatedMember,
- ieee154_security_t *security
- )
+ ieee154_security_t *security)
{
ieee154_txframe_t *txFrame;
ieee154_status_t txStatus;
txFrame->payload[5] = call MLME_GET.phyCurrentChannel();
*((nxle_uint16_t*) &txFrame->payload[6]) = ShortAddress;
txFrame->payloadLen = 8;
- if ((txStatus = call CoordRealignmentTx.transmit(txFrame)) != IEEE154_SUCCESS){
+ if ((txStatus = call CoordRealignmentTx.transmit(txFrame)) != IEEE154_SUCCESS) {
m_busy = FALSE;
destroyRealignmentFrame(txFrame);
}
uint8_t dstAddrMode;
ieee154_address_t srcAddress;
- if ((txFrame = call TxFramePool.get()) != NULL){
- if ((txControl = call TxControlPool.get()) == NULL){
+ if ((txFrame = call TxFramePool.get()) != NULL) {
+ if ((txControl = call TxControlPool.get()) == NULL) {
call TxFramePool.put(txFrame);
txFrame = NULL;
} else {
txFrame->payload = m_payload;
txFrame->header->mhr[MHR_INDEX_FC1] = FC1_FRAMETYPE_CMD;
txFrame->header->mhr[MHR_INDEX_FC2] = FC2_SRC_MODE_EXTENDED;
- if (type == ORPHAN_RESPONSE){
+ if (type == ORPHAN_RESPONSE) {
txFrame->header->mhr[MHR_INDEX_FC2] |= FC2_DEST_MODE_EXTENDED;
dstAddrMode = ADDR_MODE_EXTENDED_ADDRESS;
txFrame->header->mhr[MHR_INDEX_FC1] |= FC1_ACK_REQUEST;
uint8_t *mhr = MHR(txFrame);
ieee154_address_t dstAddr;
ieee154_address_t srcAddr;
- if (m_busy){
+
+ if (m_busy) {
call FrameUtility.convertToNative(&dstAddr.extendedAddress, &mhr[MHR_INDEX_ADDRESS+2]);
call FrameUtility.convertToNative(&srcAddr.extendedAddress, &mhr[MHR_INDEX_ADDRESS+2+8+2]);
signal MLME_COMM_STATUS.indication (
ADDR_MODE_EXTENDED_ADDRESS, // DstAddrMode
dstAddr,
status,
- NULL //security
- );
+ NULL);
call TxControlPool.put((ieee154_txcontrol_t*) ((uint8_t*) txFrame->header - offsetof(ieee154_txcontrol_t, header)));
call TxFramePool.put(txFrame);
m_busy = FALSE;
uint8_t DstAddrMode,
ieee154_address_t DstAddr,
ieee154_status_t status,
- ieee154_security_t *security
- ){}
+ ieee154_security_t *security) {}
default event void MLME_ORPHAN.indication (
uint64_t OrphanAddress,
- ieee154_security_t *security
- ){}
+ ieee154_security_t *security) {}
}
message_t *frame,
uint8_t payloadLen,
uint8_t msduHandle,
- uint8_t txOptions
- )
+ uint8_t txOptions)
{
uint8_t srcAddrMode = call Frame.getSrcAddrMode(frame);
uint8_t dstAddrMode = call Frame.getDstAddrMode(frame);
// coordinator address in the PIB, if they match the frame is
// sent in the incoming sf otherwise in the outgoing sf
call Frame.getDstAddr(frame, &dstAddr);
- if (dstAddrMode == ADDR_MODE_SHORT_ADDRESS){
+ if (dstAddrMode == ADDR_MODE_SHORT_ADDRESS) {
if (dstAddr.shortAddress == call MLME_GET.macCoordShortAddress())
sfType = INCOMING_SUPERFRAME;
else
sfType = OUTGOING_SUPERFRAME;
- } else if (dstAddrMode == ADDR_MODE_EXTENDED_ADDRESS){
+ } else if (dstAddrMode == ADDR_MODE_EXTENDED_ADDRESS) {
if (dstAddr.extendedAddress == call MLME_GET.macCoordExtendedAddress())
sfType = INCOMING_SUPERFRAME;
else
sfType = INCOMING_SUPERFRAME;
// GTS?
- if (txOptions & TX_OPTIONS_GTS){
+ if (txOptions & TX_OPTIONS_GTS) {
if (sfType == INCOMING_SUPERFRAME)
txStatus = call DeviceCfpTx.transmit(txFrame);
else
// indirect transmission?
} else if ((txOptions & TX_OPTIONS_INDIRECT) &&
call IsSendingBeacons.getNow() &&
- (dstAddrMode >= ADDR_MODE_SHORT_ADDRESS)){
- if (dstAddrMode == ADDR_MODE_SHORT_ADDRESS && dstAddr.shortAddress == 0xFFFF){
+ (dstAddrMode >= ADDR_MODE_SHORT_ADDRESS)) {
+ if (dstAddrMode == ADDR_MODE_SHORT_ADDRESS && dstAddr.shortAddress == 0xFFFF) {
mhr[MHR_INDEX_FC1] &= ~FC1_ACK_REQUEST;
txStatus = call BroadcastTx.transmit(txFrame);
} else
else
txStatus = call CoordCapTx.transmit(txFrame);
- if (txStatus != IEEE154_SUCCESS){
+ if (txStatus != IEEE154_SUCCESS) {
call TxFramePool.put(txFrame);
}
}
}
command ieee154_status_t MCPS_PURGE.request (
- uint8_t msduHandle
- )
+ uint8_t msduHandle)
{
if (call PurgeDirect.purge(msduHandle) == IEEE154_SUCCESS ||
call PurgeIndirect.purge(msduHandle) == IEEE154_SUCCESS ||
message_t* dataReceived(message_t* frame)
{
- return signal MCPS_DATA.indication( frame );
+ return signal MCPS_DATA.indication(frame);
}
void finishTxTransaction(ieee154_txframe_t *txFrame, ieee154_status_t status)
uint8_t handle = txFrame->handle;
uint32_t txTime = txFrame->metadata->timestamp;
message_t *msg = (message_t*) ((uint8_t*) txFrame->header - offsetof(message_t, header));
+
call TxFramePool.put(txFrame);
signal MCPS_DATA.confirm(msg, handle, status, txTime);
}
message_t *msg,
uint8_t msduHandle,
ieee154_status_t status,
- uint32_t Timestamp
- ){}
+ uint32_t Timestamp) {}
- default event message_t* MCPS_DATA.indication ( message_t* frame ){ return frame; }
- default command ieee154_status_t DeviceCfpTx.transmit(ieee154_txframe_t *data){return IEEE154_INVALID_GTS;}
- default command ieee154_status_t CoordCfpTx.transmit(ieee154_txframe_t *data){return IEEE154_INVALID_GTS;}
+ default event message_t* MCPS_DATA.indication(message_t* frame) { return frame; }
+ default command ieee154_status_t DeviceCfpTx.transmit(ieee154_txframe_t *data) {return IEEE154_INVALID_GTS;}
+ default command ieee154_status_t CoordCfpTx.transmit(ieee154_txframe_t *data) {return IEEE154_INVALID_GTS;}
}
--- /dev/null
+/*
+ * Copyright (c) 2008, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author: Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+configuration DebugC {
+}
+implementation {
+ components DebugP, LedsC;
+ DebugP.Leds -> LedsC;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2008, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author: Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+#include "printf.h"
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+module DebugP {
+ uses interface Leds;
+}
+implementation {
+
+ enum {
+ MAX_LEN_FUNNAME = 50,
+ MAX_LEN_FILENAME = 50,
+ NUM_LIST_ENTRIES = 20,
+ };
+
+ typedef struct {
+ const char *filename;
+ uint16_t line;
+ const char *format;
+ uint32_t param[2];
+ } debug_list_entry_t;
+
+ norace debug_list_entry_t m_list[NUM_LIST_ENTRIES];
+ norace uint8_t m_head;
+ norace uint8_t m_tail;
+ norace bool m_overflow;
+
+
+ uint16_t m_assertCounter;
+ norace uint16_t m_assertLine;
+ norace char m_assertFilename[MAX_LEN_FILENAME];
+ norace char m_assertFunction[MAX_LEN_FUNNAME];
+
+ task void assertFailTask()
+ {
+ if (m_assertCounter == 0) {
+ printf("Assert failed: File: %s, line: %d, function: %s.\n", m_assertFilename, m_assertLine, m_assertFunction);
+ printfflush();
+ }
+ if (m_assertCounter++ < 3000) {
+ call Leds.led0On();
+ call Leds.led1On();
+ call Leds.led2On();
+ } else {
+ call Leds.led0Off();
+ call Leds.led1Off();
+ call Leds.led2Off();
+ }
+ if (m_assertCounter > 6000)
+ m_assertCounter = 0;
+ post assertFailTask();
+ }
+
+ void tkn154_assert(bool val, const char *filename, uint16_t line, const char *func) @C() @spontaneous()
+ {
+ if (!val) {
+ if (m_assertLine == 0) {
+ // only catch the first failure, output it periodically
+ m_assertLine = line;
+ strncpy(m_assertFilename, filename, MAX_LEN_FILENAME);
+ strncpy(m_assertFunction, func, MAX_LEN_FILENAME);
+ post assertFailTask();
+ }
+ }
+ }
+
+ void tkn154_dbg_serial(const char *filename, uint16_t line, ...) @C() @spontaneous()
+ {
+ // This function must be fast: we just copy the strings and
+ // output them later in the flush-function
+
+ if ((m_head + 1) % NUM_LIST_ENTRIES != m_tail) {
+ va_list argp;
+
+ m_list[m_head].filename = filename;
+ m_list[m_head].line = line;
+ va_start(argp, line);
+ m_list[m_head].format = va_arg(argp, char*);
+ m_list[m_head].param[0] = va_arg(argp, uint32_t);
+ m_list[m_head].param[1] = va_arg(argp, uint32_t);
+ va_end(argp);
+ m_head = (m_head + 1) % NUM_LIST_ENTRIES;
+ } else
+ m_overflow = TRUE;
+ }
+
+ task void serialFlushTask()
+ {
+ if (m_overflow)
+ printf("SERIAL OVERFLOW!\n");
+ if (m_head != m_tail) {
+ printf("%s:%d:", m_list[m_tail].filename, m_list[m_tail].line);
+ printf(m_list[m_tail].format, m_list[m_tail].param[0], m_list[m_tail].param[1]);
+ atomic {
+ if (++m_tail >= NUM_LIST_ENTRIES)
+ m_tail = 0;
+ }
+ }
+ if (m_head != m_tail)
+ post serialFlushTask();
+ printfflush();
+ }
+
+ void tkn154_dbg_serial_flush() @C() @spontaneous()
+ {
+ post serialFlushTask();
+ }
+}
interface FrameUtility;
interface IEEE154Frame as Frame;
interface Get<uint64_t> as LocalExtendedAddress;
- interface Ieee802154Debug as Debug;
}
}
implementation
return SUCCESS;
}
-/* ------------------- MLME_DISASSOCIATE (initiating) ------------------- */
+ /* ------------------- MLME_DISASSOCIATE (initiating) ------------------- */
command ieee154_status_t MLME_DISASSOCIATE.request (
uint8_t DeviceAddrMode,
ieee154_address_t DeviceAddress,
ieee154_disassociation_reason_t DisassociateReason,
bool TxIndirect,
- ieee154_security_t *security
- )
+ ieee154_security_t *security)
{
ieee154_status_t status = IEEE154_SUCCESS;
ieee154_txframe_t *txFrame=0;
status = IEEE154_INVALID_PARAMETER;
else if (m_disAssociationOngoing || !(txFrame = call TxFramePool.get()))
status = IEEE154_TRANSACTION_OVERFLOW;
- else if (!(txControl = call TxControlPool.get())){
+ else if (!(txControl = call TxControlPool.get())) {
call TxFramePool.put(txFrame);
status = IEEE154_TRANSACTION_OVERFLOW;
}
- if (status == IEEE154_SUCCESS){
+ if (status == IEEE154_SUCCESS) {
txFrame->header = &txControl->header;
txFrame->metadata = &txControl->metadata;
srcAddress.extendedAddress = call LocalExtendedAddress.get();
if ((DeviceAddrMode == ADDR_MODE_SHORT_ADDRESS &&
DeviceAddress.shortAddress == call MLME_GET.macCoordShortAddress()) ||
(DeviceAddrMode == ADDR_MODE_EXTENDED_ADDRESS &&
- DeviceAddress.extendedAddress == call MLME_GET.macCoordExtendedAddress())){
+ DeviceAddress.extendedAddress == call MLME_GET.macCoordExtendedAddress())) {
status = call DisassociationToCoord.transmit(txFrame);
} else if (TxIndirect) {
status = call DisassociationIndirectTx.transmit(txFrame);
} else {
status = call DisassociationDirectTx.transmit(txFrame);
}
- if (status != IEEE154_SUCCESS){
+ if (status != IEEE154_SUCCESS) {
m_disAssociationOngoing = FALSE;
call TxFramePool.put(txFrame);
call TxControlPool.put(txControl);
}
}
- call Debug.log(DEBUG_LEVEL_INFO, DISSASSOCIATE_REQUEST, status, 0, 0);
+ dbg_serial("DisassociateP", "MLME_DISASSOCIATE.request -> result: %lu\n", (uint32_t) status);
return status;
}
call FrameUtility.convertToNative(&DeviceAddress.extendedAddress, &mhr[srcAddrOffset]);
call TxControlPool.put((ieee154_txcontrol_t*) ((uint8_t*) data->header - offsetof(ieee154_txcontrol_t, header)));
call TxFramePool.put(data);
- call Debug.log(DEBUG_LEVEL_INFO, DISSASSOCIATE_TXDONE, status, 2, 0);
+ dbg_serial("DisassociateP", "transmitDone() -> result: %lu\n", (uint32_t) status);
m_disAssociationOngoing = FALSE;
signal MLME_DISASSOCIATE.confirm(status, DeviceAddrMode, DevicePANID, DeviceAddress);
}
uint16_t DevicePANID = *((nxle_uint16_t*) (&(mhr[MHR_INDEX_ADDRESS])));
ieee154_address_t DeviceAddress;
call FrameUtility.convertToNative(&DeviceAddress.extendedAddress, &mhr[dstAddrOffset]);
- call Debug.log(DEBUG_LEVEL_INFO, DISSASSOCIATE_TXDONE, status, 1, 0);
call TxControlPool.put((ieee154_txcontrol_t*) ((uint8_t*) data->header - offsetof(ieee154_txcontrol_t, header)));
call TxFramePool.put(data);
- call Debug.log(DEBUG_LEVEL_INFO, DISSASSOCIATE_TXDONE, status, 2, 0);
+ dbg_serial("DisassociateP", "transmitDone() -> result: %lu\n", (uint32_t) status);
m_disAssociationOngoing = FALSE;
signal MLME_DISASSOCIATE.confirm(status, DeviceAddrMode, DevicePANID, DeviceAddress);
}
-/* ------------------- MLME_DISASSOCIATE (receiving) ------------------- */
+ /* ------------------- MLME_DISASSOCIATE (receiving) ------------------- */
event message_t* DisassociationDirectRxFromCoord.received(message_t* frame)
{
{
// received a disassociation notification from the device
ieee154_address_t address;
- call Debug.log(DEBUG_LEVEL_INFO, DISSASSOCIATE_RX, 0, 0, 0);
if (call Frame.getSrcAddrMode(frame) == ADDR_MODE_EXTENDED_ADDRESS &&
call Frame.getSrcAddr(frame, &address) == SUCCESS)
signal MLME_DISASSOCIATE.indication(address.extendedAddress, frame->data[1], NULL);
+ dbg_serial("DisassociateP", "Received disassociation request from %lx\n", (uint32_t) address.shortAddress);
return frame;
}
-/* ------------------- Defaults ------------------- */
+ /* ------------------- Defaults ------------------- */
default event void MLME_DISASSOCIATE.indication (
uint64_t DeviceAddress,
ieee154_disassociation_reason_t DisassociateReason,
- ieee154_security_t *security
- ){}
+ ieee154_security_t *security) {}
+
default event void MLME_DISASSOCIATE.confirm (
ieee154_status_t status,
uint8_t DeviceAddrMode,
uint16_t DevicePANID,
- ieee154_address_t DeviceAddress
- ){}
+ ieee154_address_t DeviceAddress) {}
}
+++ /dev/null
-/*
- * Copyright (c) 2008, Technische Universitaet Berlin
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * - Neither the name of the Technische Universitaet Berlin nor the names
- * of its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * - Revision -------------------------------------------------------------
- * $Revision$
- * $Date$
- * @author Jan Hauer <hauer@tkn.tu-berlin.de>
- * ========================================================================
- */
-
-#include "TKN154_PHY.h"
-#include "TKN154_MAC.h"
-
-
-/**
- * This module is responsible for preparing the transmission/reception of DATA
- * and COMMAND frames in the contention access period (CAP, slotted CSMA-CA) or
- * in a nonbeacon-enabled PAN (unslotted CSMA-CA). It prepares the relevant
- * parameters of the CSMA-CA algorithm (NB, BE, etc.), but it does not implement
- * the CSMA-CA algorithm (the CSMA-CA algorithm is implemented in the radio
- * driver).
- *
- * In a beacon-enabled this module does slightly different things depending on
- * whether it is the CAP for an outgoing superframe (superframeDirection =
- * OUTGOING_SUPERFRAME), i.e. the CAP from the perspective of a coordinator
- * after it has transmitted its own beacon; or for an incoming superframe
- * (superframeDirection = INCOMING_SUPERFRAME), i.e. the CAP from the
- * perspective of a device after it has received a beacon from its coordinator.
- * For example, in the CAP a coordinator will usually listen for incoming
- * frames from the devices, and a device will usually switch the radio off
- * unless it has a frame to transmit. In nonbeacon-enabled PANs the
- * superframeDirection parameter is ignored.
- */
-
-generic module FrameDispatchP(uint8_t superframeDirection)
-{
- provides
- {
- interface Init as Reset;
- interface FrameTx as FrameTx;
- interface FrameRx as FrameRx[uint8_t frameType];
- interface FrameExtracted as FrameExtracted[uint8_t frameType];
- interface FrameTxNow as BroadcastTx;
- interface Notify<bool> as WasRxEnabled;
- interface Notify<bool> as FindBeacon;
- }
- uses
- {
- interface Alarm<TSymbolIEEE802154,uint32_t> as CapEndAlarm;
- interface Alarm<TSymbolIEEE802154,uint32_t> as BLEAlarm;
- interface Alarm<TSymbolIEEE802154,uint32_t> as IndirectTxWaitAlarm;
- interface Alarm<TSymbolIEEE802154,uint32_t> as BroadcastAlarm;
- interface Resource as Token;
- interface GetNow<bool> as IsTokenRequested;
- interface ResourceTransfer as TokenToCfp;
- interface ResourceTransferred as TokenTransferred;
- interface GetNow<uint32_t> as CapStart;
- interface GetNow<ieee154_reftime_t*> as CapStartRefTime;
- interface GetNow<uint32_t> as CapLen;
- interface GetNow<bool> as IsBLEActive;
- interface GetNow<uint16_t> as BLELen;
- interface GetNow<bool> as IsRxBroadcastPending;
- interface GetNow<bool> as IsRxEnableActive;
- interface Get<ieee154_txframe_t*> as GetIndirectTxFrame;
- interface Notify<bool> as RxEnableStateChange;
- interface GetNow<bool> as IsTrackingBeacons;
- interface FrameUtility;
- interface RadioTx;
- interface RadioRx;
- interface RadioOff;
- interface GetNow<bool> as IsBeaconEnabledPAN;
- interface MLME_GET;
- interface MLME_SET;
- interface Ieee802154Debug as Debug;
- interface TimeCalc;
- interface Leds;
- interface SetNow<ieee154_cap_frame_backup_t*> as FrameBackup;
- interface GetNow<ieee154_cap_frame_backup_t*> as FrameRestore;
- }
-}
-implementation
-{
- typedef enum {
- SWITCH_OFF,
- LOAD_TX,
- PREPARE_RX,
- DO_NOTHING,
- WAIT_FOR_TXDONE,
- } next_state_t;
-
- typedef enum {
- INDIRECT_TX_ALARM,
- BROADCAST_ALARM,
- NO_ALARM,
- } rx_alarm_t;
-
- enum {
- COORD_ROLE = (superframeDirection == OUTGOING_SUPERFRAME),
- DEVICE_ROLE = !COORD_ROLE,
- };
-
- norace bool m_lock;
- norace ieee154_txframe_t *m_currentFrame;
- norace ieee154_txframe_t *m_bcastFrame;
- norace ieee154_txframe_t *m_lastFrame;
-
- norace ieee154_csma_t m_csmaParams;
- norace bool m_resume;
- norace uint16_t m_remainingBackoff;
- norace ieee154_macMaxBE_t m_BE;
- norace ieee154_macMaxCSMABackoffs_t m_macMaxCSMABackoffs;
- norace ieee154_macMaxBE_t m_macMaxBE;
- norace bool m_slottedCsma;
- norace ieee154_macMaxFrameRetries_t m_macMaxFrameRetries;
- norace ieee154_status_t m_result;
- norace uint32_t m_transactionTime;
- norace bool m_indirectTxPending = FALSE;
- norace bool m_broadcastRxPending;
- norace ieee154_macMaxFrameTotalWaitTime_t m_macMaxFrameTotalWaitTime;
-
-
-#ifdef TKN154_SERIAL_DEBUG
-#define DEBUG_NEXT_BUFFER_SIZE 12
- norace uint8_t dbgHistory[DEBUG_NEXT_BUFFER_SIZE];
- norace uint8_t dbgHistoryIndex;
- void dbgHistoryReset(){dbgHistoryIndex=0; memset(dbgHistory, 0xFF, DEBUG_NEXT_BUFFER_SIZE);}
- void dbgHistoryAdd(uint8_t nextState)
- {
- dbgHistory[dbgHistoryIndex] = nextState;
- dbgHistoryIndex = (dbgHistoryIndex+1) % DEBUG_NEXT_BUFFER_SIZE;
- }
- void dbgHistoryFlush()
- {
- uint8_t i,k=dbgHistoryIndex;
- uint32_t s1=0xFFFFFFFF,s2=0xFFFFFFFF,s3=0xFFFFFFFF;
- for (i=0; i<4; i++){ s1 = s1 << 8; s1 |= dbgHistory[k]; k = (k+1) % DEBUG_NEXT_BUFFER_SIZE;}
- for (i=0; i<4; i++){ s2 = s2 << 8; s2 |= dbgHistory[k]; k = (k+1) % DEBUG_NEXT_BUFFER_SIZE;}
- for (i=0; i<4; i++){ s3 = s3 << 8; s3 |= dbgHistory[k]; k = (k+1) % DEBUG_NEXT_BUFFER_SIZE;}
- call Debug.log(DEBUG_LEVEL_INFO, 12, s1,s2,s3);
- }
-#else
- void dbgHistoryReset(){}
- void dbgHistoryAdd(uint8_t nextState){}
- void dbgHistoryFlush(){}
-#endif
-
- void stopAllAlarms();
- next_state_t tryReceive(rx_alarm_t alarmType);
- next_state_t tryTransmit();
- next_state_t trySwitchOff();
- void backupCurrentFrame();
- void restoreFrameFromBackup();
- void updateState();
- void setCurrentFrame(ieee154_txframe_t *frame);
- void signalTxBroadcastDone(ieee154_txframe_t *frame, ieee154_status_t error);
- void transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime,
- bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result);
- task void signalTxDoneTask();
- task void setupTxBroadcastTask();
- task void wasRxEnabledTask();
-
- command error_t Reset.init()
- {
- if (m_currentFrame)
- signal FrameTx.transmitDone(m_currentFrame, IEEE154_TRANSACTION_OVERFLOW);
- if (m_lastFrame)
- signal FrameTx.transmitDone(m_lastFrame, IEEE154_TRANSACTION_OVERFLOW);
- if (m_bcastFrame)
- signalTxBroadcastDone(m_bcastFrame, IEEE154_TRANSACTION_OVERFLOW);
- m_currentFrame = m_lastFrame = m_bcastFrame = NULL;
- stopAllAlarms();
- return SUCCESS;
- }
-
- async event void TokenTransferred.transferred()
- {
- // we got the token, i.e. CAP has just started
- uint32_t actualCapLen = call CapLen.getNow();
- dbgHistoryReset();
- if (!call IsBeaconEnabledPAN.getNow()){
- call Leds.led0On(); // internal error!
- call TokenToCfp.transfer();
- call Debug.log(DEBUG_LEVEL_IMPORTANT, 0, 0,0,0);
- } else if (DEVICE_ROLE && actualCapLen == 0){
- // very rare case:
- // this can only happen, if we're on a beacon-enabled PAN, not tracking beacons,
- // and searched but didn't find a beacon for aBaseSuperframeDuration*(2n+1) symbols
- // -> transmit current frame using unslotted CSMA-CA
- m_slottedCsma = FALSE;
- updateState();
- return;
- } else if (actualCapLen < IEEE154_ACTIVE_PERIOD_GUARD_TIME){
- call Debug.log(DEBUG_LEVEL_IMPORTANT, 1, superframeDirection, actualCapLen, IEEE154_ACTIVE_PERIOD_GUARD_TIME);
- call TokenToCfp.transfer();
- return;
- } else {
- actualCapLen -= IEEE154_ACTIVE_PERIOD_GUARD_TIME;
- if (DEVICE_ROLE)
- m_broadcastRxPending = call IsRxBroadcastPending.getNow();
- else {
- // COORD_ROLE
- if (m_bcastFrame != NULL) {
- // we have to transmit a broadcast frame immediately; this
- // (possibly) requires a backup of the previously active frame
- // and a reinitializing the CSMA parameters -> will do it
- // in task context and then continue
- m_lock = TRUE;
- post setupTxBroadcastTask();
- call Debug.log(DEBUG_LEVEL_INFO, 7, 0,0,0);
- }
- }
- call CapEndAlarm.startAt(call CapStart.getNow(), actualCapLen);
- if (call IsBLEActive.getNow())
- call BLEAlarm.startAt(call CapStart.getNow(), call BLELen.getNow());
- call Debug.log(DEBUG_LEVEL_INFO, 2, call CapStart.getNow(),
- actualCapLen, call CapStart.getNow()+ actualCapLen);
- }
- updateState();
- }
-
- command ieee154_status_t FrameTx.transmit(ieee154_txframe_t *frame)
- {
- //call Debug.log(DEBUG_LEVEL_INFO, 4, m_lock, call Token.isOwner(), m_currentFrame == NULL);
- if (m_currentFrame != NULL){
- call Debug.log(DEBUG_LEVEL_IMPORTANT, 5, 0,0,0);
- return IEEE154_TRANSACTION_OVERFLOW;
- } else {
- setCurrentFrame(frame);
- if (!call IsBeaconEnabledPAN.getNow()){
- call Token.request(); // prepare for unslotted CSMA-CA
- } else {
- // a beacon must be found before transmitting in a beacon-enabled PAN
- if (DEVICE_ROLE && !call IsTrackingBeacons.getNow()){
- signal FindBeacon.notify(TRUE);
- // we'll receive the Token at latest after aBaseSuperframeDuration*(2n+1) symbols;
- // if the beacon was not found, then we'll send the frame using unslotted CSMA-CA
- }
- updateState();
- }
- return IEEE154_SUCCESS;
- }
- }
-
- task void setupTxBroadcastTask()
- {
- ieee154_macDSN_t tmp;
- ieee154_txframe_t *oldFrame = m_currentFrame;
- if (COORD_ROLE){
- if (m_bcastFrame != NULL){
- // broadcasts should be transmitted *immediately* after the beacon,
- // which may interrupt a pending transmit operation from the previous
- // CAP; back up the last active frame configuration (may be none)
- // and restore it after the broadcast frame has been transmitted;
- // do this through interfaces and don't wire them for DEVICE_ROLE,
- // so we don't waste the RAM of devices
- backupCurrentFrame();
- setCurrentFrame(m_bcastFrame);
- if (oldFrame){
- // now the sequence number are out of order... swap them back
- tmp = m_bcastFrame->header->mhr[MHR_INDEX_SEQNO];
- m_bcastFrame->header->mhr[MHR_INDEX_SEQNO] =
- oldFrame->header->mhr[MHR_INDEX_SEQNO];
- oldFrame->header->mhr[MHR_INDEX_SEQNO] = tmp;
- }
- }
- }
- m_lock = FALSE;
- updateState();
- }
-
- void setCurrentFrame(ieee154_txframe_t *frame)
- {
- ieee154_macDSN_t dsn = call MLME_GET.macDSN();
- frame->header->mhr[MHR_INDEX_SEQNO] = dsn++;
- call MLME_SET.macDSN(dsn);
- m_csmaParams.NB = 0;
- m_csmaParams.macMaxCsmaBackoffs = m_macMaxCSMABackoffs = call MLME_GET.macMaxCSMABackoffs();
- m_csmaParams.macMaxBE = m_macMaxBE = call MLME_GET.macMaxBE();
- m_csmaParams.BE = call MLME_GET.macMinBE();
- if (call MLME_GET.macBattLifeExt() && m_csmaParams.BE > 2)
- m_csmaParams.BE = 2;
- m_BE = m_csmaParams.BE;
- if (COORD_ROLE && call GetIndirectTxFrame.get() == frame)
- m_macMaxFrameRetries = 0; // this is an indirect transmissions (never retransmit)
- else
- m_macMaxFrameRetries = call MLME_GET.macMaxFrameRetries();
- m_slottedCsma = call IsBeaconEnabledPAN.getNow();
- m_transactionTime = IEEE154_SHR_DURATION +
- (frame->headerLen + frame->payloadLen + 2) * IEEE154_SYMBOLS_PER_OCTET; // extra 2 for CRC
- if (frame->header->mhr[MHR_INDEX_FC1] & FC1_ACK_REQUEST)
- m_transactionTime += (IEEE154_aTurnaroundTime + IEEE154_aUnitBackoffPeriod +
- 11 * IEEE154_SYMBOLS_PER_OCTET); // 11 byte for the ACK PPDU
- //if (frame->headerLen + frame->payloadLen > IEEE154_aMaxSIFSFrameSize)
- // m_transactionTime += call MLME_GET.macMinLIFSPeriod();
- //else
- // m_transactionTime += call MLME_GET.macMinSIFSPeriod();
- m_macMaxFrameTotalWaitTime = call MLME_GET.macMaxFrameTotalWaitTime();
- m_currentFrame = frame;
- }
-
- void stopAllAlarms()
- {
- call CapEndAlarm.stop();
- if (DEVICE_ROLE){
- call IndirectTxWaitAlarm.stop();
- call BroadcastAlarm.stop();
- }
- call BLEAlarm.stop();
- }
-
- /**
- * The updateState() function is called whenever some event happened that
- * might require a state change; it implements a lock mechanism (m_lock) to
- * prevent race conditions. Whenever the lock is set a "done"-event (from a
- * RadioTx/RadioRx/RadioOff interface) is pending and will "soon" unset the
- * lock (and then updateState() will called again). The updateState()
- * function decides about the next state by checking a list of possible
- * current states ordered by priority, e.g. it first always checks whether
- * the CAP is still active. Calling this function more than necessary can do
- * no harm, but it SHOULD be called whenever an event happened that might
- * lead to a state change.
- */
-
- void updateState()
- {
- error_t result = SUCCESS;
- next_state_t next;
- atomic {
- // long atomics are bad... but in this block, once the
- // current state has been determined only one branch will
- // be taken (no loops, etc.)
- if (m_lock || !call Token.isOwner())
- return;
- m_lock = TRUE; // lock
-
- // Check 1: for beacon-enabled PANs, has the CAP finished?
- if (call IsBeaconEnabledPAN.getNow()
- && (COORD_ROLE || call IsTrackingBeacons.getNow()) // FALSE only if device could't find a beacon
- && (call TimeCalc.hasExpired(call CapStart.getNow(), call CapLen.getNow()-IEEE154_ACTIVE_PERIOD_GUARD_TIME) ||
- !call CapEndAlarm.isRunning())){
- if (call RadioOff.isOff()) {
- stopAllAlarms(); // may still fire, locked through isOwner()
- if (DEVICE_ROLE && m_indirectTxPending)
- signal IndirectTxWaitAlarm.fired();
- m_broadcastRxPending = FALSE;
- if (COORD_ROLE && m_bcastFrame){
- // didn't manage to transmit a broadcast
- restoreFrameFromBackup();
- signalTxBroadcastDone(m_bcastFrame, IEEE154_CHANNEL_ACCESS_FAILURE);
- m_bcastFrame = NULL;
- }
- m_lock = FALSE; // unlock
- call TokenToCfp.transfer();
- call Debug.log(DEBUG_LEVEL_INFO, 8, 0,0,0);
- dbgHistoryFlush();
- return;
- } else
- next = SWITCH_OFF;
- }
-
- // Check 2: should a broadcast frame be received/transmitted immediately
- // at the start of CAP?
- else if (DEVICE_ROLE && m_broadcastRxPending){
- // receive a broadcast from coordinator
- next = tryReceive(BROADCAST_ALARM);
- } else if (COORD_ROLE && m_bcastFrame){
- next = tryTransmit();
- }
-
- // Check 3: was an indirect transmission successfully started
- // and are we now waiting for a frame from the coordinator?
- else if (DEVICE_ROLE && m_indirectTxPending) {
- next = tryReceive(INDIRECT_TX_ALARM);
- }
-
- // Check 4: is some other operation (like MLME-SCAN or MLME-RESET) pending?
- else if (call IsTokenRequested.getNow() && call IsBeaconEnabledPAN.getNow()) {
- if (call RadioOff.isOff()) {
- stopAllAlarms(); // may still fire, but is locked through isOwner()
- // nothing more to do... just release the Token
- m_lock = FALSE; // unlock
- call TokenToCfp.transfer();
- call Debug.log(DEBUG_LEVEL_INFO, 9, call IsTokenRequested.getNow(),0,0);
- dbgHistoryFlush();
- return;
- } else
- next = SWITCH_OFF;
- }
-
- // Check 5: is battery life extension (BLE) active and
- // has the BLE period expired?
- else if (call IsBLEActive.getNow() &&
- call TimeCalc.hasExpired(call CapStart.getNow(), call BLELen.getNow()) &&
- !call IsRxEnableActive.getNow()) {
- next = trySwitchOff();
- }
-
- // Check 6: is there a frame ready to transmit?
- else if (m_currentFrame != NULL) {
- next = tryTransmit();
- }
-
- // Check 7: should we be in receive mode?
- else if (COORD_ROLE || call IsRxEnableActive.getNow()) {
- next = tryReceive(NO_ALARM);
- if (next == DO_NOTHING && call IsRxEnableActive.getNow()){
- // this means there is an active MLME_RX_ENABLE.request
- // and the radio was just switched to Rx mode - signal
- // a notify event to inform the next higher layer
- post wasRxEnabledTask();
- }
- }
-
- // Check 8: just make sure the radio is switched off
- else {
- next = trySwitchOff();
- if (next == DO_NOTHING &&
- (!call IsBeaconEnabledPAN.getNow() || (DEVICE_ROLE && call CapLen.getNow() == 0))){
- // nothing more to do... just release the Token
- stopAllAlarms(); // may still fire, but is locked through isOwner()
- m_lock = FALSE; // unlock
- call Debug.log(DEBUG_LEVEL_INFO, 10, 0,0,0);
- dbgHistoryFlush();
- call Token.release();
- return;
- }
- }
-
- // if there is nothing to do, then we must clear the lock
- if (next == DO_NOTHING)
- m_lock = FALSE;
- } // atomic
- dbgHistoryAdd(next);
- // put next state in operation (possibly keeping the lock)
- switch (next)
- {
- case SWITCH_OFF: result = call RadioOff.off(); break;
- case LOAD_TX: result = call RadioTx.load(m_currentFrame); break;
- case PREPARE_RX: result = call RadioRx.prepare(); break;
- case WAIT_FOR_TXDONE: break;
- case DO_NOTHING: break;
- }
- if (result != SUCCESS)
- call Leds.led0On(); // internal error: could not update state !!!
- }
-
- next_state_t tryTransmit()
- {
- // tries to transmit m_currentFrame using the either slotted or unslotted csma-ca
- next_state_t next;
- if (call RadioTx.getLoadedFrame() == m_currentFrame){
- // the frame is already loaded -> transmit it now
- if (!m_slottedCsma){
- // unslotted CSMA-CA
- call RadioTx.transmitUnslottedCsmaCa(&m_csmaParams);
- next = WAIT_FOR_TXDONE; // this will NOT clear the lock
- } else {
- // slotted CSMA-CA
- uint32_t dtMax = call CapLen.getNow() - m_transactionTime - IEEE154_ACTIVE_PERIOD_GUARD_TIME;
- if (dtMax > call CapLen.getNow())
- dtMax = 0;
- if (call IsBLEActive.getNow()){
- // battery life extension
- uint16_t bleLen = call BLELen.getNow();
- if (bleLen < dtMax)
- dtMax = bleLen;
- }
- if (call TimeCalc.hasExpired(call CapStart.getNow() - 60, dtMax)) // 60 is for enabling Rx + 2 CCA
- next = SWITCH_OFF; // frame doesn't possibly fit in the remaining CAP
- else {
- call RadioTx.transmitSlottedCsmaCa(call CapStartRefTime.getNow(),
- dtMax, m_resume, m_remainingBackoff, &m_csmaParams);
- //call Debug.log(DEBUG_LEVEL_INFO, 13, call CapStart.getNow(), dtMax, m_resume);
- next = WAIT_FOR_TXDONE; // this will NOT clear the lock
- }
- }
- } else {
- // the frame to transmit has not yet been loaded -> load it now
- if (!call RadioOff.isOff())
- next = SWITCH_OFF;
- else {
- if (m_lastFrame){
- // the done event for the previous frame has not yet been
- // signalled to the upper layer -> wait
- next = DO_NOTHING;
- } else
- next = LOAD_TX;
- }
- }
- return next;
- }
-
- next_state_t tryReceive(rx_alarm_t alarmType)
- {
- next_state_t next;
- if (call RadioRx.isReceiving()){
- next = DO_NOTHING;
- } else if (call RadioRx.isPrepared()){
- call RadioRx.receive(NULL, 0);
- switch (alarmType)
- {
- case INDIRECT_TX_ALARM: call IndirectTxWaitAlarm.start(m_macMaxFrameTotalWaitTime); break;
- case BROADCAST_ALARM: call BroadcastAlarm.start(m_macMaxFrameTotalWaitTime); break;
- case NO_ALARM: break;
- }
- next = DO_NOTHING;
- } else if (call RadioOff.isOff())
- next = PREPARE_RX;
- else
- next = SWITCH_OFF;
- return next;
- }
-
- next_state_t trySwitchOff()
- {
- next_state_t next;
- if (call RadioOff.isOff())
- next = DO_NOTHING;
- else
- next = SWITCH_OFF;
- return next;
- }
-
- async event void RadioTx.loadDone(){ m_lock = FALSE; updateState();}
- async event void RadioOff.offDone(){ m_lock = FALSE; updateState();}
- async event void RadioRx.prepareDone(){ m_lock = FALSE; updateState();}
-
- async event void CapEndAlarm.fired(){
- call Debug.log(DEBUG_LEVEL_IMPORTANT, 3, superframeDirection, 0, 0);
- updateState();
- }
- async event void BLEAlarm.fired(){ updateState();}
- event void RxEnableStateChange.notify(bool whatever){ updateState();}
- async event void BroadcastAlarm.fired(){ m_broadcastRxPending = FALSE; updateState();}
-
- async event void IndirectTxWaitAlarm.fired()
- {
- atomic {
- if (m_indirectTxPending){
- m_indirectTxPending = FALSE;
- post signalTxDoneTask();
- }
- }
- }
-
- async event void RadioTx.transmitUnslottedCsmaCaDone(ieee154_txframe_t *frame,
- bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result)
- {
- transmitDone(frame, NULL, ackPendingFlag, csmaParams, result);
- }
-
- async event void RadioTx.transmitSlottedCsmaCaDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime,
- bool ackPendingFlag, uint16_t remainingBackoff, ieee154_csma_t *csmaParams, error_t result)
- {
- if (result == ERETRY){
- m_resume = TRUE;
- m_remainingBackoff = remainingBackoff;
- } else
- m_resume = FALSE;
- transmitDone(frame, txTime, ackPendingFlag, csmaParams, result);
- }
-
- void transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime,
- bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result)
- {
- bool done = TRUE;
- //call Debug.log(DEBUG_LEVEL_INFO, 11, result,0,0);
- switch (result)
- {
- case SUCCESS:
- // frame was successfully transmitted, if ACK was requested
- // then a matching ACK was successfully received also
- m_result = IEEE154_SUCCESS;
- if (DEVICE_ROLE && frame->payload[0] == CMD_FRAME_DATA_REQUEST &&
- ((frame->header->mhr[MHR_INDEX_FC1]) & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_CMD){
- // this was a data request frame
- m_result = IEEE154_NO_DATA; // pessimistic
- if (ackPendingFlag){
- // the coordinator has data for us; switch to Rx
- // to complete the indirect transmission
- m_indirectTxPending = TRUE;
- m_lastFrame = m_currentFrame;
- m_currentFrame = NULL;
- if (call RadioRx.prepare() != SUCCESS) // SHOULD succeed
- call RadioOff.off();
- return;
- }
- }
- break;
- case FAIL:
- // CSMA-CA algorithm failed: frame was not transmitted,
- // because channel was never idle (including backoff attempts)
- m_result = IEEE154_CHANNEL_ACCESS_FAILURE;
- break;
- case ENOACK:
- // frame was transmitted, but we didn't receive an ACK (and
- // the AckRequest flag was set in the frame header)
- // note: coordinator never retransmits an indirect transmission (see above)
- if (m_macMaxFrameRetries > 0) {
- // retransmit: reinitialize CSMA-CA parameters
- done = FALSE;
- m_csmaParams.NB = 0;
- m_csmaParams.macMaxCsmaBackoffs = m_macMaxCSMABackoffs;
- m_csmaParams.macMaxBE = m_macMaxBE;
- m_csmaParams.BE = m_BE;
- m_macMaxFrameRetries -= 1;
- } else
- m_result = IEEE154_NO_ACK;
- break;
- case ERETRY:
- // frame was not transmitted, because the transaction does not
- // fit in the remaining CAP (in beacon-enabled PANs only)
- done = FALSE;
- break;
- default:
- break;
- }
- if (COORD_ROLE && frame == m_bcastFrame){
- // always signal result of broadcast transmissions immediately
- restoreFrameFromBackup();
- signalTxBroadcastDone(m_bcastFrame, (!done) ? IEEE154_CHANNEL_ACCESS_FAILURE : m_result);
- m_bcastFrame = NULL;
- } else if (done) {
- m_lastFrame = m_currentFrame;
- m_currentFrame = NULL;
- post signalTxDoneTask();
- }
- m_lock = FALSE;
- updateState();
- }
-
- task void signalTxDoneTask()
- {
- ieee154_txframe_t *lastFrame = m_lastFrame;
- m_lastFrame = NULL; // only now can a next transmission begin
- m_indirectTxPending = FALSE;
- if (lastFrame)
- signal FrameTx.transmitDone(lastFrame, m_result);
- updateState();
- }
-
- event message_t* RadioRx.received(message_t* frame, ieee154_reftime_t *timestamp)
- {
- // received a frame during CAP - find out frame type and
- // signal it to corresponding client component
- uint8_t *payload = (uint8_t *) frame->data;
- uint8_t *mhr = MHR(frame);
- uint8_t frameType = mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK;
- if (frameType == FC1_FRAMETYPE_CMD)
- frameType += payload[0];
- atomic {
- if (DEVICE_ROLE && m_indirectTxPending){
- message_t* frameBuf;
- call IndirectTxWaitAlarm.stop();
- // TODO: check!
- //if (frame->payloadLen)
- // is this frame from our coordinator? hmm... we cannot say
- // with certainty, because we might only know either the
- // coordinator extended or short address (and the frame could
- // have been sent with the other addressing mode) ??
- m_result = IEEE154_SUCCESS;
- frameBuf = signal FrameExtracted.received[frameType](frame, m_lastFrame);
- signal IndirectTxWaitAlarm.fired();
- return frameBuf;
- } else
- return signal FrameRx.received[frameType](frame);
- }
- }
-
- void backupCurrentFrame()
- {
- ieee154_cap_frame_backup_t backup = {m_currentFrame, m_csmaParams, m_transactionTime};
- call FrameBackup.setNow(&backup);
- }
-
- void restoreFrameFromBackup()
- {
- ieee154_cap_frame_backup_t *backup = call FrameRestore.getNow();
- if (backup != NULL){
- m_currentFrame = backup->frame;
- memcpy(&m_csmaParams, &backup->csmaParams, sizeof(ieee154_csma_t));
- m_transactionTime = backup->transactionTime;
- }
- }
-
- async command ieee154_status_t BroadcastTx.transmitNow(ieee154_txframe_t *frame)
- {
- // if this command is called then it is (MUST be) called
- // only just before the token is transferred to this component
- // and it is then be called only once per CAP (max. one broadcast
- // is allowed after a beacon transmission)
- atomic {
- if (!call Token.isOwner() && m_bcastFrame == NULL){
- m_bcastFrame = frame;
- return IEEE154_SUCCESS;
- } else {
- call Leds.led0On();
- return IEEE154_TRANSACTION_OVERFLOW;
- }
- }
- }
-
- void signalTxBroadcastDone(ieee154_txframe_t *frame, ieee154_status_t error)
- {
- signal BroadcastTx.transmitNowDone(frame, error);
- }
-
- task void wasRxEnabledTask()
- {
- signal WasRxEnabled.notify(TRUE);
- }
-
- event void Token.granted()
- {
- // the current frame should be transmitted using unslotted CSMA-CA
- dbgHistoryReset();
- call Debug.log(DEBUG_LEVEL_INFO, 6, 0,0,0);
- updateState();
- }
-
- async event void RadioTx.transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime){}
-
- default event void FrameTx.transmitDone(ieee154_txframe_t *data, ieee154_status_t status){}
- default event message_t* FrameRx.received[uint8_t client](message_t* data){return data;}
- default async command bool IsRxEnableActive.getNow(){return FALSE;}
-
- default async command void IndirectTxWaitAlarm.start(uint32_t dt){call Leds.led0On();}
- default async command void IndirectTxWaitAlarm.stop(){call Leds.led0On();}
- default async command void IndirectTxWaitAlarm.startAt(uint32_t t0, uint32_t dt){call Leds.led0On();}
-
- default async command void BroadcastAlarm.start(uint32_t dt){call Leds.led0On();}
- default async command void BroadcastAlarm.stop(){call Leds.led0On();}
- default async command void BroadcastAlarm.startAt(uint32_t t0, uint32_t dt){call Leds.led0On();}
-
- default async command bool IsRxBroadcastPending.getNow(){ return FALSE;}
- default async event void BroadcastTx.transmitNowDone(ieee154_txframe_t *frame, ieee154_status_t status){}
- default event message_t* FrameExtracted.received[uint8_t client](message_t* msg, ieee154_txframe_t *txFrame){return msg;}
- default async command error_t FrameBackup.setNow(ieee154_cap_frame_backup_t* val ){return FAIL;}
- default async command ieee154_cap_frame_backup_t* FrameRestore.getNow(){return NULL;}
-
- command error_t WasRxEnabled.enable(){return FAIL;}
- command error_t WasRxEnabled.disable(){return FAIL;}
- command error_t FindBeacon.enable(){return FAIL;}
- command error_t FindBeacon.disable(){return FAIL;}
-}
command error_t Reset.init()
{
- while (call Queue.size()){
+ while (call Queue.size()) {
ieee154_txframe_t *txFrame = call Queue.dequeue();
signal FrameTx.transmitDone[txFrame->client](txFrame, IEEE154_TRANSACTION_OVERFLOW);
}
task void txTask()
{
- if (!m_busy && call Queue.size()){
+ if (!m_busy && call Queue.size()) {
ieee154_txframe_t *txFrame = call Queue.head();
- if (txFrame->headerLen == 0){
+ if (txFrame->headerLen == 0) {
// was purged
call Queue.dequeue();
signal Purge.purgeDone(txFrame, IEEE154_SUCCESS);
post txTask();
}
m_client = txFrame->client;
- if (call FrameTxCsma.transmit(txFrame) == IEEE154_SUCCESS){
+ if (call FrameTxCsma.transmit(txFrame) == IEEE154_SUCCESS) {
m_busy = TRUE;
}
}
return signal FrameExtracted.received[m_client](frame);
}
- default event void FrameTx.transmitDone[uint8_t client](ieee154_txframe_t *txFrame, ieee154_status_t status){}
+ default event void FrameTx.transmitDone[uint8_t client](ieee154_txframe_t *txFrame, ieee154_status_t status) {}
command ieee154_status_t Purge.purge(uint8_t msduHandle)
{
uint8_t qSize = call Queue.size(), i;
- if (qSize > 1){
- for (i=0; i<qSize-1; i++){
+ if (qSize > 1) {
+ for (i=0; i<qSize-1; i++) {
ieee154_txframe_t *txFrame = call Queue.element(i);
if (((txFrame->header->mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_DATA) &&
- txFrame->handle == msduHandle){
+ txFrame->handle == msduHandle) {
txFrame->headerLen = 0; // mark as invalid
return IEEE154_SUCCESS;
}
return IEEE154_INVALID_HANDLE;
}
- default event void Purge.purgeDone(ieee154_txframe_t *txFrame, ieee154_status_t status){}
+ default event void Purge.purgeDone(ieee154_txframe_t *txFrame, ieee154_status_t status) {}
}
interface Timer<TSymbolIEEE802154> as IndirectTxTimeout;
interface TimeCalc;
interface Leds;
- interface Ieee802154Debug as Debug;
}
}
implementation
return 0;
pendingAddrField[0] = 0;
adrPtr = (nxle_uint16_t *) &pendingAddrField[1];
- for (i=0; i<NUM_MAX_PENDING; i++){
+ for (i=0; i<NUM_MAX_PENDING; i++) {
if (!m_txFrameTable[i])
continue;
txFrame = m_txFrameTable[i];
- if ((txFrame->header->mhr[MHR_INDEX_FC2] & FC2_DEST_MODE_MASK) == FC2_DEST_MODE_SHORT){
+ if ((txFrame->header->mhr[MHR_INDEX_FC2] & FC2_DEST_MODE_MASK) == FC2_DEST_MODE_SHORT) {
*adrPtr++ = *((nxle_uint16_t*) &txFrame->header->mhr[MHR_INDEX_ADDRESS + sizeof(ieee154_macPANId_t)]);
} else if ((txFrame->header->mhr[MHR_INDEX_FC2] & FC2_DEST_MODE_MASK) == FC2_DEST_MODE_EXTENDED)
longAdrPtr[k++] = &(txFrame->header->mhr[MHR_INDEX_ADDRESS + sizeof(ieee154_macPANId_t)]);
for (j=0; j<8; j++)
pendingAddrField[1 + 2*m_numShortPending + i*8 + j] = longAdrPtr[i][j];
pendingAddrField[0] = m_numShortPending | (m_numExtPending << 4);
- call Debug.log(DEBUG_LEVEL_INFO, IndirectTxP_BEACON_ASSEMBLY, len,0,0);
return len;
}
{
// send a frame through indirect transmission
uint8_t i;
- if (m_numTableEntries >= NUM_MAX_PENDING){
- call Debug.log(DEBUG_LEVEL_IMPORTANT, IndirectTxP_OVERFLOW, 0,0,0);
+ if (m_numTableEntries >= NUM_MAX_PENDING) {
+ dbg_serial("IndirectTxP", "Overflow\n");
return IEEE154_TRANSACTION_OVERFLOW;
}
txFrame->client = client;
m_numExtPending++;
if (!call IndirectTxTimeout.isRunning())
call IndirectTxTimeout.startOneShot(getPersistenceTime());
- call Debug.log(DEBUG_LEVEL_INFO, IndirectTxP_NOTIFIED, 0,0,0);
+ dbg_serial("IndirectTxP", "Preparing a transmission.\n");
signal PendingAddrSpecUpdated.notify(TRUE);
return IEEE154_SUCCESS;
}
src += 10;
if (!((mhr[0] & FC1_PAN_ID_COMPRESSION) && (mhr[1] & FC2_DEST_MODE_SHORT)))
src += 2;
- for (i=0; i<NUM_MAX_PENDING; i++){
+ for (i=0; i<NUM_MAX_PENDING; i++) {
if (!m_txFrameTable[i])
continue;
else {
}
}
}
- call Debug.log(DEBUG_LEVEL_INFO, IndirectTxP_REQUESTED, NUM_MAX_PENDING-i,i,*src);
- if (i != NUM_MAX_PENDING){
+ dbg_serial("IndirectTxP", "Received a request, i=%lu, MAX=%lu\n",
+ (uint32_t) i,(uint32_t) NUM_MAX_PENDING);
+ if (i != NUM_MAX_PENDING) {
// found a matching frame, mark it for transmission
m_txFrameTable[i]->client |= SEND_THIS_FRAME;
post tryCoordCapTxTask();
// iterate over the queued frames and transmit them in the CAP
// (if they are marked for transmission)
uint8_t i;
- if (m_pendingTxFrame == NULL && m_numTableEntries){
+ if (m_pendingTxFrame == NULL && m_numTableEntries) {
for (i=0; i<NUM_MAX_PENDING; i++)
- if (m_txFrameTable[i] && (m_txFrameTable[i]->client & SEND_THIS_FRAME)){
+ if (m_txFrameTable[i] && (m_txFrameTable[i]->client & SEND_THIS_FRAME)) {
// TODO: set frame pending bit, if there's more data for this destination
m_pendingTxFrame = m_txFrameTable[i];
m_client = m_txFrameTable[i]->client;
- if (call CoordCapTx.transmit(m_txFrameTable[i]) == IEEE154_SUCCESS){
- call Debug.log(DEBUG_LEVEL_INFO, IndirectTxP_SEND_NOW, 0,0,0);
+ if (call CoordCapTx.transmit(m_txFrameTable[i]) == IEEE154_SUCCESS) {
+ dbg_serial("IndirectTxP", "Started a transmission.\n");
} else {
m_pendingTxFrame = NULL;
post tryCoordCapTxTask();
uint8_t i;
for (i=0; i<NUM_MAX_PENDING; i++)
- if (m_txFrameTable[i] && m_txFrameTable[i] != m_pendingTxFrame){
- if (call TimeCalc.hasExpired(m_txFrameTable[i]->metadata->timestamp, persistenceTime)){
+ if (m_txFrameTable[i] && m_txFrameTable[i] != m_pendingTxFrame) {
+ if (call TimeCalc.hasExpired(m_txFrameTable[i]->metadata->timestamp, persistenceTime)) {
ieee154_txframe_t *txFrame = m_txFrameTable[i];
txFrame->client &= ~SEND_THIS_FRAME;
m_txFrameTable[i] = NULL;
m_numExtPending--;
signal FrameTx.transmitDone[txFrame->client](txFrame, IEEE154_TRANSACTION_EXPIRED);
signal PendingAddrSpecUpdated.notify(TRUE);
- } else if (call TimeCalc.timeElapsed(m_txFrameTable[i]->metadata->timestamp, now) > dt){
+ } else if (call TimeCalc.timeElapsed(m_txFrameTable[i]->metadata->timestamp, now) > dt) {
dt = call TimeCalc.timeElapsed(m_txFrameTable[i]->metadata->timestamp, now);
}
}
- if (dt != 0){
+ if (dt != 0) {
if (dt > persistenceTime)
dt = persistenceTime;
call IndirectTxTimeout.startOneShot(persistenceTime - dt);
uint8_t i;
// TODO: if CSMA-CA algorithm failed, then frame shall still remain in transaction queue
for (i=0; i<NUM_MAX_PENDING; i++)
- if (m_txFrameTable[i] == txFrame){
+ if (m_txFrameTable[i] == txFrame) {
m_txFrameTable[i] = NULL; // slot is now empty
break;
}
m_numExtPending--;
signal FrameTx.transmitDone[txFrame->client](txFrame, status);
post tryCoordCapTxTask();
- call Debug.log(DEBUG_LEVEL_INFO, IndirectTxP_SEND_DONE, status,m_numTableEntries,0);
+ dbg_serial("IndirectTxP", "transmitDone()\n");
}
- command ieee154_txframe_t* GetIndirectTxFrame.get(){ return m_pendingTxFrame;}
- command error_t PendingAddrSpecUpdated.enable(){return FAIL;}
- command error_t PendingAddrSpecUpdated.disable(){return FAIL;}
- default event void FrameTx.transmitDone[uint8_t client](ieee154_txframe_t *txFrame, ieee154_status_t status){}
+ command ieee154_txframe_t* GetIndirectTxFrame.get() { return m_pendingTxFrame;}
+ command error_t PendingAddrSpecUpdated.enable() {return FAIL;}
+ command error_t PendingAddrSpecUpdated.disable() {return FAIL;}
+ default event void PendingAddrSpecUpdated.notify( bool val ) {return;}
+ default event void FrameTx.transmitDone[uint8_t client](ieee154_txframe_t *txFrame, ieee154_status_t status) {}
}
* ========================================================================
*/
-/* This component maintains the PIB (PAN Information Base) attributes and
- * provides interfaces for accessing fields in a MAC frame. */
+/**
+ * This component maintains the PIB (PAN Information Base) attributes and
+ * provides interfaces for accessing fields in a MAC frame.
+ */
#include "TKN154.h"
#include "TKN154_PIB.h"
interface Set<ieee154_macSuperframeOrder_t> as SetMacSuperframeOrder;
interface Set<ieee154_macBeaconTxTime_t> as SetMacBeaconTxTime;
interface Set<ieee154_macPanCoordinator_t> as SetMacPanCoordinator;
- interface Get<ieee154_macPanCoordinator_t> as IsMacPanCoordinator;
- interface GetNow<bool> as IsBeaconEnabledPAN;
interface FrameUtility;
interface IEEE154Frame as Frame;
interface IEEE154BeaconFrame as BeaconFrame;
uses
{
interface Get<bool> as PromiscuousModeGet;
- interface Init as CapReset;
- interface Init as CapQueueReset;
+ interface Init as FrameDispatchReset;
+ interface Init as FrameDispatchQueueReset;
interface Init as MacReset;
interface SplitControl as RadioControl;
interface Random;
ieee154_PIB_t m_pib;
uint8_t m_numResetClientPending;
bool m_setDefaultPIB;
- norace uint8_t m_panType;
- uint8_t m_updatePANType;
uint8_t m_resetSpin;
#ifdef IEEE154_EXTENDED_ADDRESS
waitTime = (((uint16_t) 1 << macMaxBE) - 1) * (macMaxCSMABackoffs - m);
if (m) {
k = 0;
- while (k != m){
+ while (k != m) {
waitTime += ((uint16_t) 1 << (macMaxBE+k));
k += 1;
}
m_pib.macMaxFrameTotalWaitTime = waitTime;
}
- command ieee154_status_t MLME_RESET.request(bool SetDefaultPIB, uint8_t PANType)
+ command ieee154_status_t MLME_RESET.request(bool SetDefaultPIB)
{
// resetting the complete stack is not so easy...
// first we acquire the Token (get exclusive radio access), then we switch off
// Alarms!), but there can still be pending Timers/tasks -> we stop all Timers
// through MacReset.init() and then spin a few tasks in between to get
// everything "flushed out"
- if (PANType != BEACON_ENABLED_PAN && PANType != NONBEACON_ENABLED_PAN)
- return IEEE154_INVALID_PARAMETER;
+ ieee154_status_t status = IEEE154_SUCCESS;
if (call PromiscuousModeGet.get())
- return IEEE154_TRANSACTION_OVERFLOW; // must first cancel promiscuous mode!
- m_setDefaultPIB = SetDefaultPIB;
- m_updatePANType = PANType;
- if (!call Token.isOwner())
- call Token.request();
- return IEEE154_SUCCESS;
+ status = IEEE154_TRANSACTION_OVERFLOW; // must first cancel promiscuous mode!
+ else {
+ m_setDefaultPIB = SetDefaultPIB;
+ if (!call Token.isOwner())
+ call Token.request();
+ }
+ dbg_serial("PibP", "MLME_RESET.request(%lu) -> result: %lu\n",
+ (uint32_t) SetDefaultPIB, (uint32_t) status);
+ return status;
}
event void Token.granted()
{
- error_t error = call RadioOff.off();
- if (error != SUCCESS) // either it is already off or driver has not been started
+ if (call RadioOff.off() != SUCCESS)
signal RadioOff.offDone();
}
task void radioControlStopTask()
{
- if (call RadioControl.stop() == EALREADY)
+ error_t result = call RadioControl.stop();
+ if (result == EALREADY)
signal RadioControl.stopDone(SUCCESS);
+ else
+ ASSERT(result == SUCCESS);
}
- event void RadioControl.stopDone(error_t error)
+ event void RadioControl.stopDone(error_t result)
{
- m_panType = m_updatePANType;
- call CapReset.init(); // resets the CAP component(s), spool out frames
- call CapQueueReset.init(); // resets the CAP queue component(s), spool out frames
+ ASSERT(result == SUCCESS);
+ call FrameDispatchReset.init(); // resets the CAP component(s), spool out frames
+ call FrameDispatchQueueReset.init(); // resets the CAP queue component(s), spool out frames
call MacReset.init(); // resets the remaining components
m_resetSpin = 5;
post resetSpinTask();
task void resetSpinTask()
{
- if (m_resetSpin == 2){
+ if (m_resetSpin == 2) {
// just to be safe...
- call CapReset.init();
- call CapQueueReset.init();
+ call FrameDispatchReset.init();
+ call FrameDispatchQueueReset.init();
call MacReset.init();
}
- if (m_resetSpin--){
+ if (m_resetSpin--) {
post resetSpinTask();
return;
}
- if (call RadioControl.start() == EALREADY)
- signal RadioControl.startDone(SUCCESS);
+ ASSERT(call RadioControl.start() == SUCCESS);
}
event void RadioControl.startDone(error_t error)
signal MLME_RESET.confirm(IEEE154_SUCCESS);
}
-/* ----------------------- MLME-GET ----------------------- */
+ /* ----------------------- MLME-GET ----------------------- */
+
+ command ieee154_phyCurrentChannel_t MLME_GET.phyCurrentChannel() { return m_pib.phyCurrentChannel;}
- command ieee154_phyCurrentChannel_t MLME_GET.phyCurrentChannel(){ return m_pib.phyCurrentChannel;}
+ command ieee154_phyChannelsSupported_t MLME_GET.phyChannelsSupported() { return IEEE154_SUPPORTED_CHANNELS;}
- command ieee154_phyChannelsSupported_t MLME_GET.phyChannelsSupported(){ return IEEE154_SUPPORTED_CHANNELS;}
+ command ieee154_phyTransmitPower_t MLME_GET.phyTransmitPower() { return m_pib.phyTransmitPower;}
- command ieee154_phyTransmitPower_t MLME_GET.phyTransmitPower(){ return m_pib.phyTransmitPower;}
+ command ieee154_phyCCAMode_t MLME_GET.phyCCAMode() { return m_pib.phyCCAMode;}
- command ieee154_phyCCAMode_t MLME_GET.phyCCAMode(){ return m_pib.phyCCAMode;}
+ command ieee154_phyCurrentPage_t MLME_GET.phyCurrentPage() { return m_pib.phyCurrentPage;}
- command ieee154_phyCurrentPage_t MLME_GET.phyCurrentPage(){ return m_pib.phyCurrentPage;}
+ command ieee154_phyMaxFrameDuration_t MLME_GET.phyMaxFrameDuration() { return IEEE154_MAX_FRAME_DURATION;}
- command ieee154_phyMaxFrameDuration_t MLME_GET.phyMaxFrameDuration(){ return IEEE154_MAX_FRAME_DURATION;}
+ command ieee154_phySHRDuration_t MLME_GET.phySHRDuration() { return IEEE154_SHR_DURATION;}
- command ieee154_phySHRDuration_t MLME_GET.phySHRDuration(){ return IEEE154_SHR_DURATION;}
+ command ieee154_phySymbolsPerOctet_t MLME_GET.phySymbolsPerOctet() { return IEEE154_SYMBOLS_PER_OCTET;}
- command ieee154_phySymbolsPerOctet_t MLME_GET.phySymbolsPerOctet(){ return IEEE154_SYMBOLS_PER_OCTET;}
+ command ieee154_macAckWaitDuration_t MLME_GET.macAckWaitDuration() { return IEEE154_ACK_WAIT_DURATION;}
- command ieee154_macAckWaitDuration_t MLME_GET.macAckWaitDuration(){ return IEEE154_ACK_WAIT_DURATION;}
+ command ieee154_macAssociationPermit_t MLME_GET.macAssociationPermit() { return m_pib.macAssociationPermit;}
- command ieee154_macAssociationPermit_t MLME_GET.macAssociationPermit(){ return m_pib.macAssociationPermit;}
+ command ieee154_macAutoRequest_t MLME_GET.macAutoRequest() { return m_pib.macAutoRequest;}
- command ieee154_macAutoRequest_t MLME_GET.macAutoRequest(){ return m_pib.macAutoRequest;}
+ command ieee154_macBattLifeExt_t MLME_GET.macBattLifeExt() { return m_pib.macBattLifeExt;}
- command ieee154_macBattLifeExt_t MLME_GET.macBattLifeExt(){ return m_pib.macBattLifeExt;}
+ command ieee154_macBattLifeExtPeriods_t MLME_GET.macBattLifeExtPeriods() { return IEEE154_BATT_LIFE_EXT_PERIODS;}
- command ieee154_macBattLifeExtPeriods_t MLME_GET.macBattLifeExtPeriods(){ return IEEE154_BATT_LIFE_EXT_PERIODS;}
+ command ieee154_macBeaconOrder_t MLME_GET.macBeaconOrder() { return m_pib.macBeaconOrder;}
- command ieee154_macBeaconOrder_t MLME_GET.macBeaconOrder(){ return m_pib.macBeaconOrder;}
+ command ieee154_macBeaconTxTime_t MLME_GET.macBeaconTxTime() { return m_pib.macBeaconTxTime;}
- command ieee154_macBeaconTxTime_t MLME_GET.macBeaconTxTime(){ return m_pib.macBeaconTxTime;}
+ command ieee154_macBSN_t MLME_GET.macBSN() { return m_pib.macBSN;}
- command ieee154_macBSN_t MLME_GET.macBSN(){ return m_pib.macBSN;}
+ command ieee154_macCoordExtendedAddress_t MLME_GET.macCoordExtendedAddress() { return m_pib.macCoordExtendedAddress;}
- command ieee154_macCoordExtendedAddress_t MLME_GET.macCoordExtendedAddress(){ return m_pib.macCoordExtendedAddress;}
+ command ieee154_macCoordShortAddress_t MLME_GET.macCoordShortAddress() { return m_pib.macCoordShortAddress;}
- command ieee154_macCoordShortAddress_t MLME_GET.macCoordShortAddress(){ return m_pib.macCoordShortAddress;}
+ command ieee154_macDSN_t MLME_GET.macDSN() { return m_pib.macDSN;}
- command ieee154_macDSN_t MLME_GET.macDSN(){ return m_pib.macDSN;}
+ command ieee154_macGTSPermit_t MLME_GET.macGTSPermit() { return m_pib.macGTSPermit;}
- command ieee154_macGTSPermit_t MLME_GET.macGTSPermit(){ return m_pib.macGTSPermit;}
+ command ieee154_macMaxCSMABackoffs_t MLME_GET.macMaxCSMABackoffs() { return m_pib.macMaxCSMABackoffs;}
- command ieee154_macMaxCSMABackoffs_t MLME_GET.macMaxCSMABackoffs(){ return m_pib.macMaxCSMABackoffs;}
+ command ieee154_macMinBE_t MLME_GET.macMinBE() { return m_pib.macMinBE;}
- command ieee154_macMinBE_t MLME_GET.macMinBE(){ return m_pib.macMinBE;}
+ command ieee154_macPANId_t MLME_GET.macPANId() { return m_pib.macPANId;}
- command ieee154_macPANId_t MLME_GET.macPANId(){ return m_pib.macPANId;}
+ command ieee154_macPromiscuousMode_t MLME_GET.macPromiscuousMode() { return call PromiscuousModeGet.get();}
- command ieee154_macPromiscuousMode_t MLME_GET.macPromiscuousMode(){ return call PromiscuousModeGet.get();}
+ command ieee154_macRxOnWhenIdle_t MLME_GET.macRxOnWhenIdle() { return m_pib.macRxOnWhenIdle;}
- command ieee154_macRxOnWhenIdle_t MLME_GET.macRxOnWhenIdle(){ return m_pib.macRxOnWhenIdle;}
+ command ieee154_macShortAddress_t MLME_GET.macShortAddress() { return m_pib.macShortAddress;}
- command ieee154_macShortAddress_t MLME_GET.macShortAddress(){ return m_pib.macShortAddress;}
+ command ieee154_macSuperframeOrder_t MLME_GET.macSuperframeOrder() { return m_pib.macSuperframeOrder;}
- command ieee154_macSuperframeOrder_t MLME_GET.macSuperframeOrder(){ return m_pib.macSuperframeOrder;}
+ command ieee154_macTransactionPersistenceTime_t MLME_GET.macTransactionPersistenceTime() { return m_pib.macTransactionPersistenceTime;}
- command ieee154_macTransactionPersistenceTime_t MLME_GET.macTransactionPersistenceTime(){ return m_pib.macTransactionPersistenceTime;}
+ command ieee154_macAssociatedPANCoord_t MLME_GET.macAssociatedPANCoord() { return m_pib.macAssociatedPANCoord;}
- command ieee154_macAssociatedPANCoord_t MLME_GET.macAssociatedPANCoord(){ return m_pib.macAssociatedPANCoord;}
+ command ieee154_macMaxBE_t MLME_GET.macMaxBE() { return m_pib.macMaxBE;}
- command ieee154_macMaxBE_t MLME_GET.macMaxBE(){ return m_pib.macMaxBE;}
+ command ieee154_macMaxFrameTotalWaitTime_t MLME_GET.macMaxFrameTotalWaitTime() { return m_pib.macMaxFrameTotalWaitTime;}
- command ieee154_macMaxFrameTotalWaitTime_t MLME_GET.macMaxFrameTotalWaitTime(){ return m_pib.macMaxFrameTotalWaitTime;}
+ command ieee154_macMaxFrameRetries_t MLME_GET.macMaxFrameRetries() { return m_pib.macMaxFrameRetries;}
- command ieee154_macMaxFrameRetries_t MLME_GET.macMaxFrameRetries(){ return m_pib.macMaxFrameRetries;}
+ command ieee154_macResponseWaitTime_t MLME_GET.macResponseWaitTime() { return m_pib.macResponseWaitTime;}
- command ieee154_macResponseWaitTime_t MLME_GET.macResponseWaitTime(){ return m_pib.macResponseWaitTime;}
+ command ieee154_macSyncSymbolOffset_t MLME_GET.macSyncSymbolOffset() { return IEEE154_SYNC_SYMBOL_OFFSET;}
- command ieee154_macSyncSymbolOffset_t MLME_GET.macSyncSymbolOffset(){ return IEEE154_SYNC_SYMBOL_OFFSET;}
+ command ieee154_macTimestampSupported_t MLME_GET.macTimestampSupported() { return IEEE154_TIMESTAMP_SUPPORTED;}
- command ieee154_macTimestampSupported_t MLME_GET.macTimestampSupported(){ return IEEE154_TIMESTAMP_SUPPORTED;}
+ command ieee154_macSecurityEnabled_t MLME_GET.macSecurityEnabled() { return m_pib.macSecurityEnabled;}
- command ieee154_macSecurityEnabled_t MLME_GET.macSecurityEnabled(){ return m_pib.macSecurityEnabled;}
+ command ieee154_macMinLIFSPeriod_t MLME_GET.macMinLIFSPeriod() { return IEEE154_MIN_LIFS_PERIOD;}
- command ieee154_macMinLIFSPeriod_t MLME_GET.macMinLIFSPeriod(){ return IEEE154_MIN_LIFS_PERIOD;}
+ command ieee154_macMinSIFSPeriod_t MLME_GET.macMinSIFSPeriod() { return IEEE154_MIN_SIFS_PERIOD;}
- command ieee154_macMinSIFSPeriod_t MLME_GET.macMinSIFSPeriod(){ return IEEE154_MIN_SIFS_PERIOD;}
+ command ieee154_macPanCoordinator_t MLME_GET.macPanCoordinator() { return m_pib.macPanCoordinator;}
-/* ----------------------- MLME-SET ----------------------- */
+ /* ----------------------- MLME-SET ----------------------- */
- command ieee154_status_t MLME_SET.phyCurrentChannel(ieee154_phyCurrentChannel_t value){
+ command ieee154_status_t MLME_SET.phyCurrentChannel(ieee154_phyCurrentChannel_t value) {
uint32_t i = 1;
uint8_t k = value;
- while (i && k){
+ while (i && k) {
i <<= 1;
k -= 1;
}
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.phyTransmitPower(ieee154_phyTransmitPower_t value){
+ command ieee154_status_t MLME_SET.phyTransmitPower(ieee154_phyTransmitPower_t value) {
m_pib.phyTransmitPower = (value & 0x3F);
signal PIBUpdate.notify[IEEE154_phyTransmitPower](&m_pib.phyTransmitPower);
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.phyCCAMode(ieee154_phyCCAMode_t value){
+ command ieee154_status_t MLME_SET.phyCCAMode(ieee154_phyCCAMode_t value) {
if (value < 1 || value > 3)
return IEEE154_INVALID_PARAMETER;
m_pib.phyCCAMode = value;
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.phyCurrentPage(ieee154_phyCurrentPage_t value){
+ command ieee154_status_t MLME_SET.phyCurrentPage(ieee154_phyCurrentPage_t value) {
if (value > 31)
return IEEE154_INVALID_PARAMETER;
m_pib.phyCurrentPage = value;
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macAssociationPermit(ieee154_macAssociationPermit_t value){
+ command ieee154_status_t MLME_SET.macAssociationPermit(ieee154_macAssociationPermit_t value) {
m_pib.macAssociationPermit = value;
signal PIBUpdate.notify[IEEE154_macAssociationPermit](&m_pib.macAssociationPermit);
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macAutoRequest(ieee154_macAutoRequest_t value){
+ command ieee154_status_t MLME_SET.macAutoRequest(ieee154_macAutoRequest_t value) {
m_pib.macAutoRequest = value;
signal PIBUpdate.notify[IEEE154_macAutoRequest](&m_pib.macAutoRequest);
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macBattLifeExt(ieee154_macBattLifeExt_t value){
+ command ieee154_status_t MLME_SET.macBattLifeExt(ieee154_macBattLifeExt_t value) {
m_pib.macBattLifeExt = value;
signal PIBUpdate.notify[IEEE154_macBattLifeExt](&m_pib.macBattLifeExt);
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macBattLifeExtPeriods(ieee154_macBattLifeExtPeriods_t value){
+ command ieee154_status_t MLME_SET.macBattLifeExtPeriods(ieee154_macBattLifeExtPeriods_t value) {
if (value < 6 || value > 41)
return IEEE154_INVALID_PARAMETER;
m_pib.macBattLifeExtPeriods = value;
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macBeaconOrder(ieee154_macBeaconOrder_t value){
+ command ieee154_status_t MLME_SET.macBeaconOrder(ieee154_macBeaconOrder_t value) {
if (value > 15)
return IEEE154_INVALID_PARAMETER;
m_pib.macBeaconOrder = value;
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macBSN(ieee154_macBSN_t value){
+ command ieee154_status_t MLME_SET.macBSN(ieee154_macBSN_t value) {
m_pib.macBSN = value;
signal PIBUpdate.notify[IEEE154_macBSN](&m_pib.macBSN);
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macCoordExtendedAddress(ieee154_macCoordExtendedAddress_t value){
+ command ieee154_status_t MLME_SET.macCoordExtendedAddress(ieee154_macCoordExtendedAddress_t value) {
m_pib.macCoordExtendedAddress = value;
signal PIBUpdate.notify[IEEE154_macCoordExtendedAddress](&m_pib.macCoordExtendedAddress);
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macCoordShortAddress(ieee154_macCoordShortAddress_t value){
+ command ieee154_status_t MLME_SET.macCoordShortAddress(ieee154_macCoordShortAddress_t value) {
m_pib.macCoordShortAddress = value;
signal PIBUpdate.notify[IEEE154_macCoordShortAddress](&m_pib.macCoordShortAddress);
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macDSN(ieee154_macDSN_t value){
+ command ieee154_status_t MLME_SET.macDSN(ieee154_macDSN_t value) {
m_pib.macDSN = value;
signal PIBUpdate.notify[IEEE154_macDSN](&m_pib.macDSN);
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macGTSPermit(ieee154_macGTSPermit_t value){
+ command ieee154_status_t MLME_SET.macGTSPermit(ieee154_macGTSPermit_t value) {
m_pib.macGTSPermit = value;
signal PIBUpdate.notify[IEEE154_macGTSPermit](&m_pib.macGTSPermit);
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macMaxCSMABackoffs(ieee154_macMaxCSMABackoffs_t value){
+ command ieee154_status_t MLME_SET.macMaxCSMABackoffs(ieee154_macMaxCSMABackoffs_t value) {
if (value > 5)
return IEEE154_INVALID_PARAMETER;
m_pib.macMaxCSMABackoffs = value;
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macMinBE(ieee154_macMinBE_t value){
+ command ieee154_status_t MLME_SET.macMinBE(ieee154_macMinBE_t value) {
if (value > m_pib.macMaxBE)
return IEEE154_INVALID_PARAMETER;
m_pib.macMinBE = value;
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macPANId(ieee154_macPANId_t value){
+ command ieee154_status_t MLME_SET.macPANId(ieee154_macPANId_t value) {
m_pib.macPANId = value;
signal PIBUpdate.notify[IEEE154_macPANId](&m_pib.macPANId);
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macRxOnWhenIdle(ieee154_macRxOnWhenIdle_t value){
+ command ieee154_status_t MLME_SET.macRxOnWhenIdle(ieee154_macRxOnWhenIdle_t value) {
m_pib.macRxOnWhenIdle = value;
signal PIBUpdate.notify[IEEE154_macRxOnWhenIdle](&m_pib.macRxOnWhenIdle);
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macShortAddress(ieee154_macShortAddress_t value){
+ command ieee154_status_t MLME_SET.macShortAddress(ieee154_macShortAddress_t value) {
m_pib.macShortAddress = value;
signal PIBUpdate.notify[IEEE154_macShortAddress](&m_pib.macShortAddress);
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macTransactionPersistenceTime(ieee154_macTransactionPersistenceTime_t value){
+ command ieee154_status_t MLME_SET.macTransactionPersistenceTime(ieee154_macTransactionPersistenceTime_t value) {
m_pib.macTransactionPersistenceTime = value;
signal PIBUpdate.notify[IEEE154_macTransactionPersistenceTime](&m_pib.macTransactionPersistenceTime);
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macAssociatedPANCoord(ieee154_macAssociatedPANCoord_t value){
+ command ieee154_status_t MLME_SET.macAssociatedPANCoord(ieee154_macAssociatedPANCoord_t value) {
m_pib.macAssociatedPANCoord = value;
signal PIBUpdate.notify[IEEE154_macAssociatedPANCoord](&m_pib.macAssociatedPANCoord);
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macMaxBE(ieee154_macMaxBE_t value){
+ command ieee154_status_t MLME_SET.macMaxBE(ieee154_macMaxBE_t value) {
if (value < 3 || value > 8)
return IEEE154_INVALID_PARAMETER;
m_pib.macMaxBE = value;
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macMaxFrameTotalWaitTime(ieee154_macMaxFrameTotalWaitTime_t value){
+ command ieee154_status_t MLME_SET.macMaxFrameTotalWaitTime(ieee154_macMaxFrameTotalWaitTime_t value) {
// equation 14 on page 160 defines how macMaxFrameTotalWaitTime is calculated;
// its value depends only on other PIB attributes and constants - why does the standard
// allow setting it by the next higher layer ??
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macMaxFrameRetries(ieee154_macMaxFrameRetries_t value){
+ command ieee154_status_t MLME_SET.macMaxFrameRetries(ieee154_macMaxFrameRetries_t value) {
if (value > 7)
return IEEE154_INVALID_PARAMETER;
m_pib.macMaxFrameRetries = value;
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macResponseWaitTime(ieee154_macResponseWaitTime_t value){
+ command ieee154_status_t MLME_SET.macResponseWaitTime(ieee154_macResponseWaitTime_t value) {
if (value < 2 || value > 64)
return IEEE154_INVALID_PARAMETER;
m_pib.macResponseWaitTime = value;
return IEEE154_SUCCESS;
}
- command ieee154_status_t MLME_SET.macSecurityEnabled(ieee154_macSecurityEnabled_t value){
+ command ieee154_status_t MLME_SET.macSecurityEnabled(ieee154_macSecurityEnabled_t value) {
return IEEE154_UNSUPPORTED_ATTRIBUTE;
}
// Read-only attributes (writable only by MAC components)
- command void SetMacSuperframeOrder.set( ieee154_macSuperframeOrder_t value ){
+ command void SetMacSuperframeOrder.set( ieee154_macSuperframeOrder_t value) {
m_pib.macSuperframeOrder = value;
signal PIBUpdate.notify[IEEE154_macSuperframeOrder](&m_pib.macSuperframeOrder);
}
- command void SetMacBeaconTxTime.set( ieee154_macBeaconTxTime_t value ){
+ command void SetMacBeaconTxTime.set( ieee154_macBeaconTxTime_t value) {
m_pib.macBeaconTxTime = value;
signal PIBUpdate.notify[IEEE154_macBeaconTxTime](&m_pib.macBeaconTxTime);
}
- command void SetMacPanCoordinator.set( ieee154_macPanCoordinator_t value ){
+ command void SetMacPanCoordinator.set( ieee154_macPanCoordinator_t value) {
m_pib.macPanCoordinator = value;
signal PIBUpdate.notify[IEEE154_macPanCoordinator](&m_pib.macPanCoordinator);
}
- command ieee154_macPanCoordinator_t IsMacPanCoordinator.get(){
- return m_pib.macPanCoordinator;
- }
-
-/* ----------------------- TimeCalc ----------------------- */
+ /* ----------------------- TimeCalc ----------------------- */
async command uint32_t TimeCalc.timeElapsed(uint32_t t0, uint32_t t1)
{
return (elapsed >= dt);
}
-/* ----------------------- Frame Access ----------------------- */
+ /* ----------------------- Frame Access ----------------------- */
command void Packet.clear(message_t* msg)
{
bool PANIDCompression)
{
uint8_t offset = MHR_INDEX_ADDRESS;
- if (DstAddrMode == ADDR_MODE_SHORT_ADDRESS || DstAddrMode == ADDR_MODE_EXTENDED_ADDRESS){
+ if (DstAddrMode == ADDR_MODE_SHORT_ADDRESS || DstAddrMode == ADDR_MODE_EXTENDED_ADDRESS) {
*((nxle_uint16_t*) &mhr[offset]) = DstPANId;
offset += 2;
- if (DstAddrMode == ADDR_MODE_SHORT_ADDRESS){
+ if (DstAddrMode == ADDR_MODE_SHORT_ADDRESS) {
*((nxle_uint16_t*) &mhr[offset]) = DstAddr->shortAddress;
offset += 2;
} else {
offset += 8;
}
}
- if (SrcAddrMode == ADDR_MODE_SHORT_ADDRESS || SrcAddrMode == ADDR_MODE_EXTENDED_ADDRESS){
- if (DstPANId != SrcPANId || !PANIDCompression){
+ if (SrcAddrMode == ADDR_MODE_SHORT_ADDRESS || SrcAddrMode == ADDR_MODE_EXTENDED_ADDRESS) {
+ if (DstPANId != SrcPANId || !PANIDCompression) {
*((nxle_uint16_t*) &mhr[offset]) = SrcPANId;
offset += 2;
}
- if (SrcAddrMode == ADDR_MODE_SHORT_ADDRESS){
+ if (SrcAddrMode == ADDR_MODE_SHORT_ADDRESS) {
*((nxle_uint16_t*) &mhr[offset]) = SrcAddr->shortAddress;
offset += 2;
} else {
if ((*(nxle_uint16_t*) (&mhr[offset])) != m_pib.macPANId)
return FALSE; // wrong PAN ID
offset += 2;
- if ((mhr[MHR_INDEX_FC2] & FC2_SRC_MODE_MASK) == FC2_SRC_MODE_SHORT){
+ if ((mhr[MHR_INDEX_FC2] & FC2_SRC_MODE_MASK) == FC2_SRC_MODE_SHORT) {
if ((*(nxle_uint16_t*) (&mhr[offset])) != m_pib.macCoordShortAddress)
return FALSE;
- } else if ((mhr[MHR_INDEX_FC2] & FC2_SRC_MODE_MASK) == FC2_SRC_MODE_EXTENDED){
+ } else if ((mhr[MHR_INDEX_FC2] & FC2_SRC_MODE_MASK) == FC2_SRC_MODE_EXTENDED) {
if (!isCoordExtendedAddress(mhr + offset))
return FALSE;
}
if (fcf1 & FC1_SECURITY_ENABLED)
return FAIL; // not supported
idCompression = (fcf1 & FC1_PAN_ID_COMPRESSION);
- if (fcf2 & 0x08){ // short or ext. address
+ if (fcf2 & 0x08) { // short or ext. address
offset += 4; // pan id + short address
if (fcf2 & 0x04) // ext. address
offset += 6; // diff to short address
}
- if (fcf2 & 0x80){ // short or ext. address
+ if (fcf2 & 0x80) { // short or ext. address
offset += 2;
if (!idCompression)
offset += 2;
if ((mhr[MHR_INDEX_FC2] & FC2_SRC_MODE_MASK) == FC2_SRC_MODE_SHORT)
address->shortAddress = *((nxle_uint16_t*) (&(mhr[offset])));
else
- call FrameUtility.convertToNative(&address->extendedAddress, (&(mhr[offset]) ));
+ call FrameUtility.convertToNative(&address->extendedAddress, (&(mhr[offset])));
return SUCCESS;
}
command bool Frame.hasStandardCompliantHeader(message_t* frame)
{
uint8_t *mhr = MHR(frame);
- if ( ((mhr[0] & FC1_FRAMETYPE_MASK) > 0x03) ||
+ if (((mhr[0] & FC1_FRAMETYPE_MASK) > 0x03) ||
((mhr[MHR_INDEX_FC2] & FC2_DEST_MODE_MASK) == 0x04) ||
((mhr[MHR_INDEX_FC2] & FC2_SRC_MODE_MASK) == 0x40) ||
#ifndef IEEE154_SECURITY_ENABLED
((mhr[0] & FC1_SECURITY_ENABLED)) ||
#endif
- (mhr[MHR_INDEX_FC2] & FC2_FRAME_VERSION_2)
- )
+ (mhr[MHR_INDEX_FC2] & FC2_FRAME_VERSION_2))
return FALSE;
else
return TRUE;
}
-/* ----------------------- Beacon Frame Access ----------------------- */
+ /* ----------------------- Beacon Frame Access ----------------------- */
uint8_t getPendAddrSpecOffset(uint8_t *macPayloadField)
{
uint8_t pendAddrSpec = payload[pendAddrSpecOffset], i;
if (((mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK) != FC1_FRAMETYPE_BEACON))
return FAIL;
- if (addrMode == ADDR_MODE_SHORT_ADDRESS){
+ if (addrMode == ADDR_MODE_SHORT_ADDRESS) {
for (i=0; i<(pendAddrSpec & PENDING_ADDRESS_SHORT_MASK) && i<bufferSize; i++)
buffer[i].shortAddress = *((nxle_uint16_t*) (payload + pendAddrSpecOffset + 1 + 2*i));
return SUCCESS;
- } else if (addrMode == ADDR_MODE_EXTENDED_ADDRESS){
+ } else if (addrMode == ADDR_MODE_EXTENDED_ADDRESS) {
for (i=0; i<((pendAddrSpec & PENDING_ADDRESS_EXT_MASK) >> 4) && i<bufferSize; i++)
call FrameUtility.convertToNative(&(buffer[i].extendedAddress),
((payload + pendAddrSpecOffset +
{
uint8_t *mhr = MHR(frame);
uint8_t *payload = (uint8_t *) frame->data;
- if ((mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_BEACON){
+ if ((mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_BEACON) {
uint8_t pendAddrSpecOffset = getPendAddrSpecOffset(payload);
uint8_t pendAddrSpec = payload[pendAddrSpecOffset];
payload += (pendAddrSpecOffset + 1);
{
uint8_t *mhr = MHR(frame);
uint8_t len = ((ieee154_header_t*) frame->header)->length & FRAMECTL_LENGTH_MASK;
- if ((mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_BEACON){
+ if ((mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_BEACON) {
uint8_t *payload = call Frame.getPayload(frame);
len = len - (payload - (uint8_t *) frame->data);
}
message_t *frame,
uint8_t LogicalChannel,
uint8_t ChannelPage,
- ieee154_PANDescriptor_t *PANDescriptor
- )
+ ieee154_PANDescriptor_t *PANDescriptor)
{
uint8_t *mhr = MHR(frame);
uint8_t offset;
ieee154_metadata_t *metadata = (ieee154_metadata_t*) frame->metadata;
- if ( (mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK) != FC1_FRAMETYPE_BEACON ||
+ if ((mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK) != FC1_FRAMETYPE_BEACON ||
(((mhr[MHR_INDEX_FC2] & FC2_SRC_MODE_MASK) != FC2_SRC_MODE_SHORT) &&
- ((mhr[MHR_INDEX_FC2] & FC2_SRC_MODE_MASK) != FC2_SRC_MODE_EXTENDED)) )
+ ((mhr[MHR_INDEX_FC2] & FC2_SRC_MODE_MASK) != FC2_SRC_MODE_EXTENDED)))
return FAIL;
+
PANDescriptor->CoordAddrMode = (mhr[MHR_INDEX_FC2] & FC2_SRC_MODE_MASK) >> FC2_SRC_MODE_OFFSET;
offset = MHR_INDEX_ADDRESS;
PANDescriptor->CoordPANId = *((nxle_uint16_t*) &mhr[offset]);
offset += sizeof(ieee154_macPANId_t);
+
if ((mhr[MHR_INDEX_FC2] & FC2_SRC_MODE_MASK) == FC2_SRC_MODE_SHORT)
PANDescriptor->CoordAddress.shortAddress = *((nxle_uint16_t*) &mhr[offset]);
else
call FrameUtility.convertToNative(&PANDescriptor->CoordAddress.extendedAddress, &mhr[offset]);
+
PANDescriptor->LogicalChannel = LogicalChannel;
PANDescriptor->ChannelPage = ChannelPage;
((uint8_t*) &PANDescriptor->SuperframeSpec)[0] = frame->data[BEACON_INDEX_SF_SPEC1]; // little endian
PANDescriptor->KeySource = 0;
PANDescriptor->KeyIndex = 0;
#else
-#error Implementation of BeaconFrame.parsePANDescriptor() needs adaptation !
+#error Implementation of BeaconFrame.parsePANDescriptor() needs to be adapted!
#endif
return SUCCESS;
}
-/* ----------------------- FrameUtility, etc. ----------------------- */
+ /* ----------------------- FrameUtility, etc. ----------------------- */
command uint64_t GetLocalExtendedAddress.get()
{
{
uint8_t i;
uint64_t srcCopy = *src;
- for (i=0; i<8; i++){
+ for (i=0; i<8; i++) {
destLE[i] = srcCopy;
srcCopy >>= 8;
}
return dest == m_pib.macCoordExtendedAddress;
}
- async command bool IsBeaconEnabledPAN.getNow()
- {
- return (m_panType == BEACON_ENABLED_PAN);
- }
-
- default event void PIBUpdate.notify[uint8_t PIBAttributeID](const void* PIBAttributeValue){}
- command error_t PIBUpdate.enable[uint8_t PIBAttributeID](){return FAIL;}
- command error_t PIBUpdate.disable[uint8_t PIBAttributeID](){return FAIL;}
+ default event void PIBUpdate.notify[uint8_t PIBAttributeID](const void* PIBAttributeValue) {}
+ command error_t PIBUpdate.enable[uint8_t PIBAttributeID]() {return FAIL;}
+ command error_t PIBUpdate.disable[uint8_t PIBAttributeID]() {return FAIL;}
}
interface FrameUtility;
interface Pool<ieee154_txframe_t> as TxFramePool;
interface Pool<ieee154_txcontrol_t> as TxControlPool;
- interface Ieee802154Debug as Debug;
interface MLME_GET;
interface Get<uint64_t> as LocalExtendedAddress;
}
uint8_t coordAddrMode,
uint16_t coordPANID,
ieee154_address_t coordAddress,
- ieee154_security_t *security
- )
+ ieee154_security_t *security)
{
ieee154_txframe_t *txFrame;
ieee154_txcontrol_t *txControl;
uint8_t srcAddrMode = 2;
- ieee154_status_t txStatus = IEEE154_SUCCESS;
+ ieee154_status_t status = IEEE154_SUCCESS;
uint8_t coordAddressLE[8]; // little endian is what we want
if (security && security->SecurityLevel)
- txStatus = IEEE154_UNSUPPORTED_SECURITY;
+ status = IEEE154_UNSUPPORTED_SECURITY;
else if (coordAddrMode < 2 || coordAddrMode > 3 || coordPANID == 0xFFFF)
- txStatus = IEEE154_INVALID_PARAMETER;
+ status = IEEE154_INVALID_PARAMETER;
else if (!(txFrame = call TxFramePool.get()))
// none of the predefined return value really fits
- txStatus = IEEE154_TRANSACTION_OVERFLOW;
- else if (!(txControl = call TxControlPool.get())){
+ status = IEEE154_TRANSACTION_OVERFLOW;
+ else if (!(txControl = call TxControlPool.get())) {
call TxFramePool.put(txFrame);
- txStatus = IEEE154_TRANSACTION_OVERFLOW;
+ status = IEEE154_TRANSACTION_OVERFLOW;
} else {
txFrame->header = &txControl->header;
txFrame->metadata = &txControl->metadata;
if (call MLME_GET.macShortAddress() >= 0xFFFE)
srcAddrMode = 3;
buildDataRequestFrame(coordAddrMode, coordPANID, coordAddressLE, srcAddrMode, txFrame);
- if ((txStatus = call PollTx.transmit(txFrame)) != IEEE154_SUCCESS){
+ if ((status = call PollTx.transmit(txFrame)) != IEEE154_SUCCESS) {
call TxFramePool.put(txFrame);
call TxControlPool.put(txControl);
- call Debug.log(DEBUG_LEVEL_IMPORTANT, PollP_ALLOC_FAIL1, 0, 0, 0);
+ status = IEEE154_TRANSACTION_OVERFLOW;
} else
m_numPending++;
}
- return txStatus;
+
+ dbg_serial("PollP", "MLME_POLL.request -> result: %lu\n", (uint32_t) status);
+ return status;
}
command ieee154_status_t DataRequest.poll[uint8_t client](uint8_t CoordAddrMode,
ieee154_txframe_t *txFrame;
ieee154_txcontrol_t *txControl;
ieee154_status_t status = IEEE154_TRANSACTION_OVERFLOW;
- call Debug.log(DEBUG_LEVEL_INFO, PollP_INTERNAL_POLL, CoordAddrMode, client, m_numPending);
- if (client == SYNC_POLL_CLIENT && m_numPending != 0){
+
+ dbg_serial("PollP", "InternalPoll\n");
+ if (client == SYNC_POLL_CLIENT && m_numPending != 0) {
// no point in auto-requesting if user request is pending
signal DataRequest.pollDone[client]();
return IEEE154_SUCCESS;
- } else if ((txFrame = call TxFramePool.get())){
+ } else if ((txFrame = call TxFramePool.get())) {
if (!(txControl = call TxControlPool.get()))
call TxFramePool.put(txFrame);
else {
txFrame->handle = client;
buildDataRequestFrame(CoordAddrMode, CoordPANId,
CoordAddressLE, srcAddrMode, txFrame);
- if ((status = call PollTx.transmit(txFrame)) != IEEE154_SUCCESS){
+ if ((status = call PollTx.transmit(txFrame)) != IEEE154_SUCCESS) {
call TxControlPool.put(txControl);
call TxFramePool.put(txFrame);
- call Debug.log(DEBUG_LEVEL_IMPORTANT, PollP_ALLOC_FAIL2, 0, 0, 0);
+ dbg_serial("PollP", "Overflow\n");
} else
m_numPending++;
}
event message_t* DataExtracted.received(message_t* frame, ieee154_txframe_t *txFrame)
{
- if (!txFrame){
- call Debug.log(DEBUG_LEVEL_CRITICAL, PollP_INTERNAL_ERROR, 0, 0, 0);
+ if (!txFrame) {
+ dbg_serial("PollP", "Internal error\n");
return frame;
} else
- call Debug.log(DEBUG_LEVEL_INFO, PollP_SUCCESS, 0, 0, 0);
+ dbg_serial("PollP", "Extracted data successfully\n");
if (txFrame->handle == HANDLE_MLME_POLL_REQUEST)
signal MLME_POLL.confirm(IEEE154_SUCCESS);
else
signal DataRequest.pollDone[txFrame->handle]();
txFrame->handle = HANDLE_MLME_POLL_SUCCESS; // mark as processed
// TODO: check if pending bit is set (then initiate another POLL)
- call Debug.log(DEBUG_LEVEL_IMPORTANT, PollP_RX, txFrame->handle, 0, 0);
return signal DataRx.received(frame);
}
event void PollTx.transmitDone(ieee154_txframe_t *txFrame, ieee154_status_t status)
{
- call Debug.log(DEBUG_LEVEL_IMPORTANT, PollP_TXDONE, status, txFrame->handle, 0);
+ dbg_serial("PollP", "transmitDone()\n");
m_numPending--;
- if (txFrame->handle != HANDLE_MLME_POLL_SUCCESS){
+ if (txFrame->handle != HANDLE_MLME_POLL_SUCCESS) {
// didn't receive a DATA frame from the coordinator
if (status == IEEE154_SUCCESS) // TODO: can this happen if a frame other than DATA was extracted?
status = IEEE154_NO_DATA;
call TxControlPool.put((ieee154_txcontrol_t*) ((uint8_t*) txFrame->header - offsetof(ieee154_txcontrol_t, header)));
call TxFramePool.put(txFrame);
}
- default event void MLME_POLL.confirm(ieee154_status_t status){}
- default event void DataRequest.pollDone[uint8_t client](){}
+ default event void MLME_POLL.confirm(ieee154_status_t status) {}
+ default event void DataRequest.pollDone[uint8_t client]() {}
}
interface RadioRx as PromiscuousRx;
interface RadioOff;
interface Set<bool> as RadioPromiscuousMode;
- interface Ieee802154Debug as Debug;
}
}
implementation
{
- enum promiscuous_state {
- S_IDLE,
+ norace enum promiscuous_state {
+ S_STOPPING,
+ S_STOPPED,
S_STARTING,
S_STARTED,
- S_STOPPING,
- } m_promiscuousState;
-
- task void prepareDoneTask();
- task void radioOffDoneTask();
+ } m_state;
command error_t Init.init()
{
- m_promiscuousState = S_IDLE;
+ m_state = S_STOPPED;
return SUCCESS;
}
-/* ----------------------- Promiscuous Mode ----------------------- */
+ /* ----------------------- Promiscuous Mode ----------------------- */
command bool PromiscuousModeGet.get()
{
- return (m_promiscuousState == S_STARTED);
+ return (m_state == S_STARTED);
}
command error_t PromiscuousMode.start()
{
- if (m_promiscuousState != S_IDLE)
- return FAIL;
- m_promiscuousState = S_STARTING;
- call Token.request();
- call Debug.log(DEBUG_LEVEL_INFO, EnableRxP_PROMISCUOUS_REQUEST, m_promiscuousState, 0, 0);
- call Debug.flush();
- return SUCCESS;
+ error_t result = FAIL;
+ if (m_state == S_STOPPED) {
+ m_state = S_STARTING;
+ call Token.request();
+ result = SUCCESS;
+ }
+ dbg_serial("PromiscuousModeP", "PromiscuousMode.start -> result: %lu\n", (uint32_t) result);
+ return result;
}
event void Token.granted()
{
- if (m_promiscuousState != S_STARTING){
- call Token.release();
- return;
- }
call RadioPromiscuousMode.set(TRUE);
- if (call PromiscuousRx.prepare() != IEEE154_SUCCESS){
- m_promiscuousState = S_IDLE;
- call Token.release();
- call Debug.log(DEBUG_LEVEL_IMPORTANT, EnableRxP_RADIORX_ERROR, 0, 0, 0);
- signal PromiscuousMode.startDone(FAIL);
- }
+ if (call RadioOff.isOff())
+ signal RadioOff.offDone();
+ else
+ call RadioOff.off();
}
- async event void PromiscuousRx.prepareDone()
+ task void signalStartDoneTask()
{
- post prepareDoneTask();
+ m_state = S_STARTED;
+ dbg_serial("PromiscuousModeP", "Promiscuous mode enabled.\n");
+ signal PromiscuousMode.startDone(SUCCESS);
}
- task void prepareDoneTask()
+ async event void PromiscuousRx.enableRxDone()
{
- if (m_promiscuousState != S_STARTING){
- call Token.release();
- return;
- }
- m_promiscuousState = S_STARTED;
- call PromiscuousRx.receive(NULL, 0);
- signal PromiscuousMode.startDone(SUCCESS);
- call Debug.log(DEBUG_LEVEL_INFO, EnableRxP_PROMISCUOUS_ON, m_promiscuousState, 0, 0);
+ post signalStartDoneTask();
}
- event message_t* PromiscuousRx.received(message_t *frame, ieee154_reftime_t *timestamp)
+ event message_t* PromiscuousRx.received(message_t *frame, const ieee154_timestamp_t *timestamp)
{
- if (m_promiscuousState == S_STARTED){
+ if (m_state == S_STARTED) {
((ieee154_header_t*) frame->header)->length |= FRAMECTL_PROMISCUOUS;
return signal FrameRx.received(frame);
} else
command error_t PromiscuousMode.stop()
{
- if (m_promiscuousState != S_STARTED)
- return FAIL;
- m_promiscuousState = S_STOPPING;
- call RadioOff.off();
- return SUCCESS;
- }
-
- async event void RadioOff.offDone()
- {
- post radioOffDoneTask();
+ error_t result = FAIL;
+ if (m_state == S_STARTED) {
+ m_state = S_STOPPING;
+ call RadioOff.off();
+ result = SUCCESS;
+ }
+ dbg_serial("PromiscuousModeP", "PromiscuousMode.stop -> result: %lu\n", (uint32_t) result);
+ return result;
}
- task void radioOffDoneTask()
+ task void continueStopTask()
{
- if (m_promiscuousState != S_STOPPING){
- call Token.release();
- return;
- }
- m_promiscuousState = S_IDLE;
call RadioPromiscuousMode.set(FALSE);
+ m_state = S_STOPPED;
call Token.release();
+ dbg_serial("PromiscuousModeP", "Promiscuous mode disabled.\n");
signal PromiscuousMode.stopDone(SUCCESS);
- call Debug.log(DEBUG_LEVEL_INFO, EnableRxP_PROMISCUOUS_OFF, m_promiscuousState, 0, 0);
}
- default event void PromiscuousMode.startDone(error_t error){}
- default event void PromiscuousMode.stopDone(error_t error){}
+ async event void RadioOff.offDone()
+ {
+ if (m_state == S_STARTING) {
+ call PromiscuousRx.enableRx(0, 0);
+ } else
+ post continueStopTask();
+ }
+
+ default event void PromiscuousMode.startDone(error_t error) {}
+ default event void PromiscuousMode.stopDone(error_t error) {}
}
This directory contains "TKN15.4", a platform-independent IEEE 802.15.4-2006
-MAC implementation. The code is in alpha state, under active development, but
-most of the functionality described in the standard is implemented (and
-cursorily tested). The MAC itself is platform-independent, but it requires
-(1) a suitable radio driver, (2) Alarms/Timers with symbol precision and (3)
-some "platform glue" code (defining guard times, etc.). Currently the only
-supported platform is TelosB (however: without additional hardware support on
-TelosB the timing in beacon-enabled mode is not standard compliant).
+MAC implementation. The code is under active development, but most of the
+functionality described in the standard is implemented (and cursorily tested).
+The MAC itself is platform-independent, but it requires (1) a suitable radio
+driver, (2) Alarms/Timers with symbol precision and (3) some "platform glue"
+code (defining guard times, etc.). Currently the only supported platform is
+TelosB (but without additional hardware support on TelosB the timing in
+beacon-enabled mode is not standard compliant).
-Status 6/16/08
---------------
+This code is the basis for the implementation of the TinyOS 15.4 WG:
+http://tinyos.stanford.edu:8000/15.4_WG
+
+Status 3/4/09
+-------------
Missing functionality:
-- security (not planned)
-- GTS (not planned)
+- security
+- GTS
- PAN ID conflict resolution
- multiple indirect transmissions to the same destination
* @author Jan Hauer <hauer@tkn.tu-berlin.de>
* ========================================================================
*/
+
#include "TKN154_MAC.h"
generic configuration RadioClientC()
{
provides
{
+ interface RadioOff;
interface RadioRx;
interface RadioTx;
- interface RadioOff;
+ interface SlottedCsmaCa;
+ interface UnslottedCsmaCa;
interface Resource as Token;
interface ResourceRequested as TokenRequested;
interface ResourceTransfer;
RadioRx = RadioControlP.RadioRx[CLIENT];
RadioTx = RadioControlP.RadioTx[CLIENT];
RadioOff = RadioControlP.RadioOff[CLIENT];
+ SlottedCsmaCa = RadioControlP.SlottedCsmaCa[CLIENT];
+ UnslottedCsmaCa = RadioControlP.UnslottedCsmaCa[CLIENT];
Token = RadioControlP.Token[CLIENT];
IsResourceRequested = RadioControlP.IsResourceRequested;
TokenRequested = RadioControlP.TokenRequested[CLIENT];
* @author Jan Hauer <hauer@tkn.tu-berlin.de>
* ========================================================================
*/
+
#include "TKN154_MAC.h"
-#include "TKN154_DEBUG.h"
+
module RadioControlImplP
{
provides
{
interface RadioRx as MacRx[uint8_t client];
interface RadioTx as MacTx[uint8_t client];
+ interface SlottedCsmaCa as SlottedCsmaCa[uint8_t client];
+ interface UnslottedCsmaCa as UnslottedCsmaCa[uint8_t client];
interface RadioOff as MacRadioOff[uint8_t client];
} uses {
interface ArbiterInfo;
interface RadioRx as PhyRx;
interface RadioTx as PhyTx;
+ interface SlottedCsmaCa as PhySlottedCsmaCa;
+ interface UnslottedCsmaCa as PhyUnslottedCsmaCa;
interface RadioOff as PhyRadioOff;
interface Get<bool> as RadioPromiscuousMode;
interface Leds;
- interface Ieee802154Debug as Debug;
}
}
implementation
{
-/* ----------------------- RadioRx ----------------------- */
-
- async command error_t MacRx.prepare[uint8_t client]()
- {
- if (client == call ArbiterInfo.userId())
- return call PhyRx.prepare();
- else {
- call Leds.led0On();
- return FAIL;
- }
- }
-
- async event void PhyRx.prepareDone()
- {
- signal MacRx.prepareDone[call ArbiterInfo.userId()]();
- }
-
- async command bool MacRx.isPrepared[uint8_t client]()
- {
- if (client == call ArbiterInfo.userId())
- return call PhyRx.isPrepared();
- else {
- call Leds.led0On();
- return FAIL;
- }
- }
+ /* ----------------------- RadioRx ----------------------- */
- async command error_t MacRx.receive[uint8_t client](ieee154_reftime_t *t0, uint32_t dt)
+ async command error_t MacRx.enableRx[uint8_t client](uint32_t t0, uint32_t dt)
{
if (client == call ArbiterInfo.userId())
- return call PhyRx.receive(t0, dt);
+ return call PhyRx.enableRx(t0, dt);
else {
- call Leds.led0On();
+ ASSERT(0);
return IEEE154_TRANSACTION_OVERFLOW;
}
}
- event message_t* PhyRx.received(message_t *msg, ieee154_reftime_t *timestamp)
+ async event void PhyRx.enableRxDone()
+ {
+ signal MacRx.enableRxDone[call ArbiterInfo.userId()]();
+ }
+
+ event message_t* PhyRx.received(message_t *msg, const ieee154_timestamp_t *timestamp)
{
uint8_t *mhr = MHR(msg);
if (((mhr[1] & FC2_FRAME_VERSION_MASK) > FC2_FRAME_VERSION_1)
if (client == call ArbiterInfo.userId())
return call PhyRx.isReceiving();
else {
- call Leds.led0On();
+ ASSERT(0);
return FAIL;
}
}
-/* ----------------------- RadioTx ----------------------- */
+ default async event void MacRx.enableRxDone[uint8_t client]() { ASSERT(0); }
- async command error_t MacTx.load[uint8_t client](ieee154_txframe_t *frame)
+ default event message_t* MacRx.received[uint8_t client](message_t *frame, const ieee154_timestamp_t *timestamp)
+ {
+ ASSERT(0);
+ return frame;
+ }
+
+ /* ----------------------- RadioTx ----------------------- */
+
+ async command error_t MacTx.transmit[uint8_t client](ieee154_txframe_t *frame,
+ const ieee154_timestamp_t *t0, uint32_t dt)
{
if (client == call ArbiterInfo.userId())
- return call PhyTx.load(frame);
+ return call PhyTx.transmit(frame, t0, dt);
else {
- call Leds.led0On();
+ ASSERT(0);
return IEEE154_TRANSACTION_OVERFLOW;
}
}
-
- async event void PhyTx.loadDone()
+
+ async event void PhyTx.transmitDone(ieee154_txframe_t *frame,
+ const ieee154_timestamp_t *timestamp, error_t result)
{
- signal MacTx.loadDone[call ArbiterInfo.userId()]();
+ signal MacTx.transmitDone[call ArbiterInfo.userId()](frame, timestamp, result);
}
- async command ieee154_txframe_t* MacTx.getLoadedFrame[uint8_t client]()
+ default async event void MacTx.transmitDone[uint8_t client](ieee154_txframe_t *frame,
+ const ieee154_timestamp_t *timestamp, error_t result)
{
- if (client == call ArbiterInfo.userId())
- return call PhyTx.getLoadedFrame();
- else {
- call Leds.led0On();
- return NULL;
- }
+ ASSERT(0);
}
- async command error_t MacTx.transmit[uint8_t client](ieee154_reftime_t *t0, uint32_t dt)
+ /* ----------------------- Unslotted CSMA ----------------------- */
+
+ async command error_t UnslottedCsmaCa.transmit[uint8_t client](ieee154_txframe_t *frame, ieee154_csma_t *csma)
{
if (client == call ArbiterInfo.userId())
- return call PhyTx.transmit(t0, dt);
+ return call PhyUnslottedCsmaCa.transmit(frame, csma);
else {
- call Leds.led0On();
+ ASSERT(0);
return IEEE154_TRANSACTION_OVERFLOW;
}
}
-
- async event void PhyTx.transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime)
- {
- signal MacTx.transmitDone[call ArbiterInfo.userId()](frame, txTime);
- }
- async command error_t MacTx.transmitUnslottedCsmaCa[uint8_t client](ieee154_csma_t *csmaParams)
+ async event void PhyUnslottedCsmaCa.transmitDone(ieee154_txframe_t *frame, ieee154_csma_t *csma, bool ackPendingFlag, error_t result)
{
- if (client == call ArbiterInfo.userId())
- return call PhyTx.transmitUnslottedCsmaCa(csmaParams);
- else {
- call Leds.led0On();
- return IEEE154_TRANSACTION_OVERFLOW;
- }
+ signal UnslottedCsmaCa.transmitDone[call ArbiterInfo.userId()](
+ frame, csma, ackPendingFlag, result);
}
- async event void PhyTx.transmitUnslottedCsmaCaDone(ieee154_txframe_t *frame,
- bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result)
+ default async event void UnslottedCsmaCa.transmitDone[uint8_t client](
+ ieee154_txframe_t *frame, ieee154_csma_t *csma, bool ackPendingFlag, error_t result)
{
- signal MacTx.transmitUnslottedCsmaCaDone[call ArbiterInfo.userId()](
- frame, ackPendingFlag, csmaParams, result);
+ ASSERT(0);
}
- async command error_t MacTx.transmitSlottedCsmaCa[uint8_t client](ieee154_reftime_t *slot0Time, uint32_t dtMax,
- bool resume, uint16_t remainingBackoff, ieee154_csma_t *csmaParams)
+ /* ----------------------- Slotted CSMA ----------------------- */
+
+ async command error_t SlottedCsmaCa.transmit[uint8_t client](ieee154_txframe_t *frame, ieee154_csma_t *csma,
+ const ieee154_timestamp_t *slot0Time, uint32_t dtMax, bool resume, uint16_t remainingBackoff)
{
if (client == call ArbiterInfo.userId())
- return call PhyTx.transmitSlottedCsmaCa(slot0Time, dtMax, resume, remainingBackoff, csmaParams);
+ return call PhySlottedCsmaCa.transmit(frame, csma, slot0Time, dtMax, resume, remainingBackoff);
else {
- call Leds.led0On();
+ ASSERT(0);
return IEEE154_TRANSACTION_OVERFLOW;
}
}
- async event void PhyTx.transmitSlottedCsmaCaDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime,
- bool ackPendingFlag, uint16_t remainingBackoff, ieee154_csma_t *csmaParams, error_t result)
+ async event void PhySlottedCsmaCa.transmitDone(ieee154_txframe_t *frame, ieee154_csma_t *csma,
+ bool ackPendingFlag, uint16_t remainingBackoff, error_t result)
+ {
+ signal SlottedCsmaCa.transmitDone[call ArbiterInfo.userId()](
+ frame, csma, ackPendingFlag, remainingBackoff, result);
+ }
+
+ default async event void SlottedCsmaCa.transmitDone[uint8_t client](
+ ieee154_txframe_t *frame, ieee154_csma_t *csma,
+ bool ackPendingFlag, uint16_t remainingBackoff, error_t result)
{
- signal MacTx.transmitSlottedCsmaCaDone[call ArbiterInfo.userId()](
- frame, txTime, ackPendingFlag, remainingBackoff, csmaParams, result);
+ ASSERT(0);
}
-/* ----------------------- RadioOff ----------------------- */
+ /* ----------------------- RadioOff ----------------------- */
async command error_t MacRadioOff.off[uint8_t client]()
{
if (client == call ArbiterInfo.userId())
return call PhyRadioOff.off();
else {
- call Leds.led0On();
+ ASSERT(0);
return EBUSY;
}
}
return EBUSY;
}
-/* ----------------------- Defaults ----------------------- */
-
- default async event void MacTx.loadDone[uint8_t client]()
- {
- call Debug.log(DEBUG_LEVEL_CRITICAL, 0, 0, 0, 0);
- }
- default async event void MacTx.transmitDone[uint8_t client](ieee154_txframe_t *frame, ieee154_reftime_t *txTime)
- {
- call Debug.log(DEBUG_LEVEL_CRITICAL, 1, 0, 0, 0);
- }
- default async event void MacRx.prepareDone[uint8_t client]()
- {
- call Debug.log(DEBUG_LEVEL_CRITICAL, 2, 0, 0, 0);
- }
- default event message_t* MacRx.received[uint8_t client](message_t *frame, ieee154_reftime_t *timestamp)
- {
- call Debug.log(DEBUG_LEVEL_IMPORTANT, 3, client, call ArbiterInfo.userId(), 0xff);
- return frame;
- }
default async event void MacRadioOff.offDone[uint8_t client]()
{
- call Debug.log(DEBUG_LEVEL_CRITICAL, 4, 0, 0, 0);
- }
- default async event void MacTx.transmitUnslottedCsmaCaDone[uint8_t client](ieee154_txframe_t *frame,
- bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result)
- {
- call Debug.log(DEBUG_LEVEL_CRITICAL, 5, 0, 0, 0);
- }
- default async event void MacTx.transmitSlottedCsmaCaDone[uint8_t client](ieee154_txframe_t *frame,
- ieee154_reftime_t *txTime, bool ackPendingFlag, uint16_t remainingBackoff,
- ieee154_csma_t *csmaParams, error_t result)
- {
- call Debug.log(DEBUG_LEVEL_CRITICAL, 6, 0, 0, 0);
+ ASSERT(0);
}
}
{
interface RadioRx as RadioRx[uint8_t client];
interface RadioTx as RadioTx[uint8_t client];
+ interface SlottedCsmaCa as SlottedCsmaCa[uint8_t client];
+ interface UnslottedCsmaCa as UnslottedCsmaCa[uint8_t client];
interface RadioOff as RadioOff[uint8_t client];
interface Resource as Token[uint8_t client];
interface ResourceRequested as TokenRequested[uint8_t client];
} uses {
interface RadioRx as PhyRx;
interface RadioTx as PhyTx;
+ interface SlottedCsmaCa as PhySlottedCsmaCa;
+ interface UnslottedCsmaCa as PhyUnslottedCsmaCa;
interface RadioOff as PhyRadioOff;
interface Get<bool> as RadioPromiscuousMode;
interface Leds;
- interface Ieee802154Debug as Debug;
}
}
implementation
components RadioControlImplP;
RadioRx = RadioControlImplP.MacRx;
RadioTx = RadioControlImplP.MacTx;
+ SlottedCsmaCa = RadioControlImplP.SlottedCsmaCa;
+ UnslottedCsmaCa = RadioControlImplP.UnslottedCsmaCa;
RadioOff = RadioControlImplP.MacRadioOff;
PhyRx = RadioControlImplP.PhyRx;
PhyTx = RadioControlImplP.PhyTx;
+ PhySlottedCsmaCa = RadioControlImplP.PhySlottedCsmaCa;
+ PhyUnslottedCsmaCa = RadioControlImplP.PhyUnslottedCsmaCa;
PhyRadioOff = RadioControlImplP.PhyRadioOff;
RadioPromiscuousMode = RadioControlImplP;
Leds = RadioControlImplP;
- Debug = RadioControlImplP;
LedsRadioClient = Leds;
components new SimpleRoundRobinTransferArbiterC(IEEE802154_RADIO_RESOURCE) as Arbiter;
{
provides
{
- interface Init;
+ interface Init as Reset;
interface MLME_RX_ENABLE;
interface GetNow<bool> as IsRxEnableActive;
interface Notify<bool> as RxEnableStateChange;
}
uses
{
- interface Ieee802154Debug as Debug;
interface Timer<TSymbolIEEE802154> as RxEnableTimer;
- interface GetNow<bool> as IsBeaconEnabledPAN;
interface Get<ieee154_macPanCoordinator_t> as IsMacPanCoordinator;
+ interface SuperframeStructure as IncomingSuperframeStructure;
+ interface SuperframeStructure as OutgoingSuperframeStructure;
interface GetNow<bool> as IsTrackingBeacons;
- interface GetNow<uint32_t> as IncomingSfStart;
- interface GetNow<uint32_t> as IncomingBeaconInterval;
interface GetNow<bool> as IsSendingBeacons;
- interface GetNow<uint32_t> as OutgoingSfStart;
- interface GetNow<uint32_t> as OutgoingBeaconInterval;
interface Notify<bool> as WasRxEnabled;
interface TimeCalc;
}
uint32_t m_rxOnOffset;
uint32_t m_rxOnAnchor;
norace bool m_isRxEnabled;
- bool m_isRxEnableConfirmPending;
+ bool m_confirmPending;
- command error_t Init.init()
+ command error_t Reset.init()
{
- if (m_isRxEnableConfirmPending){
- m_isRxEnableConfirmPending = FALSE;
+ if (m_confirmPending) {
+ m_confirmPending = FALSE;
signal MLME_RX_ENABLE.confirm(IEEE154_SUCCESS);
}
m_isRxEnabled = FALSE;
return SUCCESS;
}
-/* ----------------------- MLME-RX-ENABLE ----------------------- */
+ /* ----------------------- MLME-RX-ENABLE ----------------------- */
command ieee154_status_t MLME_RX_ENABLE.request (
bool DeferPermit,
uint32_t RxOnTime,
- uint32_t RxOnDuration
- )
+ uint32_t RxOnDuration)
{
+ ieee154_status_t status = IEEE154_SUCCESS;
uint32_t lastBeaconTime=0;
uint32_t beaconInterval=0;
- if (m_isRxEnableConfirmPending)
- return IEEE154_TRANSACTION_OVERFLOW;
- if (RxOnTime > 0xFFFFFF || RxOnDuration > 0xFFFFFF)
- return IEEE154_INVALID_PARAMETER;
- if (call IsBeaconEnabledPAN.getNow()){
- if (call IsSendingBeacons.getNow() && call IsMacPanCoordinator.get()){
+ if (m_confirmPending)
+ status = IEEE154_TRANSACTION_OVERFLOW;
+ else if (IEEE154_BEACON_ENABLED_PAN && RxOnTime > 0xFFFFFF)
+ status = IEEE154_INVALID_PARAMETER;
+ else if (RxOnDuration > 0xFFFFFF)
+ status = IEEE154_INVALID_PARAMETER;
+ else if (IEEE154_BEACON_ENABLED_PAN) {
+ if (call IsSendingBeacons.getNow() && call IsMacPanCoordinator.get()) {
// for OUTGOING SUPERFRAME
- lastBeaconTime = call OutgoingSfStart.getNow();
- beaconInterval = call OutgoingBeaconInterval.getNow();
- } else if (call IsTrackingBeacons.getNow()){
+ lastBeaconTime = call OutgoingSuperframeStructure.sfStartTime();
+ beaconInterval = call OutgoingSuperframeStructure.sfSlotDuration() * 16;
+ } else if (call IsTrackingBeacons.getNow()) {
// for INCOMING SUPERFRAME
- lastBeaconTime = call IncomingSfStart.getNow();
- beaconInterval = call IncomingBeaconInterval.getNow();
+ lastBeaconTime = call IncomingSuperframeStructure.sfStartTime();
+ beaconInterval = call IncomingSuperframeStructure.sfSlotDuration() * 16;
}
if (beaconInterval == 0)
- return IEEE154_PAST_TIME; // we're not even sending/receiving beacons
- if (RxOnTime+RxOnDuration >= beaconInterval)
- return IEEE154_ON_TIME_TOO_LONG;
- if (call TimeCalc.hasExpired(lastBeaconTime, RxOnTime - IEEE154_aTurnaroundTime)){
+ status = IEEE154_PAST_TIME; // we're not even sending/receiving beacons
+ else if (RxOnTime+RxOnDuration >= beaconInterval)
+ status = IEEE154_ON_TIME_TOO_LONG;
+ else if (call TimeCalc.hasExpired(lastBeaconTime, RxOnTime - IEEE154_aTurnaroundTime)) {
if (!DeferPermit)
- return IEEE154_PAST_TIME;
+ status = IEEE154_PAST_TIME;
else {
// defer to next beacon
RxOnTime += beaconInterval;
}
}
- m_rxOnAnchor = lastBeaconTime;
- m_rxOnOffset = RxOnTime;
+ if (status == IEEE154_SUCCESS) {
+ m_rxOnAnchor = lastBeaconTime;
+ m_rxOnOffset = RxOnTime;
+ }
} else {
+ // this is a nonbeacon-enabled PAN
m_rxOnAnchor = call RxEnableTimer.getNow();
m_rxOnOffset = 0;
}
- m_rxOnDuration = RxOnDuration;
- m_isRxEnabled = FALSE;
- m_isRxEnableConfirmPending = TRUE;
- call RxEnableTimer.startOneShotAt(m_rxOnAnchor, m_rxOnOffset);
- signal RxEnableStateChange.notify(TRUE);
- return IEEE154_SUCCESS;
+
+ if (status == IEEE154_SUCCESS) {
+ m_rxOnDuration = RxOnDuration;
+ m_isRxEnabled = FALSE;
+ m_confirmPending = TRUE;
+ call RxEnableTimer.startOneShotAt(m_rxOnAnchor, m_rxOnOffset);
+ signal RxEnableStateChange.notify(TRUE);
+ }
+ dbg_serial("RxEnableP", "MLME_RX_ENABLE.request -> result: %lu\n", (uint32_t) status);
+ return status;
}
event void RxEnableTimer.fired()
{
- if (!m_isRxEnabled){
+ if (!m_isRxEnabled) {
m_isRxEnabled = TRUE;
call RxEnableTimer.startOneShotAt(m_rxOnAnchor, m_rxOnOffset + m_rxOnDuration);
} else {
m_isRxEnabled = FALSE;
- if (m_isRxEnableConfirmPending){
- // this means we tried to enable rx, but never
- // succeeded, because there were "other
- // responsibilities" - but is SUCCESS really
+ if (m_confirmPending) {
+ // this means we tried to enable rx, but never succeeded, because
+ // there were "other responsibilities" - but is SUCCESS really
// an appropriate error code in this case?
- m_isRxEnableConfirmPending = FALSE;
+ m_confirmPending = FALSE;
+ dbg_serial("RxEnableP", "never actually managed to switch to Rx mode\n");
signal MLME_RX_ENABLE.confirm(IEEE154_SUCCESS);
}
}
return m_isRxEnabled;
}
- event void WasRxEnabled.notify( bool val )
+ event void WasRxEnabled.notify(bool val)
{
- if (m_isRxEnabled && m_isRxEnableConfirmPending){
- m_isRxEnableConfirmPending = FALSE;
+ if (m_isRxEnabled && m_confirmPending) {
+ m_confirmPending = FALSE;
+ dbg_serial("RxEnableP", "MLME_RX_ENABLE.confirm, radio is now in Rx mode\n");
signal MLME_RX_ENABLE.confirm(IEEE154_SUCCESS);
}
}
- command error_t RxEnableStateChange.enable(){return FAIL;}
- command error_t RxEnableStateChange.disable(){return FAIL;}
- default event void MLME_RX_ENABLE.confirm(ieee154_status_t status){}
+ command error_t RxEnableStateChange.enable() {return FAIL;}
+ command error_t RxEnableStateChange.disable() {return FAIL;}
+ default event void MLME_RX_ENABLE.confirm(ieee154_status_t status) {}
+ default async command uint32_t IncomingSuperframeStructure.sfStartTime() {return 0;}
+ default async command uint16_t IncomingSuperframeStructure.sfSlotDuration() {return 0;}
+ default async command uint32_t OutgoingSuperframeStructure.sfStartTime() {return 0;}
+ default async command uint16_t OutgoingSuperframeStructure.sfSlotDuration() {return 0;}
+ default async command bool IsTrackingBeacons.getNow() { return FALSE;}
+ default async command bool IsSendingBeacons.getNow() { return FALSE;}
+ default command ieee154_macPanCoordinator_t IsMacPanCoordinator.get() { return FALSE;}
}
* ========================================================================
*/
+/**
+ * This module is responsible for channel scanning.
+ */
+
#include "TKN154_MAC.h"
module ScanP
{
bool m_busy = FALSE;
void nextIteration();
+ void continueScanRequest();
task void startTimerTask();
task void nextIterationTask();
{
// triggered by MLME_RESET; remember: Init will not be called
// while this component owns the Token, so the worst case is
- // that a MLME_SCAN was accepted (returned IEEE154_SUCCESS)
- // but the Token.granted() has not been signalled
- if (m_busy){
+ // that a MLME_SCAN was accepted (returned IEEE154_SUCCESS)
+ // but the Token.granted() has not been signalled
+ if (m_busy) {
m_currentChannelNum = 27;
nextIteration(); // signals confirm and resets state
}
return SUCCESS;
}
-/* ----------------------- MLME-SCAN ----------------------- */
-/* "The MLME-SCAN.request primitive is used to initiate a channel scan over a
- * given list of channels. A device can use a channel scan to measure the
- * energy on the channel, search for the coordinator with which it associated,
- * or search for all coordinators transmitting beacon frames within the POS of
- * the scanning device." (IEEE 802.15.4-2006 Sect. 7.1.11.1)
- **/
+ /* ----------------------- MLME-SCAN ----------------------- */
+ /* "The MLME-SCAN.request primitive is used to initiate a channel scan over a
+ * given list of channels. A device can use a channel scan to measure the
+ * energy on the channel, search for the coordinator with which it associated,
+ * or search for all coordinators transmitting beacon frames within the POS of
+ * the scanning device." (IEEE 802.15.4-2006 Sect. 7.1.11.1)
+ **/
command ieee154_status_t MLME_SCAN.request (
uint8_t ScanType,
int8_t* EnergyDetectList,
uint8_t PANDescriptorListNumEntries,
ieee154_PANDescriptor_t* PANDescriptorList,
- ieee154_security_t *security
- )
+ ieee154_security_t *security)
{
ieee154_status_t status = IEEE154_SUCCESS;
ieee154_phyChannelsSupported_t supportedChannels = call MLME_GET.phyChannelsSupported();
ieee154_txcontrol_t *txControl = NULL;
- if (m_busy){
+ if (m_busy) {
status = IEEE154_SCAN_IN_PROGRESS;
- } else if (security && security->SecurityLevel){
+ } else if (security && security->SecurityLevel) {
status = IEEE154_UNSUPPORTED_SECURITY;
- } if ( (ScanType > 3) || (ScanType < 3 && ScanDuration > 14) ||
- (ChannelPage != IEEE154_SUPPORTED_CHANNELPAGE) ||
- !(supportedChannels & ScanChannels) ||
- (EnergyDetectListNumEntries && PANDescriptorListNumEntries) ||
- (EnergyDetectList != NULL && PANDescriptorList != NULL) ||
- (EnergyDetectListNumEntries && EnergyDetectList == NULL) ||
- (PANDescriptorListNumEntries && PANDescriptorList == NULL)) {
+ } if ((ScanType > 3) || (ScanType < 3 && ScanDuration > 14) ||
+ (ChannelPage != IEEE154_SUPPORTED_CHANNELPAGE) ||
+ !(supportedChannels & ScanChannels) ||
+ (EnergyDetectListNumEntries && PANDescriptorListNumEntries) ||
+ (EnergyDetectList != NULL && PANDescriptorList != NULL) ||
+ (EnergyDetectListNumEntries && EnergyDetectList == NULL) ||
+ (PANDescriptorListNumEntries && PANDescriptorList == NULL)) {
status = IEEE154_INVALID_PARAMETER;
} else if (ScanType != ENERGY_DETECTION_SCAN &&
!(m_txFrame = call TxFramePool.get())) {
m_currentChannelBit = 1;
m_currentChannelNum = 0;
m_resultIndex = 0;
- if (ScanType == ENERGY_DETECTION_SCAN){
+ if (ScanType == ENERGY_DETECTION_SCAN) {
m_resultList = EnergyDetectList;
m_resultListNumEntries = EnergyDetectListNumEntries;
} else {
m_resultListNumEntries = 0;
call Token.request();
}
+ dbg_serial("ScanP", "MLME_SCAN.request -> result: %lu\n", (uint32_t) status);
return status;
}
event void Token.granted()
+ {
+ if (call RadioOff.isOff())
+ continueScanRequest();
+ else
+ ASSERT(call RadioOff.off() == SUCCESS);
+ // will continue in continueScanRequest()
+ }
+
+ task void continueScanRequestTask()
+ {
+ continueScanRequest();
+ }
+
+ void continueScanRequest()
{
uint8_t i;
ieee154_macPANId_t bcastPANID = 0xFFFF;
ieee154_macDSN_t dsn = call MLME_GET.macDSN();
- if (!m_busy){
+ if (!m_busy) {
call Token.release();
return;
}
- switch (m_scanType){
+ switch (m_scanType) {
case ACTIVE_SCAN:
// beacon request frame
m_txFrame->header->mhr[MHR_INDEX_FC1] = FC1_FRAMETYPE_CMD;
error_t radioStatus = SUCCESS;
uint32_t supportedChannels = IEEE154_SUPPORTED_CHANNELS;
atomic {
- while (!(m_scanChannels & m_currentChannelBit & supportedChannels) && m_currentChannelNum < 27){
+ while (!(m_scanChannels & m_currentChannelBit & supportedChannels) && m_currentChannelNum < 27) {
m_unscannedChannels |= m_currentChannelBit;
m_currentChannelBit <<= 1;
m_currentChannelNum++;
}
if (m_currentChannelNum < 27) {
call MLME_SET.phyCurrentChannel(m_currentChannelNum);
- switch (m_scanType){
+ dbg_serial("ScanP", "Scanning channel %lu...\n", (uint32_t) m_currentChannelNum);
+ switch (m_scanType) {
case PASSIVE_SCAN:
- radioStatus = call RadioRx.prepare();
+ radioStatus = call RadioRx.enableRx(0, 0);
break;
- case ACTIVE_SCAN:
+ case ACTIVE_SCAN: // fall through
case ORPHAN_SCAN:
- radioStatus = call RadioTx.load(m_txFrame);
+ radioStatus = call RadioTx.transmit(m_txFrame, NULL, 0);
break;
case ENERGY_DETECTION_SCAN:
radioStatus = call EnergyDetection.start(m_scanDuration);
break;
}
- if (radioStatus != SUCCESS){
- call Leds.led0On();
- }
+ ASSERT(radioStatus == SUCCESS);
} else {
- ieee154_status_t result = IEEE154_SUCCESS;
// we're done
+ ieee154_status_t result = IEEE154_SUCCESS;
m_currentChannelBit <<= 1;
- while (m_currentChannelBit){
+ while (m_currentChannelBit) {
m_unscannedChannels |= m_currentChannelBit;
m_currentChannelBit <<= 1;
}
result = IEEE154_NO_BEACON;
if (m_scanType == PASSIVE_SCAN || m_scanType == ACTIVE_SCAN)
call MLME_SET.macPANId(m_PANID);
- if (m_txFrame != NULL){
+ if (m_txFrame != NULL) {
call TxControlPool.put((ieee154_txcontrol_t*) ((uint8_t*) m_txFrame->header - offsetof(ieee154_txcontrol_t, header)));
call TxFramePool.put(m_txFrame);
}
if (call Token.isOwner())
call Token.release();
m_busy = FALSE;
+ dbg_serial("ScanP", "MLME_SCAN.confirm()\n");
signal MLME_SCAN.confirm (
result,
m_scanType,
((m_scanType == ACTIVE_SCAN ||
m_scanType == PASSIVE_SCAN) && m_macAutoRequest) ? m_resultIndex : 0,
((m_scanType == ACTIVE_SCAN ||
- m_scanType == PASSIVE_SCAN) && m_macAutoRequest) ? (ieee154_PANDescriptor_t*) m_resultList : NULL
- );
+ m_scanType == PASSIVE_SCAN) && m_macAutoRequest) ? (ieee154_PANDescriptor_t*) m_resultList : NULL);
}
}
+
+ async event void RadioRx.enableRxDone()
+ {
+ post startTimerTask();
+ }
-/* ----------------------- EnergyDetection ----------------------- */
+ /* ----------------------- EnergyDetection ----------------------- */
event void EnergyDetection.done(error_t status, int8_t EnergyLevel)
{
call RadioOff.off();
}
-/* ----------------------- Active/Orphan scan ----------------------- */
-
- async event void RadioTx.loadDone()
- {
- call RadioTx.transmit(NULL, 0); // transmit immediately
- }
+ /* ----------------------- Active/Orphan scan ----------------------- */
- async event void RadioTx.transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime)
+ async event void RadioTx.transmitDone(ieee154_txframe_t *frame, const ieee154_timestamp_t *timestamp, error_t result)
{
- if (call RadioRx.prepare() != SUCCESS) // must succeed
- call Leds.led0On();
+ ASSERT(call RadioRx.enableRx(0, 0) == SUCCESS);
}
-/* -------- Receive events (for Active/Passive/Orphan scan) -------- */
-
- async event void RadioRx.prepareDone()
- {
- call RadioRx.receive(NULL, 0);
- post startTimerTask();
- }
+ /* -------- Receive events (for Active/Passive/Orphan scan) -------- */
- event message_t* RadioRx.received(message_t *frame, ieee154_reftime_t *timestamp)
+ event message_t* RadioRx.received(message_t *frame, const ieee154_timestamp_t *timestamp)
{
atomic {
if (!m_busy)
return frame;
- if (m_scanType == ORPHAN_SCAN){
+ if (m_scanType == ORPHAN_SCAN) {
if (!m_resultIndex)
if ((MHR(frame)[0] & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_CMD &&
- ((uint8_t*)call Frame.getPayload(frame))[0] == CMD_FRAME_COORDINATOR_REALIGNMENT){
+ ((uint8_t*)call Frame.getPayload(frame))[0] == CMD_FRAME_COORDINATOR_REALIGNMENT) {
m_resultIndex++;
+ dbg_serial("ScanP", "Received coordinator realignment frame.\n");
m_currentChannelNum = 27; // terminate scan
call RadioOff.off();
}
frame,
m_currentChannelNum,
IEEE154_SUPPORTED_CHANNELPAGE,
- &((ieee154_PANDescriptor_t*) m_resultList)[m_resultIndex]) == SUCCESS){
+ &((ieee154_PANDescriptor_t*) m_resultList)[m_resultIndex]) == SUCCESS) {
+
// check uniqueness: both PAN ID and source address must not be in a previously received beacon
uint8_t i;
+ ieee154_PANDescriptor_t* descriptor = (ieee154_PANDescriptor_t*) m_resultList;
if (m_resultIndex)
for (i=0; i<m_resultIndex; i++)
- if ( ((ieee154_PANDescriptor_t*) m_resultList)[i].CoordPANId ==
- ((ieee154_PANDescriptor_t*) m_resultList)[m_resultIndex].CoordPANId &&
- ((ieee154_PANDescriptor_t*) m_resultList)[i].CoordAddrMode ==
- ((ieee154_PANDescriptor_t*) m_resultList)[m_resultIndex].CoordAddrMode)
- if ( (((ieee154_PANDescriptor_t*) m_resultList)[i].CoordAddrMode == ADDR_MODE_SHORT_ADDRESS &&
- ((ieee154_PANDescriptor_t*) m_resultList)[i].CoordAddress.shortAddress ==
- ((ieee154_PANDescriptor_t*) m_resultList)[m_resultIndex].CoordAddress.shortAddress) ||
- (((ieee154_PANDescriptor_t*) m_resultList)[i].CoordAddrMode == ADDR_MODE_EXTENDED_ADDRESS &&
- ((ieee154_PANDescriptor_t*) m_resultList)[i].CoordAddress.extendedAddress ==
- ((ieee154_PANDescriptor_t*) m_resultList)[m_resultIndex].CoordAddress.extendedAddress) )
+ if (descriptor[i].CoordPANId == descriptor[m_resultIndex].CoordPANId &&
+ descriptor[i].CoordAddrMode == descriptor[m_resultIndex].CoordAddrMode)
+ if ((descriptor[i].CoordAddrMode == ADDR_MODE_SHORT_ADDRESS &&
+ descriptor[i].CoordAddress.shortAddress ==
+ descriptor[m_resultIndex].CoordAddress.shortAddress) ||
+ (descriptor[i].CoordAddrMode == ADDR_MODE_EXTENDED_ADDRESS &&
+ descriptor[i].CoordAddress.extendedAddress ==
+ descriptor[m_resultIndex].CoordAddress.extendedAddress))
return frame; // not unique
+ dbg_serial("ScanP", "Received beacon, source: 0x%lx, channel: %lu.\n",
+ (uint32_t) descriptor[m_resultIndex].CoordAddress.shortAddress, (uint32_t) m_currentChannelNum);
m_resultIndex++;
- if (m_resultIndex == m_resultListNumEntries){
+ if (m_resultIndex == m_resultListNumEntries) {
m_currentChannelNum = 27; // terminate scan
call RadioOff.off();
}
}
- }
+ } // PASSIVE_SCAN / ACTIVE_SCAN
}
return frame;
}
-/* ----------------------- Common ----------------------- */
+ /* ----------------------- Common ----------------------- */
task void startTimerTask()
{
async event void RadioOff.offDone()
{
- m_currentChannelBit <<= 1;
- m_currentChannelNum++;
- post nextIterationTask();
+ if (m_currentChannelNum == 0)
+ post continueScanRequestTask();
+ else {
+ m_currentChannelBit <<= 1;
+ m_currentChannelNum++;
+ post nextIterationTask();
+ }
}
task void nextIterationTask()
nextIteration();
}
- async event void RadioTx.transmitUnslottedCsmaCaDone(ieee154_txframe_t *frame,
- bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result){}
-
- async event void RadioTx.transmitSlottedCsmaCaDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime,
- bool ackPendingFlag, uint16_t remainingBackoff, ieee154_csma_t *csmaParams, error_t result){}
-
- default event message_t* MLME_BEACON_NOTIFY.indication ( message_t *beaconFrame ){return beaconFrame;}
+ default event message_t* MLME_BEACON_NOTIFY.indication (message_t *beaconFrame) {return beaconFrame;}
default event void MLME_SCAN.confirm (
ieee154_status_t status,
uint8_t ScanType,
uint8_t EnergyDetectListNumEntries,
int8_t* EnergyDetectList,
uint8_t PANDescriptorListNumEntries,
- ieee154_PANDescriptor_t* PANDescriptorList
- ){}
+ ieee154_PANDescriptor_t* PANDescriptorList) {}
}
async command error_t ResourceTransferControl.transfer(uint8_t fromClient, uint8_t toClient)
{
atomic {
- if (call ArbiterInfo.userId() == fromClient){
+ if (call ArbiterInfo.userId() == fromClient) {
call ResourceConfigure.unconfigure[fromClient]();
call ResourceConfigure.configure[resId]();
resId = toClient;
--- /dev/null
+/*
+ * Copyright (c) 2008, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+#include "TKN154_PHY.h"
+#include "TKN154_MAC.h"
+
+
+/**
+ * This module is responsible for the transmission/reception of DATA and
+ * COMMAND frames in the CAP of beacon-enabled PANs. Its main tasks are
+ * initialization of the parameters of the slotted CSMA-CA algorithm (NB, BE,
+ * etc.), initiating retransmissions and dealing with broadcast transmissions.
+ * It does not implement the actual CSMA-CA algorithm, because due to its
+ * timing requirements the CSMA-CA algorithm is not part of the MAC
+ * implementation but of the chip-specific radio driver.
+ *
+ * This module does slightly different things depending on whether it is the
+ * CAP for an outgoing superframe (sfDirection = OUTGOING_SUPERFRAME), i.e. the
+ * CAP from the perspective of a coordinator after it has transmitted its own
+ * beacon; or for an incoming superframe (sfDirection = INCOMING_SUPERFRAME),
+ * i.e. the CAP from the perspective of a device after it has received a
+ * beacon from its coordinator. For example, in the CAP a coordinator will
+ * typically listen for incoming frames from the devices, and a device will
+ * typically switch the radio off unless it has a frame to transmit.
+ */
+
+#ifndef IEEE154_BEACON_ENABLED_PAN
+#error "The IEEE154_BEACON_ENABLED_PAN macro MUST be defined when using this component!"
+#endif
+
+generic module SlottedFrameDispatchP(uint8_t sfDirection)
+{
+ provides
+ {
+ interface Init as Reset;
+ interface FrameTx as FrameTx;
+ interface FrameRx as FrameRx[uint8_t frameType];
+ interface FrameExtracted as FrameExtracted[uint8_t frameType];
+ interface FrameTxNow as BroadcastTx;
+ interface Notify<bool> as WasRxEnabled;
+ }
+ uses
+ {
+ interface Alarm<TSymbolIEEE802154,uint32_t> as CapEndAlarm;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as BLEAlarm;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as IndirectTxWaitAlarm;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as BroadcastAlarm;
+ interface Resource as Token;
+ interface GetNow<bool> as IsTokenRequested;
+ interface ResourceTransfer as TokenToCfp;
+ interface ResourceTransferred as TokenTransferred;
+ interface SuperframeStructure;
+ interface GetNow<bool> as IsRxEnableActive;
+ interface Get<ieee154_txframe_t*> as GetIndirectTxFrame;
+ interface Notify<bool> as RxEnableStateChange;
+ interface GetNow<bool> as IsTrackingBeacons;
+ interface FrameUtility;
+ interface SlottedCsmaCa;
+ interface RadioRx;
+ interface RadioOff;
+ interface MLME_GET;
+ interface MLME_SET;
+ interface TimeCalc;
+ interface Leds;
+ interface SetNow<ieee154_cap_frame_backup_t*> as FrameBackup;
+ interface GetNow<ieee154_cap_frame_backup_t*> as FrameRestore;
+ interface StdControl as TrackSingleBeacon;
+ }
+}
+implementation
+{
+ typedef enum {
+ SWITCH_OFF,
+ WAIT_FOR_RXDONE,
+ WAIT_FOR_TXDONE,
+ DO_NOTHING,
+ } next_state_t;
+
+ typedef enum {
+ INDIRECT_TX_ALARM,
+ BROADCAST_ALARM,
+ NO_ALARM,
+ } rx_alarm_t;
+
+ enum {
+ COORD_ROLE = (sfDirection == OUTGOING_SUPERFRAME),
+ DEVICE_ROLE = !COORD_ROLE,
+ };
+
+ /* state / frame management */
+ norace bool m_lock;
+ norace bool m_resume;
+ norace ieee154_txframe_t *m_currentFrame;
+ norace ieee154_txframe_t *m_bcastFrame;
+ norace ieee154_txframe_t *m_lastFrame;
+ norace uint16_t m_remainingBackoff;
+
+ /* variables for the slotted CSMA-CA */
+ norace ieee154_csma_t m_csma;
+ norace ieee154_macMaxBE_t m_BE;
+ norace ieee154_macMaxCSMABackoffs_t m_macMaxCSMABackoffs;
+ norace ieee154_macMaxBE_t m_macMaxBE;
+ norace ieee154_macMaxFrameRetries_t m_macMaxFrameRetries;
+ norace ieee154_status_t m_txStatus;
+ norace uint32_t m_transactionTime;
+ norace bool m_indirectTxPending = FALSE;
+ norace bool m_broadcastRxPending;
+ norace ieee154_macMaxFrameTotalWaitTime_t m_macMaxFrameTotalWaitTime;
+
+ /* function / task prototypes */
+ void stopAllAlarms();
+ next_state_t tryReceive(rx_alarm_t alarmType);
+ next_state_t tryTransmit();
+ next_state_t trySwitchOff();
+ void backupCurrentFrame();
+ void restoreFrameFromBackup();
+ void updateState();
+ void setCurrentFrame(ieee154_txframe_t *frame);
+ void signalTxBroadcastDone(ieee154_txframe_t *frame, ieee154_status_t error);
+ task void signalTxDoneTask();
+ task void setupTxBroadcastTask();
+ task void wasRxEnabledTask();
+
+#ifdef TKN154_DEBUG
+ enum {
+ HEADER_STR_LEN = 27,
+ DBG_STR_SIZE = 250,
+ };
+ norace uint16_t m_dbgNumEntries;
+ norace char m_dbgStr[HEADER_STR_LEN + DBG_STR_SIZE] = "updateState() transitions: ";
+ void dbg_push_state(uint8_t state) {
+ if (m_dbgNumEntries < DBG_STR_SIZE-3)
+ m_dbgStr[HEADER_STR_LEN + m_dbgNumEntries++] = '0' + state;
+ }
+ void dbg_flush_state() {
+ m_dbgStr[HEADER_STR_LEN + m_dbgNumEntries++] = '\n';
+ m_dbgStr[HEADER_STR_LEN + m_dbgNumEntries++] = 0;
+ dbg_serial("SlottedFrameDispatchP",m_dbgStr);
+ m_dbgNumEntries = 0;
+ }
+#else
+#define dbg_push_state(X)
+#define dbg_flush_state()
+#endif
+
+ command error_t Reset.init()
+ {
+ if (m_currentFrame)
+ signal FrameTx.transmitDone(m_currentFrame, IEEE154_TRANSACTION_OVERFLOW);
+ if (m_lastFrame)
+ signal FrameTx.transmitDone(m_lastFrame, IEEE154_TRANSACTION_OVERFLOW);
+ if (m_bcastFrame)
+ signalTxBroadcastDone(m_bcastFrame, IEEE154_TRANSACTION_OVERFLOW);
+ m_currentFrame = m_lastFrame = m_bcastFrame = NULL;
+ stopAllAlarms();
+ return SUCCESS;
+ }
+
+ async event void TokenTransferred.transferred()
+ {
+ // we got the token, i.e. CAP has just started
+ uint32_t capDuration = (uint32_t) call SuperframeStructure.numCapSlots() *
+ (uint32_t) call SuperframeStructure.sfSlotDuration();
+ uint16_t guardTime = call SuperframeStructure.guardTime();
+
+ dbg_serial("SlottedFrameDispatchP", "Got token, remaining CAP time: %lu\n",
+ call SuperframeStructure.sfStartTime() + capDuration - guardTime - call CapEndAlarm.getNow());
+ if (DEVICE_ROLE && !call IsTrackingBeacons.getNow()) {
+ // very rare case:
+ // this can only happen, if we're on a beacon-enabled PAN, not tracking beacons,
+ // and searched but didn't find a beacon for aBaseSuperframeDuration*(2n+1) symbols
+ // we'd actually have to transmit the current frame using unslotted CSMA-CA
+ // but we don't have that functionality available... signal FAIL...
+ m_lastFrame = m_currentFrame;
+ m_currentFrame = NULL;
+ m_txStatus = IEEE154_NO_BEACON;
+ dbg_serial("SlottedFrameDispatchP", "CAP component got token, remaining time: %lu\n");
+ post signalTxDoneTask();
+ return;
+ } else if (capDuration < guardTime) {
+ // CAP is too short to do anything practical
+ dbg_serial("SlottedFrameDispatchP", "CAP too short!\n");
+ call TokenToCfp.transfer();
+ return;
+ } else {
+ capDuration -= guardTime;
+ if (DEVICE_ROLE)
+ m_broadcastRxPending = call SuperframeStructure.isBroadcastPending();
+ else {
+ // COORD_ROLE
+ if (m_bcastFrame != NULL) {
+ // we have to transmit a broadcast frame immediately; this
+ // may require to a backup of the previously active frame
+ // and a reinitializing the CSMA parameters -> will do it
+ // in task context and then continue
+ m_lock = TRUE;
+ post setupTxBroadcastTask();
+ dbg_serial("SlottedFrameDispatchP", "Preparing broadcast.\n");
+ }
+ }
+ call CapEndAlarm.startAt(call SuperframeStructure.sfStartTime(), capDuration);
+ if (call SuperframeStructure.battLifeExtDuration() > 0)
+ call BLEAlarm.startAt(call SuperframeStructure.sfStartTime(), call SuperframeStructure.battLifeExtDuration());
+ }
+ updateState();
+ }
+
+ command ieee154_status_t FrameTx.transmit(ieee154_txframe_t *frame)
+ {
+ if (m_currentFrame != NULL) {
+ // we've not finished transmitting the current frame yet
+ dbg_serial("SlottedFrameDispatchP", "Overflow\n");
+ return IEEE154_TRANSACTION_OVERFLOW;
+ } else {
+ setCurrentFrame(frame);
+ dbg("SlottedFrameDispatchP", "New frame to transmit, DSN: %lu\n", (uint32_t) MHR(frame)[MHR_INDEX_SEQNO]);
+ // a beacon must be found before transmitting in a beacon-enabled PAN
+ if (DEVICE_ROLE && !call IsTrackingBeacons.getNow()) {
+ call TrackSingleBeacon.start();
+ dbg_serial("SlottedFrameDispatchP", "Tracking single beacon now\n");
+ // we'll receive the Token after a beacon was found or after
+ // aBaseSuperframeDuration*(2n+1) symbols if none was found
+ }
+ updateState();
+ return IEEE154_SUCCESS;
+ }
+ }
+
+ task void setupTxBroadcastTask()
+ {
+ ieee154_macDSN_t tmp;
+ ieee154_txframe_t *oldFrame = m_currentFrame;
+ if (COORD_ROLE) {
+ if (m_bcastFrame != NULL) {
+ // broadcasts should be transmitted *immediately* after the beacon,
+ // which may interrupt a pending transmit operation from the previous
+ // CAP; back up the last active frame configuration (may be none)
+ // and restore it after the broadcast frame has been transmitted;
+ // do this through interfaces and don't wire them for DEVICE_ROLE,
+ // so we don't waste the RAM of devices
+ backupCurrentFrame();
+ setCurrentFrame(m_bcastFrame);
+ if (oldFrame) {
+ // now the sequence number are out of order... swap them back
+ tmp = m_bcastFrame->header->mhr[MHR_INDEX_SEQNO];
+ m_bcastFrame->header->mhr[MHR_INDEX_SEQNO] =
+ oldFrame->header->mhr[MHR_INDEX_SEQNO];
+ oldFrame->header->mhr[MHR_INDEX_SEQNO] = tmp;
+ }
+ }
+ }
+ m_lock = FALSE;
+ updateState();
+ }
+
+ void setCurrentFrame(ieee154_txframe_t *frame)
+ {
+ ieee154_macDSN_t dsn = call MLME_GET.macDSN();
+ frame->header->mhr[MHR_INDEX_SEQNO] = dsn++;
+ call MLME_SET.macDSN(dsn);
+ m_csma.NB = 0;
+ m_csma.macMaxCsmaBackoffs = m_macMaxCSMABackoffs = call MLME_GET.macMaxCSMABackoffs();
+ m_csma.macMaxBE = m_macMaxBE = call MLME_GET.macMaxBE();
+ m_csma.BE = call MLME_GET.macMinBE();
+ if (call MLME_GET.macBattLifeExt() && m_csma.BE > 2)
+ m_csma.BE = 2;
+ m_BE = m_csma.BE;
+ if (COORD_ROLE && call GetIndirectTxFrame.get() == frame)
+ m_macMaxFrameRetries = 0; // this is an indirect transmissions (never retransmit)
+ else
+ m_macMaxFrameRetries = call MLME_GET.macMaxFrameRetries();
+ m_transactionTime = IEEE154_SHR_DURATION +
+ (frame->headerLen + frame->payloadLen + 2) * IEEE154_SYMBOLS_PER_OCTET; // extra 2 for CRC
+ if (frame->header->mhr[MHR_INDEX_FC1] & FC1_ACK_REQUEST)
+ m_transactionTime += (IEEE154_aTurnaroundTime + IEEE154_aUnitBackoffPeriod +
+ 11 * IEEE154_SYMBOLS_PER_OCTET); // 11 byte for the ACK PPDU
+ // if (frame->headerLen + frame->payloadLen > IEEE154_aMaxSIFSFrameSize)
+ // m_transactionTime += call MLME_GET.macMinLIFSPeriod();
+ // else
+ // m_transactionTime += call MLME_GET.macMinSIFSPeriod();
+ m_macMaxFrameTotalWaitTime = call MLME_GET.macMaxFrameTotalWaitTime();
+ m_currentFrame = frame;
+ }
+
+ void stopAllAlarms()
+ {
+ call CapEndAlarm.stop();
+ if (DEVICE_ROLE) {
+ call IndirectTxWaitAlarm.stop();
+ call BroadcastAlarm.stop();
+ }
+ call BLEAlarm.stop();
+ }
+
+ /**
+ * The updateState() function is called whenever something happened that
+ * might require a state transition; it implements a lock mechanism (m_lock)
+ * to prevent race conditions. Whenever the lock is set a "done"-event (from
+ * the SlottedCsmaCa/RadioRx/RadioOff interface) is pending and will "soon"
+ * unset the lock (and then updateState() will called again). The
+ * updateState() function decides about the next state by checking a list of
+ * possible current states ordered by priority, e.g. it first always checks
+ * whether the CAP is still active. Calling this function more than necessary
+ * can do no harm.
+ */
+
+ void updateState()
+ {
+ uint32_t capDuration;
+ next_state_t next;
+ atomic {
+ // long atomics are bad... but in this block, once the/ current state has
+ // been determined only one branch will/ be taken (there are no loops)
+ if (m_lock || !call Token.isOwner())
+ return;
+ m_lock = TRUE; // lock
+ capDuration = (uint32_t) call SuperframeStructure.numCapSlots() *
+ (uint32_t) call SuperframeStructure.sfSlotDuration();
+
+ // Check 1: has the CAP finished?
+ if ((COORD_ROLE || call IsTrackingBeacons.getNow()) &&
+ (call TimeCalc.hasExpired(call SuperframeStructure.sfStartTime(),
+ capDuration - call SuperframeStructure.guardTime()) ||
+ !call CapEndAlarm.isRunning())) {
+ dbg_push_state(1);
+ if (call RadioOff.isOff()) {
+ stopAllAlarms(); // may still fire, but is locked through isOwner()
+ if (DEVICE_ROLE && m_indirectTxPending)
+ signal IndirectTxWaitAlarm.fired();
+ m_broadcastRxPending = FALSE;
+ if (COORD_ROLE && m_bcastFrame) {
+ // didn't manage to transmit a broadcast
+ restoreFrameFromBackup();
+ signalTxBroadcastDone(m_bcastFrame, IEEE154_CHANNEL_ACCESS_FAILURE);
+ m_bcastFrame = NULL;
+ }
+ m_lock = FALSE; // unlock
+ dbg_flush_state();
+ dbg_serial("SlottedFrameDispatchP", "Handing over to CFP.\n");
+ call TokenToCfp.transfer();
+ return;
+ } else
+ next = SWITCH_OFF;
+ }
+
+ // Check 2: should a broadcast frame be received/transmitted
+ // immediately at the start of CAP?
+ else if (DEVICE_ROLE && m_broadcastRxPending) {
+ // receive a broadcast from coordinator
+ dbg_push_state(2);
+ next = tryReceive(BROADCAST_ALARM);
+ } else if (COORD_ROLE && m_bcastFrame) {
+ dbg_push_state(2);
+ next = tryTransmit();
+ }
+
+ // Check 3: was an indirect transmission successfully started
+ // and are we now waiting for a frame from the coordinator?
+ else if (DEVICE_ROLE && m_indirectTxPending) {
+ dbg_push_state(3);
+ next = tryReceive(INDIRECT_TX_ALARM);
+ }
+
+ // Check 4: is some other operation (like MLME-SCAN or MLME-RESET) pending?
+ else if (call IsTokenRequested.getNow()) {
+ dbg_push_state(4);
+ if (call RadioOff.isOff()) {
+ stopAllAlarms(); // may still fire, but is locked through isOwner()
+ // nothing more to do... just release the Token
+ m_lock = FALSE; // unlock
+ dbg_serial("SlottedFrameDispatchP", "Token requested: Handing over to CFP.\n");
+ call TokenToCfp.transfer();
+ return;
+ } else
+ next = SWITCH_OFF;
+ }
+
+ // Check 5: is battery life extension (BLE) active and
+ // has the BLE period expired?
+ else if (call SuperframeStructure.battLifeExtDuration() > 0 &&
+ call TimeCalc.hasExpired(call SuperframeStructure.sfStartTime(),
+ call SuperframeStructure.battLifeExtDuration()) &&
+ !call IsRxEnableActive.getNow()) {
+ dbg_push_state(5);
+ next = trySwitchOff();
+ }
+
+ // Check 6: is there a frame ready to transmit?
+ else if (m_currentFrame != NULL) {
+ dbg_push_state(6);
+ next = tryTransmit();
+ }
+
+ // Check 7: should we be in receive mode?
+ else if (COORD_ROLE || call IsRxEnableActive.getNow()) {
+ dbg_push_state(7);
+ next = tryReceive(NO_ALARM);
+ if (next == DO_NOTHING) {
+ // this means there is an active MLME_RX_ENABLE.request
+ // and the radio was just switched to Rx mode - signal
+ // a notify event to inform the respective component
+ post wasRxEnabledTask();
+ }
+ }
+
+ // Check 8: just make sure the radio is switched off
+ else {
+ dbg_push_state(8);
+ next = trySwitchOff();
+ if (next == DO_NOTHING && (DEVICE_ROLE && capDuration == 0)) {
+ // nothing more to do... just release the Token
+ stopAllAlarms(); // may still fire, but is locked through isOwner()
+ m_lock = FALSE; // unlock
+ dbg_serial("SlottedFrameDispatchP", "Releasing token\n");
+ call Token.release();
+ return;
+ }
+ }
+
+ // if there is nothing to do, then we must clear the lock
+ if (next == DO_NOTHING)
+ m_lock = FALSE;
+ } // atomic
+
+ // put next state in operation (possibly keeping the lock)
+ switch (next)
+ {
+ case SWITCH_OFF: ASSERT(call RadioOff.off() == SUCCESS); break;
+ case WAIT_FOR_RXDONE: break;
+ case WAIT_FOR_TXDONE: break;
+ case DO_NOTHING: break;
+ }
+ }
+
+ next_state_t tryTransmit()
+ {
+ // tries to transmit m_currentFrame
+ uint32_t capDuration = (uint32_t) call SuperframeStructure.numCapSlots() *
+ (uint32_t) call SuperframeStructure.sfSlotDuration();
+ next_state_t next;
+
+ if (!call RadioOff.isOff())
+ next = SWITCH_OFF;
+ else {
+ uint32_t dtMax = capDuration - call SuperframeStructure.guardTime() - m_transactionTime;
+ // round to backoff boundary
+ dtMax = dtMax + (IEEE154_aUnitBackoffPeriod - (dtMax % IEEE154_aUnitBackoffPeriod));
+ if (dtMax > capDuration)
+ dtMax = 0;
+ if (call SuperframeStructure.battLifeExtDuration() > 0) {
+ // battery life extension
+ uint16_t bleLen = call SuperframeStructure.battLifeExtDuration();
+ if (bleLen < dtMax)
+ dtMax = bleLen;
+ }
+ if (call TimeCalc.hasExpired(call SuperframeStructure.sfStartTime(), dtMax))
+ next = DO_NOTHING; // frame doesn't fit in the remaining CAP
+ else {
+ error_t res;
+ res = call SlottedCsmaCa.transmit(m_currentFrame, &m_csma,
+ call SuperframeStructure.sfStartTimeRef(), dtMax, m_resume, m_remainingBackoff);
+ dbg("SlottedFrameDispatchP", "SlottedCsmaCa.transmit() -> %lu\n", (uint32_t) res);
+ next = WAIT_FOR_TXDONE; // this will NOT clear the lock
+ }
+ }
+ return next;
+ }
+
+ next_state_t tryReceive(rx_alarm_t alarmType)
+ {
+ next_state_t next;
+ if (call RadioRx.isReceiving())
+ next = DO_NOTHING;
+ else if (!call RadioOff.isOff())
+ next = SWITCH_OFF;
+ else {
+ call RadioRx.enableRx(0, 0);
+ switch (alarmType)
+ {
+ case INDIRECT_TX_ALARM: call IndirectTxWaitAlarm.start(m_macMaxFrameTotalWaitTime); break;
+ case BROADCAST_ALARM: call BroadcastAlarm.start(m_macMaxFrameTotalWaitTime); break;
+ case NO_ALARM: break;
+ }
+ next = WAIT_FOR_RXDONE;
+ }
+ return next;
+ }
+
+ next_state_t trySwitchOff()
+ {
+ next_state_t next;
+ if (call RadioOff.isOff())
+ next = DO_NOTHING;
+ else
+ next = SWITCH_OFF;
+ return next;
+ }
+
+ async event void RadioOff.offDone() { m_lock = FALSE; updateState();}
+ async event void RadioRx.enableRxDone() { m_lock = FALSE; updateState();}
+
+ async event void CapEndAlarm.fired() {
+ dbg_serial("SlottedFrameDispatchP", "CapEndAlarm.fired()\n");
+ updateState();
+ }
+ async event void BLEAlarm.fired() { updateState();}
+ event void RxEnableStateChange.notify(bool whatever) { updateState();}
+ async event void BroadcastAlarm.fired() { m_broadcastRxPending = FALSE; updateState();}
+
+ async event void IndirectTxWaitAlarm.fired()
+ {
+ atomic {
+ if (m_indirectTxPending) {
+ m_indirectTxPending = FALSE;
+ post signalTxDoneTask();
+ }
+ }
+ }
+
+ async event void SlottedCsmaCa.transmitDone(ieee154_txframe_t *frame, ieee154_csma_t *csma,
+ bool ackPendingFlag, uint16_t remainingBackoff, error_t result)
+ {
+ bool done = TRUE;
+ dbg("SlottedFrameDispatchP", "SlottedCsmaCa.transmitDone() -> %lu\n", (uint32_t) result);
+ m_resume = FALSE;
+
+ switch (result)
+ {
+ case SUCCESS:
+ // frame was successfully transmitted, if ACK was requested
+ // then a matching ACK was successfully received as well
+ m_txStatus = IEEE154_SUCCESS;
+ if (DEVICE_ROLE && frame->payload[0] == CMD_FRAME_DATA_REQUEST &&
+ ((frame->header->mhr[MHR_INDEX_FC1]) & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_CMD) {
+ // this was a data request frame
+ m_txStatus = IEEE154_NO_DATA; // pessimistic
+ if (ackPendingFlag) {
+ // the coordinator has data for us; switch to Rx
+ // to complete the indirect transmission
+ m_indirectTxPending = TRUE;
+ m_lastFrame = m_currentFrame;
+ m_currentFrame = NULL;
+ ASSERT(call RadioRx.enableRx(0, 0) == SUCCESS);
+ return;
+ }
+ }
+ break;
+ case FAIL:
+ // The CSMA-CA algorithm failed: the frame was not transmitted,
+ // because channel was never idle
+ m_txStatus = IEEE154_CHANNEL_ACCESS_FAILURE;
+ break;
+ case ENOACK:
+ // frame was transmitted, but we didn't receive an ACK (although
+ // we requested an one). note: coordinator never retransmits an
+ // indirect transmission (see above)
+ if (m_macMaxFrameRetries > 0) {
+ // retransmit: reinitialize CSMA-CA parameters
+ done = FALSE;
+ m_csma.NB = 0;
+ m_csma.macMaxCsmaBackoffs = m_macMaxCSMABackoffs;
+ m_csma.macMaxBE = m_macMaxBE;
+ m_csma.BE = m_BE;
+ m_macMaxFrameRetries -= 1;
+ } else
+ m_txStatus = IEEE154_NO_ACK;
+ break;
+ case EINVAL: // DEBUG!!!
+ dbg_serial("SlottedFrameDispatchP", "EINVAL returned by transmitDone()!\n");
+ // fall through
+ case ERETRY:
+ // frame was not transmitted, because the transaction does not
+ // fit in the remaining CAP (in beacon-enabled PANs only)
+ dbg_serial("SlottedFrameDispatchP", "Transaction didn't fit, current BE: %lu\n", (uint32_t) csma->BE);
+ m_resume = TRUE;
+ m_remainingBackoff = remainingBackoff;
+ done = FALSE;
+ m_lock = FALSE; // debug! problem: if CAP endalarm has fired it's a deadlock!
+ if (!call CapEndAlarm.isRunning())
+ updateState();
+ return;
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ if (COORD_ROLE && frame == m_bcastFrame) {
+ // always signal result of broadcast transmissions immediately
+ restoreFrameFromBackup();
+ signalTxBroadcastDone(m_bcastFrame, (!done) ? IEEE154_CHANNEL_ACCESS_FAILURE : m_txStatus);
+ m_bcastFrame = NULL;
+ } else if (done) {
+ m_lastFrame = m_currentFrame;
+ m_currentFrame = NULL;
+ post signalTxDoneTask();
+ }
+
+ m_lock = FALSE;
+ updateState();
+ }
+
+ task void signalTxDoneTask()
+ {
+ ieee154_txframe_t *lastFrame = m_lastFrame;
+ ieee154_status_t status = m_txStatus;
+ m_indirectTxPending = FALSE;
+ m_lastFrame = NULL; // only now can the next transmission can begin
+ if (lastFrame) {
+ dbg("SlottedFrameDispatchP", "Transmit done, DSN: %lu, result: 0x%lx\n",
+ (uint32_t) MHR(lastFrame)[MHR_INDEX_SEQNO], (uint32_t) status);
+ signal FrameTx.transmitDone(lastFrame, status);
+ }
+ updateState();
+ }
+
+ event message_t* RadioRx.received(message_t* frame, const ieee154_timestamp_t *timestamp)
+ {
+ // received a frame -> find out frame type and
+ // signal it to responsible client component
+ uint8_t *payload = (uint8_t *) frame->data;
+ uint8_t *mhr = MHR(frame);
+ uint8_t frameType = mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK;
+ if (frameType == FC1_FRAMETYPE_CMD)
+ frameType += payload[0];
+ atomic {
+ if (DEVICE_ROLE && m_indirectTxPending) {
+ message_t* frameBuf;
+ call IndirectTxWaitAlarm.stop();
+ // TODO: check!
+ //if (frame->payloadLen)
+ // is this frame from our coordinator? hmm... we cannot say/ with
+ // certainty, because we might only know either the coordinator
+ // extended or short address (and the frame could/ have been sent
+ // with the other addressing mode) ??
+ m_txStatus = IEEE154_SUCCESS;
+ frameBuf = signal FrameExtracted.received[frameType](frame, m_lastFrame);
+ signal IndirectTxWaitAlarm.fired();
+ return frameBuf;
+ } else
+ return signal FrameRx.received[frameType](frame);
+ }
+ }
+
+ void backupCurrentFrame()
+ {
+ ieee154_cap_frame_backup_t backup = {m_currentFrame, m_csma, m_transactionTime};
+ call FrameBackup.setNow(&backup);
+ }
+
+ void restoreFrameFromBackup()
+ {
+ ieee154_cap_frame_backup_t *backup = call FrameRestore.getNow();
+ if (backup != NULL) {
+ m_currentFrame = backup->frame;
+ memcpy(&m_csma, &backup->csma, sizeof(ieee154_csma_t));
+ m_transactionTime = backup->transactionTime;
+ }
+ }
+
+ async command ieee154_status_t BroadcastTx.transmitNow(ieee154_txframe_t *frame)
+ {
+ // if this command is called then it is (MUST be) called only just before
+ // the token is transferred to this component and it is then called
+ // only once per CAP (max. one broadcast is allowed after a beacon
+ // transmission)
+ atomic {
+ if (!call Token.isOwner() && m_bcastFrame == NULL) {
+ m_bcastFrame = frame;
+ return IEEE154_SUCCESS;
+ } else {
+ ASSERT(0);
+ return IEEE154_TRANSACTION_OVERFLOW;
+ }
+ }
+ }
+
+ void signalTxBroadcastDone(ieee154_txframe_t *frame, ieee154_status_t error)
+ {
+ signal BroadcastTx.transmitNowDone(frame, error);
+ }
+
+ task void wasRxEnabledTask()
+ {
+ signal WasRxEnabled.notify(TRUE);
+ }
+
+ event void Token.granted()
+ {
+ ASSERT(0); // should never happen
+ }
+
+ default event void FrameTx.transmitDone(ieee154_txframe_t *data, ieee154_status_t status) {}
+ default event message_t* FrameRx.received[uint8_t client](message_t* data) {return data;}
+ default async command bool IsRxEnableActive.getNow() {return FALSE;}
+
+ default async command void IndirectTxWaitAlarm.start(uint32_t dt) {ASSERT(0);}
+ default async command void IndirectTxWaitAlarm.stop() {ASSERT(0);}
+ default async command void IndirectTxWaitAlarm.startAt(uint32_t t0, uint32_t dt) {ASSERT(0);}
+
+ default async command void BroadcastAlarm.start(uint32_t dt) {ASSERT(0);}
+ default async command void BroadcastAlarm.stop() {ASSERT(0);}
+ default async command void BroadcastAlarm.startAt(uint32_t t0, uint32_t dt) {ASSERT(0);}
+
+ default async command bool SuperframeStructure.isBroadcastPending() { return FALSE;}
+ default async event void BroadcastTx.transmitNowDone(ieee154_txframe_t *frame, ieee154_status_t status) {}
+ default event message_t* FrameExtracted.received[uint8_t client](message_t* msg, ieee154_txframe_t *txFrame) {return msg;}
+ default async command error_t FrameBackup.setNow(ieee154_cap_frame_backup_t* val) {return FAIL;}
+ default async command ieee154_cap_frame_backup_t* FrameRestore.getNow() {return NULL;}
+ default command error_t TrackSingleBeacon.start() {return FAIL;}
+
+ command error_t WasRxEnabled.enable() {return FAIL;}
+ command error_t WasRxEnabled.disable() {return FAIL;}
+}
--- /dev/null
+/*
+ * Copyright (c) 2008, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+#include "TKN154_PHY.h"
+#include "TKN154_MAC.h"
+#include "TKN154_PIB.h"
+
+#define IEEE154_BEACON_ENABLED_PAN TRUE
+
+configuration TKN154BeaconEnabledP
+{
+ provides
+ {
+ /* MCPS-SAP */
+ interface MCPS_DATA;
+ interface MCPS_PURGE;
+ interface Packet;
+
+ /* MLME-SAP */
+ interface MLME_ASSOCIATE;
+ interface MLME_BEACON_NOTIFY;
+ interface MLME_COMM_STATUS;
+ interface MLME_DISASSOCIATE;
+ interface MLME_GET;
+/* interface MLME_GTS;*/
+ interface MLME_ORPHAN;
+ interface MLME_POLL;
+ interface MLME_RESET;
+ interface MLME_RX_ENABLE;
+ interface MLME_SCAN;
+ interface MLME_SET;
+ interface MLME_START;
+ interface MLME_SYNC;
+ interface MLME_SYNC_LOSS;
+
+ interface Notify<const void*> as PIBUpdate[uint8_t attributeID];
+ interface IEEE154Frame;
+ interface IEEE154BeaconFrame;
+ interface IEEE154TxBeaconPayload;
+ interface SplitControl as PromiscuousMode;
+ interface Get<uint64_t> as GetLocalExtendedAddress;
+ interface TimeCalc;
+ interface FrameUtility;
+
+ } uses {
+
+ interface RadioRx;
+ interface RadioTx;
+ interface RadioOff;
+ interface SlottedCsmaCa;
+ interface EnergyDetection;
+ interface SplitControl as PhySplitControl;
+ interface Set<bool> as RadioPromiscuousMode;
+
+ interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm1;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm2;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm3;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm4;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm5;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm6;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm7;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm8;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm9;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm10;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm11;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm12;
+
+ interface Timer<TSymbolIEEE802154> as Timer1;
+ interface Timer<TSymbolIEEE802154> as Timer2;
+ interface Timer<TSymbolIEEE802154> as Timer3;
+ interface Timer<TSymbolIEEE802154> as Timer4;
+ interface Timer<TSymbolIEEE802154> as Timer5;
+
+ interface LocalTime<TSymbolIEEE802154>;
+ interface Random;
+ interface Leds;
+ }
+}
+implementation
+{
+ components DataP,
+ PibP,
+ RadioControlP,
+ IndirectTxP,
+ PollP,
+
+#ifndef IEEE154_SCAN_DISABLED
+ ScanP,
+#else
+ NoScanP as ScanP,
+#endif
+
+#ifndef IEEE154_ASSOCIATION_DISABLED
+ AssociateP,
+#else
+ NoAssociateP as AssociateP,
+#endif
+
+#ifndef IEEE154_DISASSOCIATION_DISABLED
+ DisassociateP,
+#else
+ NoDisassociateP as DisassociateP,
+#endif
+
+#ifndef IEEE154_BEACON_SYNC_DISABLED
+ BeaconSynchronizeP,
+ new FrameDispatchQueueP() as DeviceCapQueue,
+ new SlottedFrameDispatchP(INCOMING_SUPERFRAME) as DeviceCap,
+#else
+ NoBeaconSynchronizeP as BeaconSynchronizeP,
+ new NoFrameDispatchQueueP() as DeviceCapQueue,
+ new NoSlottedFrameDispatchP(INCOMING_SUPERFRAME) as DeviceCap,
+#endif
+ NoDeviceCfpP as DeviceCfp,
+
+#ifndef IEEE154_BEACON_TX_DISABLED
+ BeaconTransmitP,
+ new FrameDispatchQueueP() as CoordCapQueue,
+ new SlottedFrameDispatchP(OUTGOING_SUPERFRAME) as CoordCap,
+#else
+ NoBeaconTransmitP as BeaconTransmitP,
+ new NoFrameDispatchQueueP() as CoordCapQueue,
+ new NoSlottedFrameDispatchP(OUTGOING_SUPERFRAME) as CoordCap,
+#endif
+ NoCoordCfpP as CoordCfp,
+
+#ifndef IEEE154_RXENABLE_DISABLED
+ RxEnableP,
+#else
+ NoRxEnableP as RxEnableP,
+#endif
+
+
+#ifndef IEEE154_PROMISCUOUS_MODE_DISABLED
+ PromiscuousModeP,
+#else
+ NoPromiscuousModeP as PromiscuousModeP,
+#endif
+
+#ifndef IEEE154_COORD_REALIGNMENT_DISABLED
+ CoordRealignmentP,
+#else
+ NoCoordRealignmentP as CoordRealignmentP,
+#endif
+
+#ifndef IEEE154_COORD_BROADCAST_DISABLED
+ CoordBroadcastP,
+#else
+ NoCoordBroadcastP as CoordBroadcastP,
+#endif
+
+ new PoolC(ieee154_txframe_t, TXFRAME_POOL_SIZE) as TxFramePoolP,
+ new PoolC(ieee154_txcontrol_t, TXCONTROL_POOL_SIZE) as TxControlPoolP,
+ new QueueC(ieee154_txframe_t*, CAP_TX_QUEUE_SIZE) as DeviceCapQueueC,
+ new QueueC(ieee154_txframe_t*, CAP_TX_QUEUE_SIZE) as CoordCapQueueC,
+ new QueueC(ieee154_txframe_t*, CAP_TX_QUEUE_SIZE) as BroadcastQueueC;
+
+ components MainC;
+
+ /* MCPS */
+ MCPS_DATA = DataP;
+ MCPS_PURGE = DataP;
+
+ /* MLME */
+ MLME_START = BeaconTransmitP;
+ MLME_ASSOCIATE = AssociateP;
+ MLME_DISASSOCIATE = DisassociateP;
+ MLME_BEACON_NOTIFY = BeaconSynchronizeP;
+ MLME_BEACON_NOTIFY = ScanP;
+ MLME_COMM_STATUS = AssociateP;
+ MLME_COMM_STATUS = CoordRealignmentP;
+ MLME_GET = PibP;
+ MLME_ORPHAN = CoordRealignmentP;
+ /* MLME_GTS = CfpTransmitP;*/
+ MLME_POLL = PollP;
+ MLME_RESET = PibP;
+ MLME_RX_ENABLE = RxEnableP;
+ MLME_SCAN = ScanP;
+ MLME_SET = PibP;
+ MLME_SYNC = BeaconSynchronizeP;
+ MLME_SYNC_LOSS = BeaconSynchronizeP;
+ IEEE154Frame = PibP;
+ IEEE154BeaconFrame = PibP;
+ PromiscuousMode = PromiscuousModeP;
+ GetLocalExtendedAddress = PibP.GetLocalExtendedAddress;
+ IEEE154TxBeaconPayload = BeaconTransmitP;
+ Packet = PibP;
+ TimeCalc = PibP;
+ FrameUtility = PibP;
+
+ /* ----------------------- Scanning (MLME-SCAN) ----------------------- */
+
+ components new RadioClientC() as ScanRadioClient;
+ PibP.MacReset -> ScanP;
+ ScanP.MLME_GET -> PibP;
+ ScanP.MLME_SET -> PibP.MLME_SET;
+ ScanP.EnergyDetection = EnergyDetection;
+ ScanP.RadioRx -> ScanRadioClient;
+ ScanP.RadioTx -> ScanRadioClient;
+ ScanP.Frame -> PibP;
+ ScanP.BeaconFrame -> PibP;
+ ScanP.RadioOff -> ScanRadioClient;
+ ScanP.ScanTimer = Timer1;
+ ScanP.TxFramePool -> TxFramePoolP;
+ ScanP.TxControlPool -> TxControlPoolP;
+ ScanP.Token -> ScanRadioClient;
+ ScanP.Leds = Leds;
+ ScanP.FrameUtility -> PibP;
+
+ /* ----------------- Beacon Transmission (MLME-START) ----------------- */
+
+ components new RadioClientC() as BeaconTxRadioClient;
+ PibP.MacReset -> BeaconTransmitP;
+ BeaconTransmitP.PIBUpdate[IEEE154_macAssociationPermit] -> PibP.PIBUpdate[IEEE154_macAssociationPermit];
+ BeaconTransmitP.PIBUpdate[IEEE154_macGTSPermit] -> PibP.PIBUpdate[IEEE154_macGTSPermit];
+ BeaconTransmitP.BeaconSendAlarm = Alarm1;
+ BeaconTransmitP.BeaconPayloadUpdateTimer = Timer2;
+ BeaconTransmitP.RadioOff -> BeaconTxRadioClient;
+ BeaconTransmitP.BeaconTx -> BeaconTxRadioClient;
+ BeaconTransmitP.MLME_SET -> PibP.MLME_SET;
+ BeaconTransmitP.MLME_GET -> PibP;
+ BeaconTransmitP.SetMacSuperframeOrder -> PibP.SetMacSuperframeOrder;
+ BeaconTransmitP.SetMacBeaconTxTime -> PibP.SetMacBeaconTxTime;
+ BeaconTransmitP.SetMacPanCoordinator -> PibP.SetMacPanCoordinator;
+ BeaconTransmitP.Token -> BeaconTxRadioClient;
+ BeaconTransmitP.IsTokenRequested -> BeaconTxRadioClient;
+ BeaconTransmitP.TokenTransferred -> BeaconTxRadioClient;
+ BeaconTransmitP.TokenToBroadcast -> BeaconTxRadioClient;
+ BeaconTransmitP.RealignmentBeaconEnabledTx -> CoordBroadcastP.RealignmentTx;
+ BeaconTransmitP.RealignmentNonBeaconEnabledTx -> CoordCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
+ BeaconTransmitP.BeaconRequestRx -> CoordCap.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_BEACON_REQUEST];
+ BeaconTransmitP.GtsInfoWrite -> CoordCfp.GtsInfoWrite;
+ BeaconTransmitP.PendingAddrSpecUpdated -> IndirectTxP.PendingAddrSpecUpdated;
+ BeaconTransmitP.PendingAddrWrite -> IndirectTxP.PendingAddrWrite;
+ BeaconTransmitP.FrameUtility -> PibP.FrameUtility;
+ BeaconTransmitP.IsTrackingBeacons -> BeaconSynchronizeP.IsTrackingBeacons;
+ BeaconTransmitP.IncomingSF -> BeaconSynchronizeP.IncomingSF;
+ BeaconTransmitP.GetSetRealignmentFrame -> CoordRealignmentP;
+ BeaconTransmitP.IsBroadcastReady -> CoordBroadcastP.IsBroadcastReady;
+ BeaconTransmitP.TimeCalc -> PibP;
+ BeaconTransmitP.Leds = Leds;
+ BeaconTxRadioClient.TransferTo -> CoordBroadcastRadioClient.TransferFrom;
+
+ /* ------------------ Beacon Tracking (MLME-SYNC) ------------------ */
+
+ components new RadioClientC() as SyncRadioClient;
+ PibP.MacReset -> BeaconSynchronizeP;
+ BeaconSynchronizeP.MLME_SET -> PibP.MLME_SET;
+ BeaconSynchronizeP.MLME_GET -> PibP;
+ BeaconSynchronizeP.TrackAlarm = Alarm2;
+ BeaconSynchronizeP.FrameUtility -> PibP;
+ BeaconSynchronizeP.Frame -> PibP;
+ BeaconSynchronizeP.BeaconFrame -> PibP;
+ BeaconSynchronizeP.BeaconRx -> SyncRadioClient;
+ BeaconSynchronizeP.RadioOff -> SyncRadioClient;
+ BeaconSynchronizeP.DataRequest -> PollP.DataRequest[SYNC_POLL_CLIENT];
+ BeaconSynchronizeP.Token -> SyncRadioClient;
+ BeaconSynchronizeP.IsTokenRequested -> SyncRadioClient;
+ BeaconSynchronizeP.TokenTransferred -> SyncRadioClient;
+ BeaconSynchronizeP.TokenToCap -> SyncRadioClient;
+ BeaconSynchronizeP.TimeCalc -> PibP;
+ BeaconSynchronizeP.CoordRealignmentRx -> DeviceCap.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_COORDINATOR_REALIGNMENT];
+ BeaconSynchronizeP.Leds = Leds;
+ SyncRadioClient.TransferTo -> DeviceCapRadioClient.TransferFrom;
+
+ /* -------------------- Association (MLME-ASSOCIATE) -------------------- */
+
+ PibP.MacReset -> AssociateP;
+ AssociateP.AssociationRequestRx -> CoordCap.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_ASSOCIATION_REQUEST];
+ AssociateP.AssociationRequestTx -> DeviceCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
+ AssociateP.AssociationResponseExtracted -> DeviceCap.FrameExtracted[FC1_FRAMETYPE_CMD + CMD_FRAME_ASSOCIATION_RESPONSE];
+ AssociateP.AssociationResponseTx -> IndirectTxP.FrameTx[unique(INDIRECT_TX_CLIENT)];
+ AssociateP.DataRequest -> PollP.DataRequest[ASSOCIATE_POLL_CLIENT];
+ AssociateP.ResponseTimeout = Timer3;
+ AssociateP.TxFramePool -> TxFramePoolP;
+ AssociateP.TxControlPool -> TxControlPoolP;
+ AssociateP.MLME_GET -> PibP;
+ AssociateP.MLME_SET -> PibP.MLME_SET;
+ AssociateP.FrameUtility -> PibP;
+ AssociateP.Frame -> PibP;
+ AssociateP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress;
+
+ /* --------------- Disassociation (MLME-DISASSOCIATE) --------------- */
+
+ PibP.MacReset -> DisassociateP;
+ DisassociateP.DisassociationIndirectTx -> IndirectTxP.FrameTx[unique(INDIRECT_TX_CLIENT)];
+ DisassociateP.DisassociationDirectTx -> CoordCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
+ DisassociateP.DisassociationToCoord -> DeviceCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
+ DisassociateP.DisassociationDirectRxFromCoord ->
+ DeviceCap.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_DISASSOCIATION_NOTIFICATION];
+ DisassociateP.DisassociationExtractedFromCoord ->
+ DeviceCap.FrameExtracted[FC1_FRAMETYPE_CMD + CMD_FRAME_DISASSOCIATION_NOTIFICATION];
+ DisassociateP.DisassociationRxFromDevice ->
+ CoordCap.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_DISASSOCIATION_NOTIFICATION];
+ DisassociateP.TxFramePool -> TxFramePoolP;
+ DisassociateP.TxControlPool -> TxControlPoolP;
+ DisassociateP.MLME_GET -> PibP;
+ DisassociateP.FrameUtility -> PibP;
+ DisassociateP.Frame -> PibP;
+ DisassociateP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress;
+
+ /* ------------------ Data Transmission (MCPS-DATA) ------------------- */
+
+ DataP.IsSendingBeacons -> BeaconTransmitP.IsSendingBeacons;
+ DataP.CoordCapRx -> CoordCap.FrameRx[FC1_FRAMETYPE_DATA];
+ DataP.DeviceCapTx -> DeviceCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
+ DataP.CoordCapTx -> CoordCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
+ DataP.DeviceCapRx -> PollP.DataRx;
+ DataP.DeviceCapRx -> PromiscuousModeP.FrameRx;
+ DataP.DeviceCapRx -> DeviceCap.FrameRx[FC1_FRAMETYPE_DATA];
+ DataP.TxFramePool -> TxFramePoolP;
+ DataP.BroadcastTx -> CoordBroadcastP.BroadcastDataFrame;
+ DataP.DeviceCfpTx -> DeviceCfp.CfpTx;
+ DataP.IndirectTx -> IndirectTxP.FrameTx[unique(INDIRECT_TX_CLIENT)];
+ DataP.FrameUtility -> PibP;
+ DataP.Frame -> PibP;
+ DataP.PurgeDirect -> DeviceCapQueue;
+ DataP.PurgeIndirect -> IndirectTxP;
+ DataP.PurgeGtsDevice -> DeviceCfp;
+ DataP.PurgeGtsCoord -> CoordCfp;
+ DataP.MLME_GET -> PibP;
+ DataP.Packet -> PibP;
+ DataP.Leds = Leds;
+
+ /* ------------------------ Polling (MLME-POLL) ----------------------- */
+
+ PibP.MacReset -> PollP;
+ PollP.PollTx -> DeviceCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
+ PollP.DataExtracted -> DeviceCap.FrameExtracted[FC1_FRAMETYPE_DATA];
+ PollP.FrameUtility -> PibP;
+ PollP.TxFramePool -> TxFramePoolP;
+ PollP.TxControlPool -> TxControlPoolP;
+ PollP.MLME_GET -> PibP;
+ PollP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress;
+
+ /* ---------------------- Indirect transmission ----------------------- */
+
+ PibP.MacReset -> IndirectTxP;
+ IndirectTxP.CoordCapTx -> CoordCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
+ IndirectTxP.DataRequestRx -> CoordCap.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_DATA_REQUEST];
+ IndirectTxP.MLME_GET -> PibP;
+ IndirectTxP.FrameUtility -> PibP;
+ IndirectTxP.IndirectTxTimeout = Timer4;
+ IndirectTxP.TimeCalc -> PibP;
+ IndirectTxP.Leds = Leds;
+
+ /* ---------------------------- Realignment --------------------------- */
+
+ PibP.MacReset -> CoordRealignmentP;
+ CoordRealignmentP.CoordRealignmentTx -> CoordCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
+ CoordRealignmentP.OrphanNotificationRx -> CoordCap.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_ORPHAN_NOTIFICATION];
+ CoordRealignmentP.FrameUtility -> PibP;
+ CoordRealignmentP.Frame -> PibP;
+ CoordRealignmentP.TxFramePool -> TxFramePoolP;
+ CoordRealignmentP.TxControlPool -> TxControlPoolP;
+ CoordRealignmentP.MLME_GET -> PibP;
+ CoordRealignmentP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress;
+
+ /* ---------------------------- Broadcasts ---------------------------- */
+
+ components new RadioClientC() as CoordBroadcastRadioClient;
+ PibP.MacReset -> CoordBroadcastP;
+ CoordBroadcastP.TokenTransferred -> CoordBroadcastRadioClient;
+ CoordBroadcastP.TokenToCap -> CoordBroadcastRadioClient;
+ CoordBroadcastRadioClient.TransferTo -> CoordCapRadioClient.TransferFrom;
+ CoordBroadcastP.OutgoingSF -> BeaconTransmitP.OutgoingSF;
+ CoordBroadcastP.CapTransmitNow -> CoordCap.BroadcastTx;
+ CoordBroadcastP.Queue -> BroadcastQueueC;
+ CoordBroadcastP.Leds = Leds;
+
+ /* --------------------- CAP (incoming superframe) -------------------- */
+
+ PibP.FrameDispatchQueueReset -> DeviceCapQueue;
+ DeviceCapQueue.Queue -> DeviceCapQueueC;
+ DeviceCapQueue.FrameTxCsma -> DeviceCap;
+
+ PibP.FrameDispatchQueueReset -> CoordCapQueue;
+ CoordCapQueue.Queue -> CoordCapQueueC;
+ CoordCapQueue.FrameTxCsma -> CoordCap;
+
+ components new RadioClientC() as DeviceCapRadioClient;
+ PibP.FrameDispatchReset -> DeviceCap;
+ DeviceCap.CapEndAlarm = Alarm3;
+ DeviceCap.BLEAlarm = Alarm4;
+ DeviceCap.IndirectTxWaitAlarm = Alarm5;
+ DeviceCap.BroadcastAlarm = Alarm6;
+ DeviceCap.Token -> DeviceCapRadioClient;
+ DeviceCap.IsTokenRequested -> DeviceCapRadioClient;
+ DeviceCap.TokenToCfp -> DeviceCapRadioClient;
+ DeviceCap.TokenTransferred -> DeviceCapRadioClient;
+ DeviceCap.SuperframeStructure -> BeaconSynchronizeP.IncomingSF;
+ DeviceCap.IsRxEnableActive -> RxEnableP.IsRxEnableActive;
+ DeviceCap.GetIndirectTxFrame -> IndirectTxP;
+ DeviceCap.RxEnableStateChange -> RxEnableP.RxEnableStateChange;
+ DeviceCap.IsTrackingBeacons -> BeaconSynchronizeP.IsTrackingBeacons;
+ DeviceCap.FrameUtility -> PibP;
+ DeviceCap.SlottedCsmaCa -> DeviceCapRadioClient;
+ DeviceCap.RadioRx -> DeviceCapRadioClient;
+ DeviceCap.RadioOff -> DeviceCapRadioClient;
+ DeviceCap.MLME_GET -> PibP;
+ DeviceCap.MLME_SET -> PibP.MLME_SET;
+ DeviceCap.TimeCalc -> PibP;
+ DeviceCap.Leds = Leds;
+ DeviceCap.TrackSingleBeacon -> BeaconSynchronizeP.TrackSingleBeacon;
+ DeviceCapRadioClient.TransferTo -> DeviceCfpRadioClient.TransferFrom;
+
+ /* ---------------------- CAP (outgoing superframe) ------------------- */
+
+ components new RadioClientC() as CoordCapRadioClient,
+ new BackupP(ieee154_cap_frame_backup_t);
+ PibP.FrameDispatchReset -> CoordCap;
+ CoordCap.CapEndAlarm = Alarm7;
+ CoordCap.BLEAlarm = Alarm8;
+ CoordCap.Token -> CoordCapRadioClient;
+ CoordCap.TokenToCfp -> CoordCapRadioClient;
+ CoordCap.TokenTransferred -> CoordCapRadioClient;
+ CoordCap.IsTokenRequested -> CoordCapRadioClient;
+ CoordCap.SuperframeStructure -> BeaconTransmitP.OutgoingSF;
+ CoordCap.IsRxEnableActive -> RxEnableP.IsRxEnableActive;
+ CoordCap.GetIndirectTxFrame -> IndirectTxP;
+ CoordCap.RxEnableStateChange -> RxEnableP.RxEnableStateChange;
+ CoordCap.IsTrackingBeacons -> BeaconSynchronizeP.IsTrackingBeacons;
+ CoordCap.FrameUtility -> PibP;
+ CoordCap.SlottedCsmaCa -> CoordCapRadioClient;
+ CoordCap.RadioRx -> CoordCapRadioClient;
+ CoordCap.RadioOff -> CoordCapRadioClient;
+ CoordCap.MLME_GET -> PibP;
+ CoordCap.MLME_SET -> PibP.MLME_SET;
+ CoordCap.TimeCalc -> PibP;
+ CoordCap.Leds = Leds;
+ CoordCapRadioClient.TransferTo -> CoordCfpRadioClient.TransferFrom;
+ CoordCap.FrameBackup -> BackupP;
+ CoordCap.FrameRestore -> BackupP;
+
+ /* -------------------- GTS (incoming superframe) --------------------- */
+
+ components new RadioClientC() as DeviceCfpRadioClient;
+ PibP.MacReset -> DeviceCfp;
+ DeviceCfp.TokenTransferred -> DeviceCfpRadioClient;
+ DeviceCfp.TokenRequested -> DeviceCfpRadioClient;
+ DeviceCfp.TokenToBeaconSync -> DeviceCfpRadioClient;
+ DeviceCfp.IncomingSF -> BeaconSynchronizeP.IncomingSF;
+ DeviceCfp.CfpSlotAlarm = Alarm9;
+ DeviceCfp.CfpEndAlarm = Alarm10;
+ DeviceCfp.RadioTx -> DeviceCfpRadioClient;
+ DeviceCfp.RadioRx -> DeviceCfpRadioClient;
+ DeviceCfp.RadioOff -> DeviceCfpRadioClient;
+ DeviceCfp.MLME_GET -> PibP;
+ DeviceCfp.MLME_SET -> PibP.MLME_SET;
+ DeviceCfpRadioClient.TransferTo -> SyncRadioClient.TransferFrom;
+
+ /* -------------------- GTS (outgoing superframe) --------------------- */
+
+ components new RadioClientC() as CoordCfpRadioClient;
+ PibP.MacReset -> CoordCfp;
+ CoordCfp.TokenTransferred -> CoordCfpRadioClient;
+ CoordCfp.TokenRequested -> CoordCfpRadioClient;
+ CoordCfp.TokenToBeaconTransmit -> CoordCfpRadioClient;
+ CoordCfp.OutgoingSF -> BeaconTransmitP.OutgoingSF;
+ CoordCfp.CfpSlotAlarm = Alarm11;
+ CoordCfp.CfpEndAlarm = Alarm12;
+ CoordCfp.RadioTx -> CoordCfpRadioClient;
+ CoordCfp.RadioRx -> CoordCfpRadioClient;
+ CoordCfp.RadioOff -> CoordCfpRadioClient;
+ CoordCfp.MLME_GET -> PibP;
+ CoordCfp.MLME_SET -> PibP.MLME_SET;
+ CoordCfpRadioClient.TransferTo -> BeaconTxRadioClient.TransferFrom;
+
+ /* -------------------------- promiscuous mode ------------------------ */
+
+ components new RadioClientC() as PromiscuousModeRadioClient;
+ PibP.MacReset -> PromiscuousModeP;
+ PromiscuousModeP.Token -> PromiscuousModeRadioClient;
+ PromiscuousModeP.PromiscuousRx -> PromiscuousModeRadioClient;
+ PromiscuousModeP.RadioOff -> PromiscuousModeRadioClient;
+ PromiscuousModeP.RadioPromiscuousMode = RadioPromiscuousMode;
+
+ /* --------------------------- MLME-RX-ENABLE ------------------------ */
+
+ PibP.MacReset -> RxEnableP;
+ RxEnableP.IncomingSuperframeStructure -> BeaconSynchronizeP;
+ RxEnableP.OutgoingSuperframeStructure -> BeaconTransmitP;
+ RxEnableP.IsTrackingBeacons -> BeaconSynchronizeP.IsTrackingBeacons;
+ RxEnableP.IsSendingBeacons-> BeaconTransmitP.IsSendingBeacons;
+ RxEnableP.TimeCalc -> PibP.TimeCalc;
+ RxEnableP.WasRxEnabled -> DeviceCap.WasRxEnabled;
+ RxEnableP.WasRxEnabled -> CoordCap.WasRxEnabled;
+ RxEnableP.RxEnableTimer = Timer5;
+
+ /* ------------------------------- PIB -------------------------------- */
+
+ components new RadioClientC() as PibRadioClient;
+ PIBUpdate = PibP;
+ MainC.SoftwareInit -> PibP.LocalInit;
+ PibP.RadioControl = PhySplitControl;
+ PibP.Random = Random;
+ PibP.PromiscuousModeGet -> PromiscuousModeP;
+ PibP.LocalTime = LocalTime;
+ PibP.Token -> PibRadioClient;
+ PibP.RadioOff -> PibRadioClient;
+
+ /* ------------------------- Radio Control ---------------------------- */
+
+ RadioControlP.PhyTx = RadioTx;
+ RadioControlP.PhySlottedCsmaCa = SlottedCsmaCa;
+ RadioControlP.PhyRx = RadioRx;
+ RadioControlP.PhyRadioOff = RadioOff;
+ RadioControlP.RadioPromiscuousMode -> PromiscuousModeP;
+ RadioControlP.Leds = Leds;
+}
--- /dev/null
+/*
+ * Copyright (c) 2008, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+#include "TKN154_PHY.h"
+#include "TKN154_MAC.h"
+#include "TKN154_PIB.h"
+
+#define IEEE154_BEACON_ENABLED_PAN FALSE
+
+// TODO: check the wiring!!
+
+configuration TKN154NonBeaconEnabledP
+{
+ provides
+ {
+ /* MCPS-SAP */
+ interface MCPS_DATA;
+ interface MCPS_PURGE;
+ interface Packet;
+
+ /* MLME-SAP */
+ interface MLME_ASSOCIATE;
+ interface MLME_BEACON_NOTIFY;
+ interface MLME_COMM_STATUS;
+ interface MLME_DISASSOCIATE;
+ interface MLME_GET;
+ interface MLME_ORPHAN;
+ interface MLME_POLL;
+ interface MLME_RESET;
+ interface MLME_RX_ENABLE;
+ interface MLME_SCAN;
+ interface MLME_SET;
+ interface MLME_START;
+
+ interface Notify<const void*> as PIBUpdate[uint8_t attributeID];
+ interface IEEE154Frame;
+ interface IEEE154BeaconFrame;
+ interface SplitControl as PromiscuousMode;
+ interface Get<uint64_t> as GetLocalExtendedAddress;
+ interface TimeCalc;
+ interface FrameUtility;
+
+ } uses {
+
+ interface RadioRx;
+ interface RadioTx;
+ interface RadioOff;
+ interface UnslottedCsmaCa;
+ interface EnergyDetection;
+ interface SplitControl as PhySplitControl;
+ interface Set<bool> as RadioPromiscuousMode;
+
+ interface Timer<TSymbolIEEE802154> as Timer1;
+ interface Timer<TSymbolIEEE802154> as Timer2;
+ interface Timer<TSymbolIEEE802154> as Timer3;
+ interface Timer<TSymbolIEEE802154> as Timer4;
+ interface Timer<TSymbolIEEE802154> as Timer5;
+
+ interface LocalTime<TSymbolIEEE802154>;
+ interface Random;
+ interface Leds;
+ }
+}
+implementation
+{
+ components DataP,
+ PibP,
+ RadioControlP,
+ IndirectTxP,
+ PollP,
+
+#ifndef IEEE154_SCAN_DISABLED
+ ScanP,
+#else
+ NoScanP as ScanP,
+#endif
+
+#ifndef IEEE154_ASSOCIATION_DISABLED
+ AssociateP,
+#else
+ NoAssociateP as AssociateP,
+#endif
+
+#ifndef IEEE154_DISASSOCIATION_DISABLED
+ DisassociateP,
+#else
+ NoDisassociateP as DisassociateP,
+#endif
+ new FrameDispatchQueueP() as FrameDispatchQueueP,
+ UnslottedFrameDispatchP as FrameDispatchP,
+
+#ifndef IEEE154_RXENABLE_DISABLED
+ RxEnableP,
+#else
+ NoRxEnableP as RxEnableP,
+#endif
+
+
+#ifndef IEEE154_PROMISCUOUS_MODE_DISABLED
+ PromiscuousModeP,
+#else
+ NoPromiscuousModeP as PromiscuousModeP,
+#endif
+
+#ifndef IEEE154_COORD_REALIGNMENT_DISABLED
+ CoordRealignmentP,
+#else
+ NoCoordRealignmentP as CoordRealignmentP,
+#endif
+
+ new PoolC(ieee154_txframe_t, TXFRAME_POOL_SIZE) as TxFramePoolP,
+ new PoolC(ieee154_txcontrol_t, TXCONTROL_POOL_SIZE) as TxControlPoolP,
+ new QueueC(ieee154_txframe_t*, CAP_TX_QUEUE_SIZE) as FrameDispatchQueueC;
+
+ components MainC;
+
+ /* MCPS */
+ MCPS_DATA = DataP;
+ MCPS_PURGE = DataP;
+
+ /* MLME */
+ MLME_START = FrameDispatchP;
+ MLME_ASSOCIATE = AssociateP;
+ MLME_DISASSOCIATE = DisassociateP;
+ MLME_BEACON_NOTIFY = ScanP;
+ MLME_COMM_STATUS = AssociateP;
+ MLME_COMM_STATUS = CoordRealignmentP;
+ MLME_GET = PibP;
+ MLME_ORPHAN = CoordRealignmentP;
+ MLME_POLL = PollP;
+ MLME_RESET = PibP;
+ MLME_RX_ENABLE = RxEnableP;
+ MLME_SCAN = ScanP;
+ MLME_SET = PibP;
+ IEEE154Frame = PibP;
+ IEEE154BeaconFrame = PibP;
+ PromiscuousMode = PromiscuousModeP;
+ GetLocalExtendedAddress = PibP.GetLocalExtendedAddress;
+ Packet = PibP;
+ TimeCalc = PibP;
+ FrameUtility = PibP;
+
+ /* ----------------------- Scanning (MLME-SCAN) ----------------------- */
+
+ components new RadioClientC() as ScanRadioClient;
+ PibP.MacReset -> ScanP;
+ ScanP.MLME_GET -> PibP;
+ ScanP.MLME_SET -> PibP.MLME_SET;
+ ScanP.EnergyDetection = EnergyDetection;
+ ScanP.RadioRx -> ScanRadioClient;
+ ScanP.RadioTx -> ScanRadioClient;
+ ScanP.Frame -> PibP;
+ ScanP.BeaconFrame -> PibP;
+ ScanP.RadioOff -> ScanRadioClient;
+ ScanP.ScanTimer = Timer1;
+ ScanP.TxFramePool -> TxFramePoolP;
+ ScanP.TxControlPool -> TxControlPoolP;
+ ScanP.Token -> ScanRadioClient;
+ ScanP.Leds = Leds;
+ ScanP.FrameUtility -> PibP;
+
+ /* -------------------- Association (MLME-ASSOCIATE) -------------------- */
+
+ PibP.MacReset -> AssociateP;
+ AssociateP.AssociationRequestRx -> FrameDispatchP.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_ASSOCIATION_REQUEST];
+ AssociateP.AssociationRequestTx -> FrameDispatchQueueP.FrameTx[unique(CAP_TX_CLIENT)];
+ AssociateP.AssociationResponseExtracted -> FrameDispatchP.FrameExtracted[FC1_FRAMETYPE_CMD + CMD_FRAME_ASSOCIATION_RESPONSE];
+ AssociateP.AssociationResponseTx -> IndirectTxP.FrameTx[unique(INDIRECT_TX_CLIENT)];
+ AssociateP.DataRequest -> PollP.DataRequest[ASSOCIATE_POLL_CLIENT];
+ AssociateP.ResponseTimeout = Timer2;
+ AssociateP.TxFramePool -> TxFramePoolP;
+ AssociateP.TxControlPool -> TxControlPoolP;
+ AssociateP.MLME_GET -> PibP;
+ AssociateP.MLME_SET -> PibP.MLME_SET;
+ AssociateP.FrameUtility -> PibP;
+ AssociateP.Frame -> PibP;
+ AssociateP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress;
+
+ /* --------------- Disassociation (MLME-DISASSOCIATE) --------------- */
+
+ PibP.MacReset -> DisassociateP;
+ DisassociateP.DisassociationIndirectTx -> IndirectTxP.FrameTx[unique(INDIRECT_TX_CLIENT)];
+ DisassociateP.DisassociationDirectTx -> FrameDispatchQueueP.FrameTx[unique(CAP_TX_CLIENT)];
+ DisassociateP.DisassociationToCoord -> FrameDispatchQueueP.FrameTx[unique(CAP_TX_CLIENT)];
+ DisassociateP.DisassociationExtractedFromCoord ->
+ FrameDispatchP.FrameExtracted[FC1_FRAMETYPE_CMD + CMD_FRAME_DISASSOCIATION_NOTIFICATION];
+ DisassociateP.DisassociationRxFromDevice ->
+ FrameDispatchP.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_DISASSOCIATION_NOTIFICATION];
+ DisassociateP.TxFramePool -> TxFramePoolP;
+ DisassociateP.TxControlPool -> TxControlPoolP;
+ DisassociateP.MLME_GET -> PibP;
+ DisassociateP.FrameUtility -> PibP;
+ DisassociateP.Frame -> PibP;
+ DisassociateP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress;
+
+ /* ------------------ Data Transmission (MCPS-DATA) ------------------- */
+
+ DataP.DeviceCapTx -> FrameDispatchQueueP.FrameTx[unique(CAP_TX_CLIENT)];
+ DataP.CoordCapTx -> FrameDispatchQueueP.FrameTx[unique(CAP_TX_CLIENT)];
+ DataP.DeviceCapRx -> PollP.DataRx;
+ DataP.DeviceCapRx -> PromiscuousModeP.FrameRx;
+ DataP.TxFramePool -> TxFramePoolP;
+ DataP.IndirectTx -> IndirectTxP.FrameTx[unique(INDIRECT_TX_CLIENT)];
+ DataP.FrameUtility -> PibP;
+ DataP.Frame -> PibP;
+ DataP.PurgeDirect -> FrameDispatchQueueP;
+ DataP.PurgeIndirect -> IndirectTxP;
+ DataP.MLME_GET -> PibP;
+ DataP.Packet -> PibP;
+ DataP.Leds = Leds;
+
+ /* ------------------------ Polling (MLME-POLL) ----------------------- */
+
+ PibP.MacReset -> PollP;
+ PollP.PollTx -> FrameDispatchQueueP.FrameTx[unique(CAP_TX_CLIENT)];
+ PollP.DataExtracted -> FrameDispatchP.FrameExtracted[FC1_FRAMETYPE_DATA];
+ PollP.FrameUtility -> PibP;
+ PollP.TxFramePool -> TxFramePoolP;
+ PollP.TxControlPool -> TxControlPoolP;
+ PollP.MLME_GET -> PibP;
+ PollP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress;
+
+ /* ---------------------- Indirect transmission ----------------------- */
+
+ PibP.MacReset -> IndirectTxP;
+ IndirectTxP.CoordCapTx -> FrameDispatchQueueP.FrameTx[unique(CAP_TX_CLIENT)];
+ IndirectTxP.DataRequestRx -> FrameDispatchP.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_DATA_REQUEST];
+ IndirectTxP.MLME_GET -> PibP;
+ IndirectTxP.FrameUtility -> PibP;
+ IndirectTxP.IndirectTxTimeout = Timer3;
+ IndirectTxP.TimeCalc -> PibP;
+ IndirectTxP.Leds = Leds;
+
+ /* ---------------------------- Realignment --------------------------- */
+
+ PibP.MacReset -> CoordRealignmentP;
+ CoordRealignmentP.CoordRealignmentTx -> FrameDispatchQueueP.FrameTx[unique(CAP_TX_CLIENT)];
+ CoordRealignmentP.OrphanNotificationRx -> FrameDispatchP.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_ORPHAN_NOTIFICATION];
+ CoordRealignmentP.FrameUtility -> PibP;
+ CoordRealignmentP.Frame -> PibP;
+ CoordRealignmentP.TxFramePool -> TxFramePoolP;
+ CoordRealignmentP.TxControlPool -> TxControlPoolP;
+ CoordRealignmentP.MLME_GET -> PibP;
+ CoordRealignmentP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress;
+
+ /* --------------------- FrameDispatchP -------------------- */
+
+ PibP.FrameDispatchReset -> FrameDispatchP;
+ PibP.FrameDispatchQueueReset -> FrameDispatchQueueP;
+ FrameDispatchQueueP.Queue -> FrameDispatchQueueC;
+ FrameDispatchQueueP.FrameTxCsma -> FrameDispatchP;
+
+ components new RadioClientC() as FrameDispatchRadioClient;
+ PibP.FrameDispatchReset -> FrameDispatchP;
+ FrameDispatchP.IndirectTxWaitTimer = Timer4;
+ FrameDispatchP.Token -> FrameDispatchRadioClient;
+ FrameDispatchP.SetMacSuperframeOrder -> PibP.SetMacSuperframeOrder;
+ FrameDispatchP.SetMacPanCoordinator -> PibP.SetMacPanCoordinator;
+ FrameDispatchP.IsTokenRequested -> FrameDispatchRadioClient;
+ FrameDispatchP.IsRxEnableActive -> RxEnableP.IsRxEnableActive;
+ FrameDispatchP.GetIndirectTxFrame -> IndirectTxP;
+ FrameDispatchP.RxEnableStateChange -> RxEnableP.RxEnableStateChange;
+ FrameDispatchP.FrameUtility -> PibP;
+ FrameDispatchP.UnslottedCsmaCa -> FrameDispatchRadioClient;
+ FrameDispatchP.RadioRx -> FrameDispatchRadioClient;
+ FrameDispatchP.RadioOff -> FrameDispatchRadioClient;
+ FrameDispatchP.MLME_GET -> PibP;
+ FrameDispatchP.MLME_SET -> PibP.MLME_SET;
+ FrameDispatchP.TimeCalc -> PibP;
+ FrameDispatchP.Leds = Leds;
+
+ /* -------------------------- promiscuous mode ------------------------ */
+
+ components new RadioClientC() as PromiscuousModeRadioClient;
+ PibP.MacReset -> PromiscuousModeP;
+ PromiscuousModeP.Token -> PromiscuousModeRadioClient;
+ PromiscuousModeP.PromiscuousRx -> PromiscuousModeRadioClient;
+ PromiscuousModeP.RadioOff -> PromiscuousModeRadioClient;
+ PromiscuousModeP.RadioPromiscuousMode = RadioPromiscuousMode;
+
+ /* --------------------------- MLME-RX-ENABLE ------------------------ */
+
+ PibP.MacReset -> RxEnableP;
+ RxEnableP.TimeCalc -> PibP.TimeCalc;
+ RxEnableP.WasRxEnabled -> FrameDispatchP.WasRxEnabled;
+ RxEnableP.WasRxEnabled -> FrameDispatchP.WasRxEnabled;
+ RxEnableP.RxEnableTimer = Timer5;
+
+ /* ------------------------------- PIB -------------------------------- */
+
+ components new RadioClientC() as PibRadioClient;
+ PIBUpdate = PibP;
+ MainC.SoftwareInit -> PibP.LocalInit;
+ PibP.RadioControl = PhySplitControl;
+ PibP.Random = Random;
+ PibP.PromiscuousModeGet -> PromiscuousModeP;
+ PibP.LocalTime = LocalTime;
+ PibP.Token -> PibRadioClient;
+ PibP.RadioOff -> PibRadioClient;
+
+ /* ------------------------- Radio Control ---------------------------- */
+
+ RadioControlP.PhyTx = RadioTx;
+ RadioControlP.PhyUnslottedCsmaCa = UnslottedCsmaCa;
+ RadioControlP.PhyRx = RadioRx;
+ RadioControlP.PhyRadioOff = RadioOff;
+ RadioControlP.RadioPromiscuousMode -> PromiscuousModeP;
+ RadioControlP.Leds = Leds;
+}
+++ /dev/null
-/*
- * Copyright (c) 2008, Technische Universitaet Berlin
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * - Neither the name of the Technische Universitaet Berlin nor the names
- * of its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * - Revision -------------------------------------------------------------
- * $Revision$
- * $Date$
- * @author Jan Hauer <hauer@tkn.tu-berlin.de>
- * ========================================================================
- */
-
-#include "TKN154_PHY.h"
-#include "TKN154_MAC.h"
-#include "TKN154_PIB.h"
-#include "TKN154_DEBUG.h"
-
-configuration TKN154P
-{
- provides
- {
- // MCPS-SAP
- interface MCPS_DATA;
- interface MCPS_PURGE;
- interface Packet;
-
- // MLME-SAP
- interface MLME_ASSOCIATE;
- interface MLME_BEACON_NOTIFY;
- interface MLME_COMM_STATUS;
- interface MLME_DISASSOCIATE;
- interface MLME_GET;
-/* interface MLME_GTS;*/
- interface MLME_ORPHAN;
- interface MLME_POLL;
- interface MLME_RESET;
- interface MLME_RX_ENABLE;
- interface MLME_SCAN;
- interface MLME_SET;
- interface MLME_START;
- interface MLME_SYNC;
- interface MLME_SYNC_LOSS;
-
- interface Notify<const void*> as PIBUpdate[uint8_t attributeID];
- interface IEEE154Frame;
- interface IEEE154BeaconFrame;
- interface IEEE154TxBeaconPayload;
- interface SplitControl as PromiscuousMode;
- interface Get<uint64_t> as GetLocalExtendedAddress;
- interface TimeCalc;
- interface FrameUtility;
-
- } uses {
-
- interface RadioRx;
- interface RadioTx;
- interface RadioOff;
- interface EnergyDetection;
- interface SplitControl as PhySplitControl;
- interface Set<bool> as RadioPromiscuousMode;
-
- interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm1;
- interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm2;
- interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm3;
- interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm4;
- interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm5;
- interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm6;
- interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm7;
- interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm8;
- interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm9;
- interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm10;
- interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm11;
- interface Alarm<TSymbolIEEE802154,uint32_t> as Alarm12;
-
- interface Timer<TSymbolIEEE802154> as Timer1;
- interface Timer<TSymbolIEEE802154> as Timer2;
- interface Timer<TSymbolIEEE802154> as Timer3;
- interface Timer<TSymbolIEEE802154> as Timer4;
- interface Timer<TSymbolIEEE802154> as Timer5;
-
- interface Ieee802154Debug[uint8_t client];
- interface LocalTime<TSymbolIEEE802154>;
- interface Random;
- interface Leds;
- }
-}
-implementation
-{
- components DataP,
- PibP,
- RadioControlP,
- IndirectTxP,
- PollP,
-
-#ifndef IEEE154_SCAN_DISABLED
- ScanP,
-#else
- NoScanP as ScanP,
-#endif
-
-#ifndef IEEE154_ASSOCIATION_DISABLED
- AssociateP,
-#else
- NoAssociateP as AssociateP,
-#endif
-
-#ifndef IEEE154_DISASSOCIATION_DISABLED
- DisassociateP,
-#else
- NoDisassociateP as DisassociateP,
-#endif
-
-#ifndef IEEE154_BEACON_SYNC_DISABLED
- BeaconSynchronizeP,
- new FrameDispatchQueueP() as DeviceCapQueue,
- new FrameDispatchP(INCOMING_SUPERFRAME) as DeviceCap,
-#else
- NoBeaconSynchronizeP as BeaconSynchronizeP,
- new NoFrameDispatchQueueP() as DeviceCapQueue,
- new NoFrameDispatchP(INCOMING_SUPERFRAME) as DeviceCap,
-#endif
- NoDeviceCfpP as DeviceCfp,
-
-#ifndef IEEE154_BEACON_TX_DISABLED
- BeaconTransmitP,
- new FrameDispatchQueueP() as CoordCapQueue,
- new FrameDispatchP(OUTGOING_SUPERFRAME) as CoordCap,
-#else
- NoBeaconTransmitP as BeaconTransmitP,
- new NoFrameDispatchQueueP() as CoordCapQueue,
- new NoFrameDispatchP(OUTGOING_SUPERFRAME) as CoordCap,
-#endif
- NoCoordCfpP as CoordCfp,
-
-#ifndef IEEE154_RXENABLE_DISABLED
- RxEnableP,
-#else
- NoRxEnableP as RxEnableP,
-#endif
-
-
-#ifndef IEEE154_PROMISCUOUS_MODE_DISABLED
- PromiscuousModeP,
-#else
- NoPromiscuousModeP as PromiscuousModeP,
-#endif
-
-#ifndef IEEE154_COORD_REALIGNMENT_DISABLED
- CoordRealignmentP,
-#else
- NoCoordRealignmentP as CoordRealignmentP,
-#endif
-
-#ifndef IEEE154_COORD_BROADCAST_DISABLED
- CoordBroadcastP,
-#else
- NoCoordBroadcastP as CoordBroadcastP,
-#endif
-
- new PoolC(ieee154_txframe_t, TXFRAME_POOL_SIZE) as TxFramePoolP,
- new PoolC(ieee154_txcontrol_t, TXCONTROL_POOL_SIZE) as TxControlPoolP,
- new QueueC(ieee154_txframe_t*, CAP_TX_QUEUE_SIZE) as DeviceCapQueueC,
- new QueueC(ieee154_txframe_t*, CAP_TX_QUEUE_SIZE) as CoordCapQueueC,
- new QueueC(ieee154_txframe_t*, CAP_TX_QUEUE_SIZE) as BroadcastQueueC;
-
- components MainC;
-
- // MCPS
- MCPS_DATA = DataP;
- MCPS_PURGE = DataP;
-
- //MLME
- MLME_START = BeaconTransmitP;
- MLME_ASSOCIATE = AssociateP;
- MLME_DISASSOCIATE = DisassociateP;
- MLME_BEACON_NOTIFY = BeaconSynchronizeP;
- MLME_BEACON_NOTIFY = ScanP;
- MLME_COMM_STATUS = AssociateP;
- MLME_COMM_STATUS = CoordRealignmentP;
- MLME_GET = PibP;
- MLME_ORPHAN = CoordRealignmentP;
-/* MLME_GTS = CfpTransmitP;*/
- MLME_POLL = PollP;
- MLME_RESET = PibP;
- MLME_RX_ENABLE = RxEnableP;
- MLME_SCAN = ScanP;
- MLME_SET = PibP;
- MLME_SYNC = BeaconSynchronizeP;
- MLME_SYNC_LOSS = BeaconSynchronizeP;
- IEEE154Frame = PibP;
- IEEE154BeaconFrame = PibP;
- PromiscuousMode = PromiscuousModeP;
- GetLocalExtendedAddress = PibP.GetLocalExtendedAddress;
- IEEE154TxBeaconPayload = BeaconTransmitP;
- Packet = PibP;
- TimeCalc = PibP;
- FrameUtility = PibP;
-
-/* ----------------------- Scanning (MLME-SCAN) ----------------------- */
-
- components new RadioClientC() as ScanRadioClient;
- PibP.MacReset -> ScanP;
- ScanP.MLME_GET -> PibP;
- ScanP.MLME_SET -> PibP.MLME_SET;
- ScanP.EnergyDetection = EnergyDetection;
- ScanP.RadioRx -> ScanRadioClient;
- ScanP.RadioTx -> ScanRadioClient;
- ScanP.Frame -> PibP;
- ScanP.BeaconFrame -> PibP;
- ScanP.RadioOff -> ScanRadioClient;
- ScanP.ScanTimer = Timer1;
- ScanP.TxFramePool -> TxFramePoolP;
- ScanP.TxControlPool -> TxControlPoolP;
- ScanP.Token -> ScanRadioClient;
- ScanP.FrameUtility -> PibP;
- ScanP.Leds = Leds;
-
-/* ----------------- Beacon Transmission (MLME-START) ----------------- */
-
- components new RadioClientC() as BeaconTxRadioClient;
- PibP.MacReset -> BeaconTransmitP;
- BeaconTransmitP.PIBUpdate[IEEE154_macAssociationPermit] -> PibP.PIBUpdate[IEEE154_macAssociationPermit];
- BeaconTransmitP.PIBUpdate[IEEE154_macGTSPermit] -> PibP.PIBUpdate[IEEE154_macGTSPermit];
- BeaconTransmitP.BeaconTxAlarm = Alarm1;
- BeaconTransmitP.BeaconPayloadUpdateTimer = Timer2;
- BeaconTransmitP.RadioOff -> BeaconTxRadioClient;
- BeaconTransmitP.IsBeaconEnabledPAN -> PibP.IsBeaconEnabledPAN;
- BeaconTransmitP.BeaconTx -> BeaconTxRadioClient;
- BeaconTransmitP.MLME_SET -> PibP.MLME_SET;
- BeaconTransmitP.MLME_GET -> PibP;
- BeaconTransmitP.SetMacSuperframeOrder -> PibP.SetMacSuperframeOrder;
- BeaconTransmitP.SetMacBeaconTxTime -> PibP.SetMacBeaconTxTime;
- BeaconTransmitP.SetMacPanCoordinator -> PibP.SetMacPanCoordinator;
- BeaconTransmitP.Token -> BeaconTxRadioClient;
- BeaconTransmitP.IsTokenRequested -> BeaconTxRadioClient;
- BeaconTransmitP.TokenTransferred -> BeaconTxRadioClient;
- BeaconTransmitP.TokenToBroadcast -> BeaconTxRadioClient;
- BeaconTransmitP.RealignmentBeaconEnabledTx -> CoordBroadcastP.RealignmentTx;
- BeaconTransmitP.RealignmentNonBeaconEnabledTx -> CoordCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
- BeaconTransmitP.BeaconRequestRx -> CoordCap.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_BEACON_REQUEST];
- BeaconTransmitP.GtsInfoWrite -> CoordCfp.GtsInfoWrite;
- BeaconTransmitP.PendingAddrSpecUpdated -> IndirectTxP.PendingAddrSpecUpdated;
- BeaconTransmitP.PendingAddrWrite -> IndirectTxP.PendingAddrWrite;
- BeaconTransmitP.FrameUtility -> PibP.FrameUtility;
- BeaconTransmitP.IsTrackingBeacons -> BeaconSynchronizeP.IsTrackingBeacons;
- BeaconTransmitP.LastBeaconRxRefTime -> BeaconSynchronizeP.CapStartRefTime;
- BeaconTransmitP.LastBeaconRxTime -> BeaconSynchronizeP.CapStart;
- BeaconTransmitP.GetSetRealignmentFrame -> CoordRealignmentP;
- BeaconTransmitP.IsBroadcastReady -> CoordBroadcastP.IsBroadcastReady;
- BeaconTransmitP.TimeCalc -> PibP;
- BeaconTransmitP.Leds = Leds;
- BeaconTransmitP.Debug = Ieee802154Debug[DEBUG_BEACON_TRANSMIT_ID];
- BeaconTxRadioClient.TransferTo -> CoordBroadcastRadioClient.TransferFrom;
-
-/* ------------------ Beacon Tracking (MLME-SYNC) ------------------ */
-
- components new RadioClientC() as SyncRadioClient;
- PibP.MacReset -> BeaconSynchronizeP;
- BeaconSynchronizeP.MLME_SET -> PibP.MLME_SET;
- BeaconSynchronizeP.MLME_GET -> PibP;
- BeaconSynchronizeP.TrackAlarm = Alarm2;
- BeaconSynchronizeP.FrameUtility -> PibP;
- BeaconSynchronizeP.FindBeacon -> DeviceCap.FindBeacon;
- BeaconSynchronizeP.FindBeacon -> CoordCap.FindBeacon;
- BeaconSynchronizeP.Frame -> PibP;
- BeaconSynchronizeP.BeaconFrame -> PibP;
- BeaconSynchronizeP.BeaconRx -> SyncRadioClient;
- BeaconSynchronizeP.RadioOff -> SyncRadioClient;
- BeaconSynchronizeP.IsBeaconEnabledPAN -> PibP.IsBeaconEnabledPAN;
- BeaconSynchronizeP.DataRequest -> PollP.DataRequest[SYNC_POLL_CLIENT];
- BeaconSynchronizeP.Token -> SyncRadioClient;
- BeaconSynchronizeP.IsTokenRequested -> SyncRadioClient;
- BeaconSynchronizeP.TokenTransferred -> SyncRadioClient;
- BeaconSynchronizeP.TokenToCap -> SyncRadioClient;
- BeaconSynchronizeP.TimeCalc -> PibP;
- BeaconSynchronizeP.CoordRealignmentRx -> DeviceCap.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_COORDINATOR_REALIGNMENT];
- BeaconSynchronizeP.Leds = Leds;
- BeaconSynchronizeP.Debug = Ieee802154Debug[DEBUG_BEACON_SYNCHRONIZE_ID];
- SyncRadioClient.TransferTo -> DeviceCapRadioClient.TransferFrom;
-
-/* -------------------- Association (MLME-ASSOCIATE) -------------------- */
-
- PibP.MacReset -> AssociateP;
- AssociateP.AssociationRequestRx -> CoordCap.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_ASSOCIATION_REQUEST];
- AssociateP.AssociationRequestTx -> DeviceCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
- AssociateP.AssociationResponseExtracted -> DeviceCap.FrameExtracted[FC1_FRAMETYPE_CMD + CMD_FRAME_ASSOCIATION_RESPONSE];
- AssociateP.AssociationResponseTx -> IndirectTxP.FrameTx[unique(INDIRECT_TX_CLIENT)];
- AssociateP.DataRequest -> PollP.DataRequest[ASSOCIATE_POLL_CLIENT];
- AssociateP.ResponseTimeout = Timer3;
- AssociateP.TxFramePool -> TxFramePoolP;
- AssociateP.TxControlPool -> TxControlPoolP;
- AssociateP.MLME_GET -> PibP;
- AssociateP.MLME_SET -> PibP.MLME_SET;
- AssociateP.FrameUtility -> PibP;
- AssociateP.Frame -> PibP;
- AssociateP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress;
- AssociateP.Debug = Ieee802154Debug[DEBUG_ASSOCIATE_ID];
-
-/* --------------- Disassociation (MLME-DISASSOCIATE) --------------- */
-
- PibP.MacReset -> DisassociateP;
- DisassociateP.DisassociationIndirectTx -> IndirectTxP.FrameTx[unique(INDIRECT_TX_CLIENT)];
- DisassociateP.DisassociationDirectTx -> CoordCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
- DisassociateP.DisassociationToCoord -> DeviceCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
- DisassociateP.DisassociationDirectRxFromCoord ->
- DeviceCap.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_DISASSOCIATION_NOTIFICATION];
- DisassociateP.DisassociationExtractedFromCoord ->
- DeviceCap.FrameExtracted[FC1_FRAMETYPE_CMD + CMD_FRAME_DISASSOCIATION_NOTIFICATION];
- DisassociateP.DisassociationRxFromDevice ->
- CoordCap.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_DISASSOCIATION_NOTIFICATION];
- DisassociateP.TxFramePool -> TxFramePoolP;
- DisassociateP.TxControlPool -> TxControlPoolP;
- DisassociateP.MLME_GET -> PibP;
- DisassociateP.FrameUtility -> PibP;
- DisassociateP.Frame -> PibP;
- DisassociateP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress;
- DisassociateP.Debug = Ieee802154Debug[DEBUG_DISASSOCIATE_ID];
-
-/* ------------------ Data Transmission (MCPS-DATA) ------------------- */
-
- PibP.MacReset -> DataP;
- DataP.IsSendingBeacons -> BeaconTransmitP.IsSendingBeacons;
- DataP.CoordCapRx -> CoordCap.FrameRx[FC1_FRAMETYPE_DATA];
- DataP.DeviceCapTx -> DeviceCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
- DataP.CoordCapTx -> CoordCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
- DataP.DeviceCapRx -> PollP.DataRx; // indirect
- DataP.DeviceCapRx -> PromiscuousModeP.FrameRx; // promiscuous
- DataP.DeviceCapRx -> DeviceCap.FrameRx[FC1_FRAMETYPE_DATA]; // broadcast
- DataP.TxFramePool -> TxFramePoolP;
- DataP.BroadcastTx -> CoordBroadcastP.BroadcastDataFrame;
- DataP.DeviceCfpTx -> DeviceCfp.CfpTx;
- DataP.IndirectTx -> IndirectTxP.FrameTx[unique(INDIRECT_TX_CLIENT)];
- DataP.FrameUtility -> PibP;
- DataP.Frame -> PibP;
- DataP.PurgeDirect -> DeviceCapQueue;
- DataP.PurgeIndirect -> IndirectTxP;
- DataP.PurgeGtsDevice -> DeviceCfp;
- DataP.PurgeGtsCoord -> CoordCfp;
- DataP.MLME_GET -> PibP;
- DataP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress;
- DataP.Packet -> PibP;
- DataP.Leds = Leds;
-
-/* ------------------------ Polling (MLME-POLL) ----------------------- */
-
- PibP.MacReset -> PollP;
- PollP.PollTx -> DeviceCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
- PollP.DataExtracted -> DeviceCap.FrameExtracted[FC1_FRAMETYPE_DATA];
- PollP.FrameUtility -> PibP;
- PollP.TxFramePool -> TxFramePoolP;
- PollP.TxControlPool -> TxControlPoolP;
- PollP.Debug = Ieee802154Debug[DEBUG_POLL_ID];
- PollP.MLME_GET -> PibP;
- PollP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress;
-
-/* ---------------------- Indirect transmission ----------------------- */
-
- PibP.MacReset -> IndirectTxP;
- IndirectTxP.CoordCapTx -> CoordCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
- IndirectTxP.DataRequestRx -> CoordCap.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_DATA_REQUEST];
- IndirectTxP.MLME_GET -> PibP;
- IndirectTxP.FrameUtility -> PibP;
- IndirectTxP.IndirectTxTimeout = Timer4;
- IndirectTxP.TimeCalc -> PibP;
- IndirectTxP.Leds = Leds;
- IndirectTxP.Debug = Ieee802154Debug[DEBUG_INDIRECTTX_ID];
-
-/* ---------------------------- Realignment --------------------------- */
-
- PibP.MacReset -> CoordRealignmentP;
- CoordRealignmentP.CoordRealignmentTx -> CoordCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
- CoordRealignmentP.OrphanNotificationRx -> CoordCap.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_ORPHAN_NOTIFICATION];
- CoordRealignmentP.FrameUtility -> PibP;
- CoordRealignmentP.Frame -> PibP;
- CoordRealignmentP.TxFramePool -> TxFramePoolP;
- CoordRealignmentP.TxControlPool -> TxControlPoolP;
- CoordRealignmentP.MLME_GET -> PibP;
- CoordRealignmentP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress;
-
-/* ---------------------------- Broadcasts ---------------------------- */
-
- components new RadioClientC() as CoordBroadcastRadioClient;
- PibP.MacReset -> CoordBroadcastP;
- CoordBroadcastP.TokenTransferred -> CoordBroadcastRadioClient;
- CoordBroadcastP.TokenToCap -> CoordBroadcastRadioClient;
- CoordBroadcastRadioClient.TransferTo -> CoordCapRadioClient.TransferFrom;
- CoordBroadcastP.BeaconFramePendingBit -> BeaconTransmitP.BeaconFramePendingBit;
- CoordBroadcastP.CapTransmitNow -> CoordCap.BroadcastTx;
- CoordBroadcastP.Queue -> BroadcastQueueC;
- CoordBroadcastP.Leds = Leds;
-
-/* --------------------- CAP (incoming superframe) -------------------- */
-
- PibP.CapQueueReset -> DeviceCapQueue;
- DeviceCapQueue.Queue -> DeviceCapQueueC;
- DeviceCapQueue.FrameTxCsma -> DeviceCap;
-
- PibP.CapQueueReset -> CoordCapQueue;
- CoordCapQueue.Queue -> CoordCapQueueC;
- CoordCapQueue.FrameTxCsma -> CoordCap;
-
- components new RadioClientC() as DeviceCapRadioClient;
- PibP.CapReset -> DeviceCap;
- DeviceCap.CapEndAlarm = Alarm3;
- DeviceCap.BLEAlarm = Alarm4;
- DeviceCap.IndirectTxWaitAlarm = Alarm5;
- DeviceCap.BroadcastAlarm = Alarm6;
- DeviceCap.Token -> DeviceCapRadioClient;
- DeviceCap.IsTokenRequested -> DeviceCapRadioClient;
- DeviceCap.TokenToCfp -> DeviceCapRadioClient;
- DeviceCap.TokenTransferred -> DeviceCapRadioClient;
- DeviceCap.CapStart -> BeaconSynchronizeP.CapStart;
- DeviceCap.CapStartRefTime -> BeaconSynchronizeP.CapStartRefTime;
- DeviceCap.CapLen -> BeaconSynchronizeP.CapLen;
- DeviceCap.IsBLEActive -> BeaconSynchronizeP.IsBLEActive;
- DeviceCap.BLELen -> BeaconSynchronizeP.BLELen;
- DeviceCap.IsRxBroadcastPending -> BeaconSynchronizeP.IsRxBroadcastPending;
- DeviceCap.IsRxEnableActive -> RxEnableP.IsRxEnableActive;
- DeviceCap.GetIndirectTxFrame -> IndirectTxP;
- DeviceCap.RxEnableStateChange -> RxEnableP.RxEnableStateChange;
- DeviceCap.IsTrackingBeacons -> BeaconSynchronizeP.IsTrackingBeacons;
- DeviceCap.FrameUtility -> PibP;
- DeviceCap.RadioTx -> DeviceCapRadioClient;
- DeviceCap.RadioRx -> DeviceCapRadioClient;
- DeviceCap.RadioOff -> DeviceCapRadioClient;
- DeviceCap.IsBeaconEnabledPAN -> PibP.IsBeaconEnabledPAN;
- DeviceCap.MLME_GET -> PibP;
- DeviceCap.MLME_SET -> PibP.MLME_SET;
- DeviceCap.Debug = Ieee802154Debug[DEBUG_FRAME_DISPATCH_DEVICE_ID];
- DeviceCap.TimeCalc -> PibP;
- DeviceCap.Leds = Leds;
- DeviceCapRadioClient.TransferTo -> DeviceCfpRadioClient.TransferFrom;
-
-/* ---------------------- CAP (outgoing superframe) ------------------- */
-
- components new RadioClientC() as CoordCapRadioClient,
- new BackupP(ieee154_cap_frame_backup_t);
- PibP.CapReset -> CoordCap;
- CoordCap.CapEndAlarm = Alarm7;
- CoordCap.BLEAlarm = Alarm8;
- CoordCap.Token -> CoordCapRadioClient;
- CoordCap.TokenToCfp -> CoordCapRadioClient;
- CoordCap.TokenTransferred -> CoordCapRadioClient;
- CoordCap.IsTokenRequested -> CoordCapRadioClient;
- CoordCap.CapStart -> BeaconTransmitP.CapStart;
- CoordCap.CapStartRefTime -> BeaconTransmitP.CapStartRefTime;
- CoordCap.CapLen -> BeaconTransmitP.CapLen;
- CoordCap.IsBLEActive -> BeaconTransmitP.IsBLEActive;
- CoordCap.BLELen -> BeaconTransmitP.BLELen;
- CoordCap.IsRxEnableActive -> RxEnableP.IsRxEnableActive;
- CoordCap.GetIndirectTxFrame -> IndirectTxP;
- CoordCap.RxEnableStateChange -> RxEnableP.RxEnableStateChange;
- CoordCap.IsTrackingBeacons -> BeaconSynchronizeP.IsTrackingBeacons;
- CoordCap.FrameUtility -> PibP;
- CoordCap.RadioTx -> CoordCapRadioClient;
- CoordCap.RadioRx -> CoordCapRadioClient;
- CoordCap.RadioOff -> CoordCapRadioClient;
- CoordCap.IsBeaconEnabledPAN -> PibP.IsBeaconEnabledPAN;
- CoordCap.MLME_GET -> PibP;
- CoordCap.MLME_SET -> PibP.MLME_SET;
- CoordCap.Debug = Ieee802154Debug[DEBUG_FRAME_DISPATCH_COORD_ID];
- CoordCap.TimeCalc -> PibP;
- CoordCap.Leds = Leds;
- CoordCapRadioClient.TransferTo -> CoordCfpRadioClient.TransferFrom;
- CoordCap.FrameBackup -> BackupP;
- CoordCap.FrameRestore -> BackupP;
-
-/* -------------------- GTS (incoming superframe) --------------------- */
-
- components new RadioClientC() as DeviceCfpRadioClient;
- PibP.MacReset -> DeviceCfp;
- DeviceCfp.TokenTransferred -> DeviceCfpRadioClient;
- DeviceCfp.TokenRequested -> DeviceCfpRadioClient;
- DeviceCfp.TokenToBeaconSync -> DeviceCfpRadioClient;
- DeviceCfp.CapStartRefTime -> BeaconSynchronizeP.CapStartRefTime;
- DeviceCfp.IsSendingBeacons -> BeaconTransmitP.IsSendingBeacons;
- DeviceCfp.CfpEnd -> BeaconSynchronizeP.CfpEnd;
- DeviceCfp.GtsField -> BeaconSynchronizeP.GtsField;
- DeviceCfp.SfSlotDuration -> BeaconSynchronizeP.SfSlotDuration;
- DeviceCfp.FinalCapSlot -> BeaconSynchronizeP.FinalCapSlot;
- DeviceCfp.CfpSlotAlarm = Alarm9;
- DeviceCfp.CfpEndAlarm = Alarm10;
- DeviceCfp.RadioTx -> DeviceCfpRadioClient;
- DeviceCfp.RadioRx -> DeviceCfpRadioClient;
- DeviceCfp.RadioOff -> DeviceCfpRadioClient;
- DeviceCfp.MLME_GET -> PibP;
- DeviceCfp.MLME_SET -> PibP.MLME_SET;
- DeviceCfpRadioClient.TransferTo -> SyncRadioClient.TransferFrom;
-
-/* -------------------- GTS (outgoing superframe) --------------------- */
-
- components new RadioClientC() as CoordCfpRadioClient;
- PibP.MacReset -> CoordCfp;
- CoordCfp.TokenTransferred -> CoordCfpRadioClient;
- CoordCfp.TokenRequested -> CoordCfpRadioClient;
- CoordCfp.IsTokenRequested -> CoordCfpRadioClient;
- CoordCfp.TokenToBeaconTransmit -> CoordCfpRadioClient;
- CoordCfp.IsTrackingBeacons -> BeaconSynchronizeP.IsTrackingBeacons;
- CoordCfp.CfpEnd -> BeaconTransmitP.CfpEnd;
- CoordCfp.GtsField -> BeaconTransmitP.GtsField;
- CoordCfp.SfSlotDuration -> BeaconTransmitP.SfSlotDuration;
- CoordCfp.FinalCapSlot -> BeaconTransmitP.FinalCapSlot;
- CoordCfp.CfpSlotAlarm = Alarm11;
- CoordCfp.CfpEndAlarm = Alarm12;
- CoordCfp.RadioTx -> CoordCfpRadioClient;
- CoordCfp.RadioRx -> CoordCfpRadioClient;
- CoordCfp.RadioOff -> CoordCfpRadioClient;
- CoordCfp.MLME_GET -> PibP;
- CoordCfp.MLME_SET -> PibP.MLME_SET;
- CoordCfpRadioClient.TransferTo -> BeaconTxRadioClient.TransferFrom;
-
-/* -------------------------- promiscuous mode ------------------------ */
-
- components new RadioClientC() as PromiscuousModeRadioClient;
- PibP.MacReset -> PromiscuousModeP;
- PromiscuousModeP.Token -> PromiscuousModeRadioClient;
- PromiscuousModeP.PromiscuousRx -> PromiscuousModeRadioClient;
- PromiscuousModeP.RadioOff -> PromiscuousModeRadioClient;
- PromiscuousModeP.RadioPromiscuousMode = RadioPromiscuousMode;
- PromiscuousModeP.Debug = Ieee802154Debug[DEBUG_PROMISCUOUSMODE_ID];
-
-/* --------------------------- MLME-RX-ENABLE ------------------------ */
-
- PibP.MacReset -> RxEnableP;
- RxEnableP.IncomingSfStart -> BeaconSynchronizeP.CapStart;
- RxEnableP.OutgoingSfStart -> BeaconTransmitP.CapStart;
- RxEnableP.IncomingBeaconInterval -> BeaconSynchronizeP.BeaconInterval;
- RxEnableP.OutgoingBeaconInterval -> BeaconTransmitP.BeaconInterval;
- RxEnableP.IsTrackingBeacons -> BeaconSynchronizeP.IsTrackingBeacons;
- RxEnableP.IsSendingBeacons-> BeaconTransmitP.IsSendingBeacons;
- RxEnableP.IsMacPanCoordinator -> PibP.IsMacPanCoordinator;
- RxEnableP.IsBeaconEnabledPAN -> PibP.IsBeaconEnabledPAN;
- RxEnableP.TimeCalc -> PibP.TimeCalc;
- RxEnableP.WasRxEnabled -> DeviceCap.WasRxEnabled;
- RxEnableP.WasRxEnabled -> CoordCap.WasRxEnabled;
- RxEnableP.RxEnableTimer = Timer5;
- RxEnableP.Debug = Ieee802154Debug[DEBUG_RXENABLE_ID];
-
-/* ------------------------------- PIB -------------------------------- */
-
- components new RadioClientC() as PibRadioClient;
- PIBUpdate = PibP;
- MainC.SoftwareInit -> PibP.LocalInit;
- PibP.RadioControl = PhySplitControl;
- PibP.Random = Random;
- PibP.PromiscuousModeGet -> PromiscuousModeP;
- PibP.LocalTime = LocalTime;
- PibP.Token -> PibRadioClient;
- PibP.RadioOff -> PibRadioClient;
-
-/* ------------------------- Radio Control ---------------------------- */
-
- RadioControlP.PhyTx = RadioTx;
- RadioControlP.PhyRx = RadioRx;
- RadioControlP.PhyRadioOff = RadioOff;
- RadioControlP.RadioPromiscuousMode -> PromiscuousModeP;
- RadioControlP.Leds = Leds;
- RadioControlP.Debug = Ieee802154Debug[DEBUG_RADIOCONTROL_ID];
-}
+++ /dev/null
-/*
- * Copyright (c) 2008, Technische Universitaet Berlin
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * - Neither the name of the Technische Universitaet Berlin nor the names
- * of its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * - Revision -------------------------------------------------------------
- * $Revision$
- * $Date$
- * @author Jan Hauer <hauer@tkn.tu-berlin.de>
- * ========================================================================
- */
-
-#ifndef __TKN154_DEBUG_H
-#define __TKN154_DEBUG_H
-
-#define PollP_ALLOC_FAIL1 0
-#define PollP_ALLOC_FAIL2 1
-#define PollP_INTERNAL_POLL 2
-#define PollP_SUCCESS 3
-#define PollP_TXDONE 4
-#define PollP_WRONG_FORMAT 5
-#define PollP_INTERNAL_ERROR 6
-#define PollP_RX 7
-
-#define IndirectTxP_OVERFLOW 0
-#define IndirectTxP_NOTIFIED 1
-#define IndirectTxP_REQUESTED 2
-#define IndirectTxP_BUSY 3
-#define IndirectTxP_DATA_REQUEST 4
-#define IndirectTxP_SEND_NOW 5
-#define IndirectTxP_SEND_NOW_FAIL 6
-#define IndirectTxP_SEND_DONE 7
-#define IndirectTxP_BEACON_ASSEMBLY 8
-
-#define EnableRxP_RADIORX_ERROR 0
-#define EnableRxP_PROMISCUOUS_REQUEST 1
-#define EnableRxP_PROMISCUOUS_ON 2
-#define EnableRxP_PROMISCUOUS_OFF 3
-
-#define AssociateP_REQUEST 0
-#define AssociateP_TXDONE 1
-#define AssociateP_TIMEOUT 2
-#define AssociateP_RX 3
-#define AssociateP_SETTIMER 4
-#define AssociateP_POLL_DONE 5
-
-#define DISSASSOCIATE_REQUEST 50
-#define DISSASSOCIATE_TXDONE 51
-#define DISSASSOCIATE_RX 52
-
-#define CapP_TOO_SHORT 0
-#define CapP_SET_CAP_END 1
-#define CapP_CAP_END_FIRED 2
-#define CapP_INTERNAL_ERROR 3
-
-#define DeviceCapTransmitP_CONTINUE 0
-#define DeviceCapTransmitP_TOVERFLOW 1
-#define DeviceCapTransmitP_RADIO_RESERVE 2
-#define DeviceCapTransmitP_CCA_FAIL 3
-#define DeviceCapTransmitP_NO_ACK 4
-#define DeviceCapTransmitP_TX_DONE 5
-#define DeviceCapTransmitP_TX_PREPARE 6
-#define DeviceCapTransmitP_TX_NOW 7
-#define DeviceCapTransmitP_TX_CANCEL 8
-#define DeviceCapTransmitP_TX_PREPARE_DONE 9
-#define DeviceCapTransmitP_CAP_END_ALARM 10
-#define DeviceCapTransmitP_RADIO_OFF 11
-#define DeviceCapTransmitP_RADIO_RX 12
-#define DeviceCapTransmitP_TX_CANCEL_DONE 13
-#define DeviceCapTransmitP_TX_DONE_UNKNOWN 14
-#define DeviceCapTransmitP_RESOURCE_REQ 15
-#define DeviceCapTransmitP_GOT_RESOURCE 16
-
-#define CoordCapTransmitP_RADIO_RESERVE 0
-#define CoordCapTransmitP_TX_CANCEL 1
-#define CoordCapTransmitP_CCA_FAIL 2
-#define CoordCapTransmitP_CAP_END_ALARM 3
-#define CoordCapTransmitP_OFF_DONE 4
-#define CoordCapTransmitP_FINISH_TX 5
-#define CoordCapTransmitP_RADIO_RX 6
-
-
-#define PhyRx_START 0
-#define PhyRx_STOP 1
-#define PhyRx_FIFOP 2
-#define PhyRx_RXON 3
-
-
-enum {
- DEBUG_LEVEL_INFO = 0,
- DEBUG_LEVEL_IMPORTANT = 1,
- DEBUG_LEVEL_CRITICAL = 2,
-
- // IDs assigned for debugging
- DEBUG_BEACON_TRANSMIT_ID = 0,
- DEBUG_FRAME_DISPATCH_COORD_ID = 1,
- DEBUG_COORD_CFP_ID = 2,
-
- DEBUG_BEACON_SYNCHRONIZE_ID = 3,
- DEBUG_FRAME_DISPATCH_DEVICE_ID = 4,
- DEBUG_DEVICE_CFP_ID = 5,
-
- DEBUG_SCAN_ID = 6,
-
- DEBUG_RADIOCONTROL_ID = 7,
- DEBUG_PIB_ID = 8,
- DEBUG_ASSOCIATE_ID = 9,
- DEBUG_DISASSOCIATE_ID = 10,
- DEBUG_FRAMEDISPATCHQUEUE_ID = 11,
- DEBUG_INDIRECTTX_ID = 12,
- DEBUG_DATA_ID = 13,
- DEBUG_POLL_ID = 14,
- DEBUG_RXENABLE_ID = 15,
- DEBUG_PROMISCUOUSMODE_ID = 16,
- DEBUG_RADIO_DRIVER_ID = 17,
-
-};
-
-typedef nx_struct serial_debug_msg {
- nx_uint8_t client;
- nx_uint8_t eventID;
- nx_uint8_t seqno;
- nx_uint8_t priority;
- nx_uint32_t timestamp;
- nx_uint32_t param1;
- nx_uint32_t param2;
- nx_uint32_t param3;
-} serial_debug_msg_t;
-
-#ifndef SERIAL_DBG_MSGBUF_SIZE
-#define SERIAL_DBG_MSGBUF_SIZE 150
-#endif
-
-enum {
- AM_SERIAL_DEBUG_MSG = 222,
-};
-
-#endif // __TKN154_DEBUG_H
#include "TKN154.h"
#include "TKN154_PHY.h"
+#include "TKN154_platform.h"
/****************************************************
* IEEE 802.15.4 PAN information base identifiers
IEEE154_macMaxFrameTotalWaitTime = 0x58,
IEEE154_macMaxFrameRetries = 0x59,
IEEE154_macMinBE = 0x4F,
-// no identifier defined in standard
IEEE154_macMinLIFSPeriod = 0xA0,
-// no identifier defined in standard
IEEE154_macMinSIFSPeriod = 0xA1,
IEEE154_macPANId = 0x50,
IEEE154_macPromiscuousMode = 0x51,
IEEE154_macTimestampSupported = 0x5C,
IEEE154_macTransactionPersistenceTime = 0x55,
-// attributes not present in the standard PIB:
+ // custom attributes (not present in the standard PIB)
IEEE154_macPanCoordinator = 0xF0,
};
FC2_FRAME_VERSION_MASK = 0x30,
};
+/** some unique strings */
#define SYNC_POLL_CLIENT unique("PollP.client")
#define ASSOCIATE_POLL_CLIENT unique("PollP.client")
#define CAP_TX_CLIENT "CapQueueP.FrameTx.client"
INCOMING_SUPERFRAME,
};
+/****************************************************
+ * Default time-related constants for beacon-enabled PANs,
+ * these may be overridden by platform-specific constants.
+ * */
+
+#ifndef IEEE154_MAX_BEACON_JITTER
+ // will start to listen for a beacon MAX_BEACON_JITTER_TIME(BO) symbols
+ // before its expected arrival, where BO is the current beacon order
+ // (here --by default-- BO is ignored)
+ #define IEEE154_MAX_BEACON_JITTER(BO) 20
+#endif
+
+#ifndef IEEE154_MAX_BEACON_LISTEN_TIME
+ // maximum time to listen for a beacon after its expected arrival,
+ // before it is declared as missed
+ #define IEEE154_MAX_BEACON_LISTEN_TIME(BO) (128 * IEEE154_SYMBOLS_PER_OCTET + IEEE154_MAX_BEACON_JITTER(BO))
+#endif
+
typedef struct {
uint8_t length; // top bit denotes -> promiscuous mode
uint8_t mhr[MHR_MAX_LEN];
ieee154_header_t header;
ieee154_metadata_t metadata;
} ieee154_txcontrol_t;
-
+
typedef struct ieee154_csma {
uint8_t BE; // initial backoff exponent
uint8_t macMaxBE; // maximum backoff exponent
typedef struct {
ieee154_txframe_t *frame;
- ieee154_csma_t csmaParams;
+ ieee154_csma_t csma;
uint32_t transactionTime;
} ieee154_cap_frame_backup_t;
// PHY sublayer constants
IEEE154_aTurnaroundTime = 12,
- FRAMECTL_LENGTH_MASK = 0x7F, // "length" member in ieee154_frame_t
- FRAMECTL_PROMISCUOUS = 0x80, // "length" member in ieee154_frame_t
+ FRAMECTL_LENGTH_MASK = 0x7F, // "length" member in ieee154_header_t
+ FRAMECTL_PROMISCUOUS = 0x80, // "length" member in ieee154_header_t
};
#define IEEE154_SUPPORTED_CHANNELPAGE (IEEE154_SUPPORTED_CHANNELS >> 27)
IEEE154_aUnitBackoffPeriod = 20,
};
+#ifdef TKN154_DEBUG
+
+ /******************************************************************
+ * ATTENTION! Debugging over serial is a lot of overhead. To
+ * keep it simple, here are the rules you have to follow when
+ * using the dbg_serial() command:
+ *
+ * - dbg_serial() is used like dbg(), i.e. you pass it at least
+ * two strings, the first one describing the component/file,
+ * the second is a format string (like in printf())
+ * - following the second string, there may be zero up to
+ * two parameters -- these must be (cast to) uint32_t!
+ * - both strings must be constants (pointers always valid)
+ * - no data is sent over serial, unless dbg_serial_flush() is
+ * called; try to call it when the system is idle or at least
+ * when no time-critical operations are pending
+ * - on the PC use the printf java client to display the text
+ * (see tinyos-2.x/apps/tests/TestPrintf/README.txt)
+ *
+ * The ASSERT(X) macro is used to test for errors. If X evaluates
+ * to zero, then 3 leds start blinking simulataneously (about 2Hz)
+ * and the node *continuously* outputs over serial the filename+line
+ * where the (first) ASSERT has failed. This means, even if your
+ * TelosB was not attached to your PC while the ASSERT failed you
+ * can still pull the information out later.
+ *
+ * All dbg_serial() and ASSERT() statements are removed, if
+ * TKN154_DEBUG is not defined (which is the default).
+ **/
+
+ /* -> functions are defined in DebugP.nc */
+ void tkn154_assert(bool val, const char *filename, uint16_t line, const char *func);
+ void tkn154_dbg_serial(const char *filename, uint16_t line, ...);
+ void tkn154_dbg_serial_flush();
+ #define ASSERT(X) tkn154_assert(X, __FILE__,__LINE__,__FUNCTION__)
+ #define dbg_serial(m, ...) tkn154_dbg_serial(m, __LINE__,__VA_ARGS__)
+ #define dbg_serial_flush() tkn154_dbg_serial_flush()
+#else
+ #define ASSERT(X) if ((X)==0){}
+ #define dbg_serial(m, ...) dbg(m, __VA_ARGS__)
+ #define dbg_serial_flush()
+#endif
#endif // __TKN154_MAC_H
*/
-typedef struct ieee154_PIB_t {
+typedef struct ieee154_PIB {
- /**************/
- /* bool types */
- /**************/
+ /** bool types */
// 0x41
ieee154_macAssociationPermit_t macAssociationPermit;
ieee154_macAssociatedPANCoord_t macAssociatedPANCoord;
// 0x5D
ieee154_macSecurityEnabled_t macSecurityEnabled;
- // no standard attribute
+ // custom attribute
ieee154_macPanCoordinator_t macPanCoordinator;
- /*****************/
- /* uint8_t types */
- /*****************/
+
+ /** uint8_t types */
// 0x00
ieee154_phyCurrentChannel_t phyCurrentChannel;
// 0x5a
ieee154_macResponseWaitTime_t macResponseWaitTime;
- /*****************************/
- /* larger than uint8_t types */
- /*****************************/
+ /** larger than uint8_t types */
// 0x4B
ieee154_macCoordShortAddress_t macCoordShortAddress;
return result;
}
- async command uint8_t TransferredFrom.getUserId(){ return myUserId;}
+ async command uint8_t TransferredFrom.getUserId() { return myUserId;}
async command void TransferredFrom.transfer()
{
signal ResourceTransferred.transferred();
}
- default async command uint8_t TransferTo.getUserId(){ call Leds.led0On(); return 0xFF;}
- default async command void TransferTo.transfer(){ call Leds.led0On(); }
- default async event void ResourceTransferred.transferred(){}
+ default async command uint8_t TransferTo.getUserId() { ASSERT(0); return 0xFF;}
+ default async command void TransferTo.transfer() { ASSERT(0); }
+ default async event void ResourceTransferred.transferred() {}
}
--- /dev/null
+/*
+ * Copyright (c) 2008, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+#include "TKN154_PHY.h"
+#include "TKN154_MAC.h"
+
+/**
+ * This module is responsible for the transmission/reception of DATA and
+ * COMMAND frames in a nonbeacon-enabled PAN. Its main tasks are initialization
+ * of the parameters of the unslotted CSMA-CA algorithm (NB, BE, etc.),
+ * initiating retransmissions and managing requests for enabling the receiver
+ * for a finite period of time. It does not implement the actual CSMA-CA
+ * algorithm, because due to its timing requirements the CSMA-CA algorithm is
+ * not part of the MAC implementation but of the chip-specific radio driver.
+ */
+
+#if IEEE154_BEACON_ENABLED_PAN
+#error "The IEEE154_BEACON_ENABLED_PAN macro MUST NOT be set when using this component!"
+#endif
+
+module UnslottedFrameDispatchP
+{
+ provides
+ {
+ interface Init as Reset;
+ interface MLME_START;
+ interface FrameTx as FrameTx;
+ interface FrameRx as FrameRx[uint8_t frameType];
+ interface FrameExtracted as FrameExtracted[uint8_t frameType];
+ interface Notify<bool> as WasRxEnabled;
+ }
+ uses
+ {
+ interface Timer<TSymbolIEEE802154> as IndirectTxWaitTimer;
+ interface Resource as Token;
+ interface GetNow<bool> as IsTokenRequested;
+ interface GetNow<bool> as IsRxEnableActive;
+ interface Set<ieee154_macSuperframeOrder_t> as SetMacSuperframeOrder;
+ interface Set<ieee154_macPanCoordinator_t> as SetMacPanCoordinator;
+ interface Get<ieee154_txframe_t*> as GetIndirectTxFrame;
+ interface Notify<bool> as RxEnableStateChange;
+ interface FrameUtility;
+ interface UnslottedCsmaCa;
+ interface RadioRx;
+ interface RadioOff;
+ interface MLME_GET;
+ interface MLME_SET;
+ interface TimeCalc;
+ interface Leds;
+ }
+}
+implementation
+{
+ typedef enum {
+ SWITCH_OFF,
+ WAIT_FOR_RXDONE,
+ WAIT_FOR_TXDONE,
+ DO_NOTHING,
+ } next_state_t;
+
+ typedef enum {
+ INDIRECT_TX_ALARM,
+ NO_ALARM,
+ } rx_alarm_t;
+
+ /* state / frame management */
+ norace bool m_lock;
+ norace bool m_resume;
+ norace ieee154_txframe_t *m_currentFrame;
+ norace ieee154_txframe_t *m_lastFrame;
+
+ /* variables for the unslotted CSMA-CA */
+ norace ieee154_csma_t m_csma;
+ norace ieee154_macMaxBE_t m_BE;
+ norace ieee154_macMaxCSMABackoffs_t m_macMaxCSMABackoffs;
+ norace ieee154_macMaxBE_t m_macMaxBE;
+ norace ieee154_macMaxFrameRetries_t m_macMaxFrameRetries;
+ norace ieee154_status_t m_txStatus;
+ norace uint32_t m_transactionTime;
+ norace bool m_indirectTxPending = FALSE;
+ norace ieee154_macMaxFrameTotalWaitTime_t m_macMaxFrameTotalWaitTime;
+
+ /* function / task prototypes */
+ next_state_t tryReceive(bool startIndirectTxTimer);
+ next_state_t tryTransmit();
+ next_state_t trySwitchOff();
+ void backupCurrentFrame();
+ void restoreFrameFromBackup();
+ void updateState();
+ void setCurrentFrame(ieee154_txframe_t *frame);
+ void signalTxBroadcastDone(ieee154_txframe_t *frame, ieee154_status_t error);
+ task void signalTxDoneTask();
+ task void wasRxEnabledTask();
+ task void startIndirectTxTimerTask();
+ task void signalStartConfirmTask();
+
+ command error_t Reset.init()
+ {
+ if (m_currentFrame)
+ signal FrameTx.transmitDone(m_currentFrame, IEEE154_TRANSACTION_OVERFLOW);
+ if (m_lastFrame)
+ signal FrameTx.transmitDone(m_lastFrame, IEEE154_TRANSACTION_OVERFLOW);
+ m_currentFrame = m_lastFrame = NULL;
+ call IndirectTxWaitTimer.stop();
+ return SUCCESS;
+ }
+
+ command ieee154_status_t MLME_START.request (
+ uint16_t panID,
+ uint8_t logicalChannel,
+ uint8_t channelPage,
+ uint32_t startTime,
+ uint8_t beaconOrder,
+ uint8_t superframeOrder,
+ bool panCoordinator,
+ bool batteryLifeExtension,
+ bool coordRealignment,
+ ieee154_security_t *coordRealignSecurity,
+ ieee154_security_t *beaconSecurity)
+ {
+ ieee154_status_t status;
+ ieee154_macShortAddress_t shortAddress = call MLME_GET.macShortAddress();
+
+ // check parameters
+ if ((coordRealignSecurity && coordRealignSecurity->SecurityLevel) ||
+ (beaconSecurity && beaconSecurity->SecurityLevel))
+ status = IEEE154_UNSUPPORTED_SECURITY;
+ else if (shortAddress == 0xFFFF)
+ status = IEEE154_NO_SHORT_ADDRESS;
+ else if (logicalChannel > 26 ||
+ (channelPage != IEEE154_SUPPORTED_CHANNELPAGE) ||
+ !(IEEE154_SUPPORTED_CHANNELS & ((uint32_t) 1 << logicalChannel)))
+ status = IEEE154_INVALID_PARAMETER;
+ else if (beaconOrder != 15)
+ status = IEEE154_INVALID_PARAMETER;
+ else {
+ call MLME_SET.macPANId(panID);
+ call MLME_SET.phyCurrentChannel(logicalChannel);
+ call MLME_SET.macBeaconOrder(beaconOrder);
+ call SetMacSuperframeOrder.set(superframeOrder);
+ call SetMacPanCoordinator.set(panCoordinator);
+ //TODO: check realignment
+ post signalStartConfirmTask();
+ status = IEEE154_SUCCESS;
+ }
+ return status;
+ }
+
+ task void signalStartConfirmTask()
+ {
+ signal MLME_START.confirm(IEEE154_SUCCESS);
+ }
+
+ command ieee154_status_t FrameTx.transmit(ieee154_txframe_t *frame)
+ {
+ if (m_currentFrame != NULL) {
+ // we've not finished transmitting the current frame yet
+ dbg_serial("UnslottedFrameDispatchP", "Overflow\n");
+ return IEEE154_TRANSACTION_OVERFLOW;
+ } else {
+ setCurrentFrame(frame);
+ call Token.request();
+ return IEEE154_SUCCESS;
+ }
+ }
+
+ event void Token.granted()
+ {
+ updateState();
+ }
+
+ void setCurrentFrame(ieee154_txframe_t *frame)
+ {
+ ieee154_macDSN_t dsn = call MLME_GET.macDSN();
+ frame->header->mhr[MHR_INDEX_SEQNO] = dsn++;
+ call MLME_SET.macDSN(dsn);
+ m_csma.NB = 0;
+ m_csma.macMaxCsmaBackoffs = m_macMaxCSMABackoffs = call MLME_GET.macMaxCSMABackoffs();
+ m_csma.macMaxBE = m_macMaxBE = call MLME_GET.macMaxBE();
+ m_csma.BE = call MLME_GET.macMinBE();
+ if (call MLME_GET.macBattLifeExt() && m_csma.BE > 2)
+ m_csma.BE = 2;
+ m_BE = m_csma.BE;
+ if (call GetIndirectTxFrame.get() == frame)
+ m_macMaxFrameRetries = 0; // this is an indirect transmissions (never retransmit)
+ else
+ m_macMaxFrameRetries = call MLME_GET.macMaxFrameRetries();
+ m_transactionTime = IEEE154_SHR_DURATION +
+ (frame->headerLen + frame->payloadLen + 2) * IEEE154_SYMBOLS_PER_OCTET; // extra 2 for CRC
+ if (frame->header->mhr[MHR_INDEX_FC1] & FC1_ACK_REQUEST)
+ m_transactionTime += (IEEE154_aTurnaroundTime + IEEE154_aUnitBackoffPeriod +
+ 11 * IEEE154_SYMBOLS_PER_OCTET); // 11 byte for the ACK PPDU
+ // if (frame->headerLen + frame->payloadLen > IEEE154_aMaxSIFSFrameSize)
+ // m_transactionTime += call MLME_GET.macMinLIFSPeriod();
+ // else
+ // m_transactionTime += call MLME_GET.macMinSIFSPeriod();
+ m_macMaxFrameTotalWaitTime = call MLME_GET.macMaxFrameTotalWaitTime();
+ m_currentFrame = frame;
+ }
+
+ /**
+ * The updateState() function is called whenever some event happened that
+ * might require a state transition; it implements a lock mechanism (m_lock)
+ * to prevent race conditions. Whenever the lock is set a "done"-event (from
+ * a RadioTx/RadioRx/RadioOff interface) is pending and will "soon" unset the
+ * lock (and then updateState() will called again). The updateState()
+ * function decides about the next state by checking a list of possible
+ * current states ordered by priority. Calling this function more than
+ * necessary can do no harm.
+ */
+
+ void updateState()
+ {
+ next_state_t next;
+ atomic {
+ // long atomics are bad... but in this block, once the
+ // current state has been determined only one branch will
+ // be taken (there are no loops)
+ if (m_lock || !call Token.isOwner())
+ return;
+ m_lock = TRUE; // lock
+
+ // Check 1: was an indirect transmission successfully started
+ // and are we now waiting for a frame from the coordinator?
+ if (m_indirectTxPending) {
+ next = tryReceive(TRUE);
+ }
+
+ // Check 2: is some other operation (like MLME-SCAN or MLME-RESET) pending?
+ else if (call IsTokenRequested.getNow()) {
+ if (call RadioOff.isOff()) {
+ // nothing more to do... just release the Token
+ m_lock = FALSE; // unlock
+ dbg_serial("UnslottedFrameDispatchP", "Token requested: releasing it.\n");
+ call Token.release();
+ return;
+ } else
+ next = SWITCH_OFF;
+ }
+
+ // Check 3: is there a frame ready to transmit?
+ else if (m_currentFrame != NULL) {
+ next = tryTransmit();
+ }
+
+ // Check 4: should we be in receive mode?
+ else if (call IsRxEnableActive.getNow()) {
+ next = tryReceive(FALSE);
+ if (next == DO_NOTHING) {
+ // this means there is an active MLME_RX_ENABLE.request
+ // and the radio was just switched to Rx mode - signal
+ // a notify event to inform the next higher layer
+ post wasRxEnabledTask();
+ }
+ }
+
+ // Check 6: just make sure the radio is switched off
+ else {
+ next = trySwitchOff();
+ if (next == DO_NOTHING) {
+ // nothing more to do... just release the Token
+ m_lock = FALSE; // unlock
+ dbg_serial("UnslottedFrameDispatchP", "Releasing token\n");
+ call Token.release();
+ return;
+ }
+ }
+
+ // if there is nothing to do, then we must clear the lock
+ if (next == DO_NOTHING)
+ m_lock = FALSE;
+ } // atomic
+
+ // put next state in operation (possibly keeping the lock)
+ switch (next)
+ {
+ case SWITCH_OFF: ASSERT(call RadioOff.off() == SUCCESS); break;
+ case WAIT_FOR_RXDONE: break;
+ case WAIT_FOR_TXDONE: break;
+ case DO_NOTHING: break;
+ }
+ }
+
+ next_state_t tryTransmit()
+ {
+ // tries to transmit m_currentFrame
+ next_state_t next;
+
+ if (!call RadioOff.isOff())
+ next = SWITCH_OFF;
+ else {
+ error_t res;
+ res = call UnslottedCsmaCa.transmit(m_currentFrame, &m_csma);
+ dbg("UnslottedFrameDispatchP", "UnslottedCsmaCa.transmit() -> %lu\n", (uint32_t) res);
+ next = WAIT_FOR_TXDONE; // this will NOT clear the lock
+ }
+ return next;
+ }
+
+ next_state_t tryReceive(bool startIndirectTxTimer)
+ {
+ next_state_t next;
+ if (call RadioRx.isReceiving())
+ next = DO_NOTHING;
+ else if (!call RadioOff.isOff())
+ next = SWITCH_OFF;
+ else {
+ call RadioRx.enableRx(0, 0);
+ if (startIndirectTxTimer)
+ post startIndirectTxTimerTask();
+ next = WAIT_FOR_RXDONE;
+ }
+ return next;
+ }
+
+ next_state_t trySwitchOff()
+ {
+ next_state_t next;
+ if (call RadioOff.isOff())
+ next = DO_NOTHING;
+ else
+ next = SWITCH_OFF;
+ return next;
+ }
+
+ async event void RadioOff.offDone() { m_lock = FALSE; updateState();}
+ async event void RadioRx.enableRxDone() { m_lock = FALSE; updateState();}
+ event void RxEnableStateChange.notify(bool whatever) { updateState();}
+
+ event void IndirectTxWaitTimer.fired()
+ {
+ atomic {
+ if (m_indirectTxPending) {
+ m_indirectTxPending = FALSE;
+ post signalTxDoneTask();
+ }
+ }
+ }
+
+ task void startIndirectTxTimerTask()
+ {
+ call IndirectTxWaitTimer.startOneShot(m_macMaxFrameTotalWaitTime);
+ }
+
+ async event void UnslottedCsmaCa.transmitDone(ieee154_txframe_t *frame,
+ ieee154_csma_t *csma, bool ackPendingFlag, error_t result)
+ {
+ bool done = TRUE;
+ dbg("UnslottedFrameDispatchP", "UnslottedCsmaCa.transmitDone() -> %lu\n", (uint32_t) result);
+ m_resume = FALSE;
+
+ switch (result)
+ {
+ case SUCCESS:
+ // frame was successfully transmitted, if ACK was requested
+ // then a matching ACK was successfully received as well
+ m_txStatus = IEEE154_SUCCESS;
+ if (frame->payload[0] == CMD_FRAME_DATA_REQUEST &&
+ ((frame->header->mhr[MHR_INDEX_FC1]) & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_CMD) {
+ // this was a data request frame
+ m_txStatus = IEEE154_NO_DATA; // pessimistic
+ if (ackPendingFlag) {
+ // the coordinator has data for us; switch to Rx
+ // to complete the indirect transmission
+ m_indirectTxPending = TRUE;
+ m_lastFrame = m_currentFrame;
+ m_currentFrame = NULL;
+ ASSERT(call RadioRx.enableRx(0, 0) == SUCCESS);
+ return;
+ }
+ }
+ break;
+ case FAIL:
+ // The CSMA-CA algorithm failed: the frame was not transmitted,
+ // because channel was never idle
+ m_txStatus = IEEE154_CHANNEL_ACCESS_FAILURE;
+ break;
+ case ENOACK:
+ // frame was transmitted, but we didn't receive an ACK (although
+ // we requested an one). note: coordinator never retransmits an
+ // indirect transmission (see above)
+ if (m_macMaxFrameRetries > 0) {
+ // retransmit: reinitialize CSMA-CA parameters
+ done = FALSE;
+ m_csma.NB = 0;
+ m_csma.macMaxCsmaBackoffs = m_macMaxCSMABackoffs;
+ m_csma.macMaxBE = m_macMaxBE;
+ m_csma.BE = m_BE;
+ m_macMaxFrameRetries -= 1;
+ } else
+ m_txStatus = IEEE154_NO_ACK;
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ if (done) {
+ m_lastFrame = m_currentFrame;
+ m_currentFrame = NULL;
+ post signalTxDoneTask();
+ }
+
+ m_lock = FALSE;
+ updateState();
+ }
+
+ task void signalTxDoneTask()
+ {
+ ieee154_txframe_t *lastFrame = m_lastFrame;
+ ieee154_status_t status = m_txStatus;
+ m_indirectTxPending = FALSE;
+ m_lastFrame = NULL; // only now the next transmission can begin
+ if (lastFrame) {
+ dbg("UnslottedFrameDispatchP", "Transmit done, DSN: %lu, result: 0x%lx\n",
+ (uint32_t) MHR(lastFrame)[MHR_INDEX_SEQNO], (uint32_t) status);
+ signal FrameTx.transmitDone(lastFrame, status);
+ }
+ updateState();
+ }
+
+ event message_t* RadioRx.received(message_t* frame, const ieee154_timestamp_t *timestamp)
+ {
+ // received a frame -> find out frame type and
+ // signal it to responsible client component
+ uint8_t *payload = (uint8_t *) frame->data;
+ uint8_t *mhr = MHR(frame);
+ uint8_t frameType = mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK;
+ if (frameType == FC1_FRAMETYPE_CMD)
+ frameType += payload[0];
+ atomic {
+ if (m_indirectTxPending) {
+ message_t* frameBuf;
+ call IndirectTxWaitTimer.stop();
+ // TODO: check!
+ //if (frame->payloadLen)
+ // is this frame from our coordinator? hmm... we cannot say
+ // with certainty, because we might only know either the
+ // coordinator extended or short address (and the frame could
+ // have been sent with the other addressing mode) ??
+ m_txStatus = IEEE154_SUCCESS;
+ frameBuf = signal FrameExtracted.received[frameType](frame, m_lastFrame);
+ signal IndirectTxWaitTimer.fired();
+ return frameBuf;
+ } else
+ return signal FrameRx.received[frameType](frame);
+ }
+ }
+
+ task void wasRxEnabledTask()
+ {
+ signal WasRxEnabled.notify(TRUE);
+ }
+
+
+ default event void FrameTx.transmitDone(ieee154_txframe_t *data, ieee154_status_t status) {}
+ default event message_t* FrameRx.received[uint8_t client](message_t* data) {return data;}
+ default async command bool IsRxEnableActive.getNow() {return FALSE;}
+
+ default event message_t* FrameExtracted.received[uint8_t client](message_t* msg, ieee154_txframe_t *txFrame) {return msg;}
+
+ command error_t WasRxEnabled.enable() {return FAIL;}
+ command error_t WasRxEnabled.disable() {return FAIL;}
+ default event void MLME_START.confirm(ieee154_status_t status) {}
+}
* ========================================================================
*/
+ /** Empty placeholder component for AssociateP. */
#include "TKN154_MAC.h"
interface FrameUtility;
interface IEEE154Frame as Frame;
interface Get<uint64_t> as LocalExtendedAddress;
- interface Ieee802154Debug as Debug;
}
}
implementation
command error_t Init.init() { return SUCCESS; }
-/* ------------------- MLME_ASSOCIATE Request ------------------- */
+ /* ------------------- MLME_ASSOCIATE Request ------------------- */
command ieee154_status_t MLME_ASSOCIATE.request (
uint8_t LogicalChannel,
event void DataRequest.pollDone() { }
-/* ------------------- MLME_ASSOCIATE Response ------------------- */
+ /* ------------------- MLME_ASSOCIATE Response ------------------- */
event message_t* AssociationRequestRx.received(message_t* frame) { return frame; }
event void AssociationResponseTx.transmitDone(ieee154_txframe_t *txFrame, ieee154_status_t status) { }
-/* ------------------- Defaults ------------------- */
+ /* ------------------- Defaults ------------------- */
default event void MLME_ASSOCIATE.indication (
uint64_t DeviceAddress,
* ========================================================================
*/
+ /** Empty placeholder component for BeaconSynchronizeP. */
#include "TKN154_MAC.h"
{
provides
{
- interface Init;
+ interface Init as Reset;
interface MLME_SYNC;
interface MLME_BEACON_NOTIFY;
interface MLME_SYNC_LOSS;
+ interface SuperframeStructure as IncomingSF;
interface GetNow<bool> as IsTrackingBeacons;
- interface Get<uint32_t> as GetLastBeaconRxTime;
- interface GetNow<uint32_t> as CapStart;
- interface GetNow<ieee154_reftime_t*> as CapStartRefTime;
- interface GetNow<uint32_t> as CapLen;
- interface GetNow<uint32_t> as CapEnd;
- interface GetNow<uint32_t> as CfpEnd;
- interface GetNow<uint32_t> as CfpLen;
- interface GetNow<uint32_t> as BeaconInterval;
- interface GetNow<bool> as IsBLEActive;
- interface GetNow<uint16_t> as BLELen;
- interface GetNow<uint8_t*> as GtsField;
- interface GetNow<uint32_t> as SfSlotDuration;
- interface GetNow<uint8_t> as FinalCapSlot;
- interface GetNow<uint8_t> as NumGtsSlots;
- interface GetNow<bool> as IsRxBroadcastPending;
+ interface StdControl as TrackSingleBeacon;
}
uses
{
interface MLME_GET;
interface MLME_SET;
interface FrameUtility;
- interface Notify<bool> as FindBeacon;
interface IEEE154BeaconFrame as BeaconFrame;
interface Alarm<TSymbolIEEE802154,uint32_t> as TrackAlarm;
interface RadioRx as BeaconRx;
interface RadioOff;
- interface GetNow<bool> as IsBeaconEnabledPAN;
interface DataRequest;
interface FrameRx as CoordRealignmentRx;
interface Resource as Token;
interface GetNow<bool> as IsTokenRequested;
- interface ResourceTransfer as TokenToCap;
interface ResourceTransferred as TokenTransferred;
- interface GetNow<bool> as IsSendingBeacons;
+ interface ResourceTransfer as TokenToCap;
interface TimeCalc;
interface IEEE154Frame as Frame;
interface Leds;
- interface Ieee802154Debug as Debug;
}
}
implementation
{
+ command error_t Reset.init() { return SUCCESS; }
- command error_t Init.init() { return SUCCESS; }
-
- command ieee154_status_t MLME_SYNC.request (
- uint8_t logicalChannel,
- uint8_t channelPage,
- bool trackBeacon
- )
+ command ieee154_status_t MLME_SYNC.request ( uint8_t logicalChannel, uint8_t channelPage, bool trackBeacon)
{
return IEEE154_TRANSACTION_OVERFLOW;
}
event void Token.granted() { }
- async event void TokenTransferred.transferred() { call Token.release(); }
+ async event void TokenTransferred.transferred() { }
- async event void TrackAlarm.fired() {}
+ async event void RadioOff.offDone() { }
- async event void BeaconRx.prepareDone() {}
+ async event void BeaconRx.enableRxDone() { }
- event message_t* BeaconRx.received(message_t* frame, ieee154_reftime_t *timestamp) { return frame;}
+ async event void TrackAlarm.fired() { }
- async event void RadioOff.offDone() {}
+ event message_t* BeaconRx.received(message_t *frame, const ieee154_timestamp_t *timestamp) { return frame; }
- async command bool IsTrackingBeacons.getNow(){ return FALSE;}
- command uint32_t GetLastBeaconRxTime.get(){ return 0;}
- async command uint8_t* GtsField.getNow() { return 0; }
- async command uint32_t SfSlotDuration.getNow() { return 0; }
- async command uint8_t FinalCapSlot.getNow() { return 0; }
+ command error_t TrackSingleBeacon.start()
+ {
+ return FAIL;
+ }
+
+ command error_t TrackSingleBeacon.stop()
+ {
+ return FAIL;
+ }
+
+ /* ----------------------- SF Structure, etc. ----------------------- */
+
+ async command uint32_t IncomingSF.sfStartTime() { return 0; }
+ async command uint16_t IncomingSF.sfSlotDuration() { return 0; }
+ async command uint8_t IncomingSF.numCapSlots() { return 0; }
+ async command uint8_t IncomingSF.numGtsSlots() { return 0; }
+ async command uint16_t IncomingSF.battLifeExtDuration() { return 0; }
+ async command const uint8_t* IncomingSF.gtsFields() { return NULL; }
+ async command uint16_t IncomingSF.guardTime() { return 0; }
+ async command const ieee154_timestamp_t* IncomingSF.sfStartTimeRef() { return NULL; }
+ async command bool IncomingSF.isBroadcastPending() { return 0; }
+ async command bool IsTrackingBeacons.getNow() { return 0; }
event void DataRequest.pollDone(){}
- async command uint32_t CapEnd.getNow() { return 0; }
- async command uint32_t CapStart.getNow() { return 0; }
- async command uint32_t CapLen.getNow() { return 0; }
- async command uint32_t CfpEnd.getNow() { return 0; }
- async command ieee154_reftime_t* CapStartRefTime.getNow() { return NULL; }
- async command uint32_t CfpLen.getNow(){ return 0;}
- async command uint32_t BeaconInterval.getNow(){ return 0;}
- async command bool IsBLEActive.getNow(){ return 0;}
- async command uint16_t BLELen.getNow(){ return 0;}
- async command uint8_t NumGtsSlots.getNow() { return 0; }
- async command bool IsRxBroadcastPending.getNow() { return FALSE; }
- event message_t* CoordRealignmentRx.received(message_t* frame) {return frame;}
- event void FindBeacon.notify( bool val ){}
+
+ default event message_t* MLME_BEACON_NOTIFY.indication (message_t* frame){return frame;}
+ default event void MLME_SYNC_LOSS.indication (
+ ieee154_status_t lossReason,
+ uint16_t panID,
+ uint8_t logicalChannel,
+ uint8_t channelPage,
+ ieee154_security_t *security){}
+
+ event message_t* CoordRealignmentRx.received(message_t* frame) { return frame; }
}
* ========================================================================
*/
+ /** Empty placeholder component for BeaconTransmitP. */
+
#include "TKN154_MAC.h"
#include "TKN154_PHY.h"
module NoBeaconTransmitP
{
provides
{
- interface Init;
+ interface Init as Reset;
interface MLME_START;
- interface WriteBeaconField as SuperframeSpecWrite;
- interface GetNow<bool> as IsSendingBeacons;
- interface GetNow<uint32_t> as CapStart;
- interface GetNow<ieee154_reftime_t*> as CapStartRefTime;
- interface GetNow<uint32_t> as CapLen;
- interface GetNow<uint32_t> as CapEnd;
- interface GetNow<uint32_t> as CfpEnd;
- interface GetNow<uint32_t> as CfpLen;
- interface GetNow<bool> as IsBLEActive;
- interface GetNow<uint16_t> as BLELen;
- interface GetNow<uint8_t*> as GtsField;
- interface GetNow<uint32_t> as SfSlotDuration;
- interface GetNow<uint32_t> as BeaconInterval;
- interface GetNow<uint8_t> as FinalCapSlot;
- interface GetNow<uint8_t> as NumGtsSlots;
- interface GetNow<bool> as BeaconFramePendingBit;
interface IEEE154TxBeaconPayload;
+ interface SuperframeStructure as OutgoingSF;
+ interface GetNow<bool> as IsSendingBeacons;
} uses {
interface Notify<bool> as GtsSpecUpdated;
interface Notify<bool> as PendingAddrSpecUpdated;
interface Notify<const void*> as PIBUpdate[uint8_t attributeID];
- interface Alarm<TSymbolIEEE802154,uint32_t> as BeaconTxAlarm;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as BeaconSendAlarm;
interface Timer<TSymbolIEEE802154> as BeaconPayloadUpdateTimer;
interface RadioOff;
- interface GetNow<bool> as IsBeaconEnabledPAN;
interface RadioTx as BeaconTx;
interface MLME_GET;
interface MLME_SET;
interface Resource as Token;
- interface GetNow<bool> as IsTokenRequested;
- interface ResourceTransfer as TokenToBroadcast;
interface ResourceTransferred as TokenTransferred;
+ interface ResourceTransfer as TokenToBroadcast;
+ interface GetNow<bool> as IsTokenRequested;
interface FrameTx as RealignmentBeaconEnabledTx;
interface FrameTx as RealignmentNonBeaconEnabledTx;
interface FrameRx as BeaconRequestRx;
interface WriteBeaconField as PendingAddrWrite;
interface FrameUtility;
interface GetNow<bool> as IsTrackingBeacons;
- interface GetNow<uint32_t> as LastBeaconRxTime;
- interface GetNow<ieee154_reftime_t*> as LastBeaconRxRefTime;
- interface Ieee802154Debug as Debug;
+ interface SuperframeStructure as IncomingSF;
interface Set<ieee154_macSuperframeOrder_t> as SetMacSuperframeOrder;
interface Set<ieee154_macBeaconTxTime_t> as SetMacBeaconTxTime;
interface Set<ieee154_macPanCoordinator_t> as SetMacPanCoordinator;
}
implementation
{
- command error_t Init.init()
- {
- return SUCCESS;
- }
+ command error_t Reset.init() { return SUCCESS; }
+
command ieee154_status_t MLME_START.request (
uint16_t panID,
uint8_t logicalChannel,
async event void RadioOff.offDone() { }
- async event void BeaconTxAlarm.fired() {}
-
- async event void BeaconTx.loadDone() {}
-
- async event void BeaconTx.transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime){}
-
- async event void BeaconTx.transmitUnslottedCsmaCaDone(ieee154_txframe_t *frame,
- bool ackPendingFlag, ieee154_csma_t *csmaParameters, error_t result){}
+ async event void BeaconSendAlarm.fired() {}
- async event void BeaconTx.transmitSlottedCsmaCaDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime,
- bool ackPendingFlag, uint16_t remainingBackoff, ieee154_csma_t *csmaParameters, error_t result){}
+ async event void BeaconTx.transmitDone(ieee154_txframe_t *frame, const ieee154_timestamp_t *timestamp, error_t result){}
command error_t IEEE154TxBeaconPayload.setBeaconPayload(void *beaconPayload, uint8_t length) { return ESIZE; }
{
}
- command uint8_t SuperframeSpecWrite.write(uint8_t *superframeSpecField, uint8_t maxlen)
- {
- return 0;
- }
-
- command uint8_t SuperframeSpecWrite.getLength()
- {
- return 0;
- }
-
event void RealignmentBeaconEnabledTx.transmitDone(ieee154_txframe_t *frame, ieee154_status_t status)
{
}
return frame;
}
- async command bool IsSendingBeacons.getNow(){ return FALSE;}
+ async command uint32_t OutgoingSF.sfStartTime() {return 0;}
- async command uint32_t CapStart.getNow() { return 0; }
- async command ieee154_reftime_t* CapStartRefTime.getNow() { return NULL; }
- async command uint32_t CapLen.getNow() { return 0;}
- async command uint32_t CapEnd.getNow()
- {
- return 0;
- }
- async command uint32_t CfpEnd.getNow()
- {
- return 0;
- }
- async command uint32_t CfpLen.getNow()
- {
- return 0;
- }
- async command bool IsBLEActive.getNow(){ return FALSE;}
- async command uint16_t BLELen.getNow(){ return 0;}
- async command bool BeaconFramePendingBit.getNow(){ return FALSE;}
+ async command uint16_t OutgoingSF.sfSlotDuration() {return 0;}
+
+ async command uint8_t OutgoingSF.numCapSlots() {return 0;}
- async command uint8_t* GtsField.getNow() { return NULL; }
- async command uint32_t SfSlotDuration.getNow() { return 0; }
- async command uint32_t BeaconInterval.getNow() { return 0; }
- async command uint8_t FinalCapSlot.getNow() { return 0; }
- async command uint8_t NumGtsSlots.getNow() { return 0; }
+ async command uint8_t OutgoingSF.numGtsSlots() {return 0;}
- default event void MLME_START.confirm (
- ieee154_status_t status
- ){}
+ async command uint16_t OutgoingSF.battLifeExtDuration() {return 0;}
- default event void IEEE154TxBeaconPayload.setBeaconPayloadDone(void *beaconPayload, uint8_t length){}
+ async command const uint8_t* OutgoingSF.gtsFields() {return NULL;}
- default event void IEEE154TxBeaconPayload.modifyBeaconPayloadDone(uint8_t offset, void *buffer, uint8_t bufferLength){}
+ async command uint16_t OutgoingSF.guardTime() {return 0;}
- default event void IEEE154TxBeaconPayload.aboutToTransmit(){}
+ async command const ieee154_timestamp_t* OutgoingSF.sfStartTimeRef() {return NULL;}
- default event void IEEE154TxBeaconPayload.beaconTransmitted(){}
+ async command bool OutgoingSF.isBroadcastPending() {return FALSE;}
+ async command bool IsSendingBeacons.getNow() {return FALSE;}
}
* ========================================================================
*/
+ /** Empty placeholder component for CoordBroadcastP. */
+
#include "TKN154_MAC.h"
module NoCoordBroadcastP
{
interface ResourceTransfer as TokenToCap;
interface ResourceTransferred as TokenTransferred;
interface GetNow<bool> as BeaconFramePendingBit;
+ interface SuperframeStructure as OutgoingSF;
interface Leds;
}
}
* @author Jan Hauer <hauer@tkn.tu-berlin.de>
* ========================================================================
*/
-
+
/**
* The contention free period (CFP) in beacon mode, a.k.a. GTS, is not yet
* implemented - this is only an empty placeholder. In contrast to the CAP
interface ResourceTransferred as TokenTransferred;
interface ResourceTransfer as TokenToBeaconTransmit;
interface ResourceRequested as TokenRequested;
- interface GetNow<bool> as IsTokenRequested;
- interface GetNow<bool> as IsTrackingBeacons;
- interface GetNow<uint32_t> as CfpEnd;
- interface GetNow<ieee154_reftime_t*> as CapStartRefTime;
- interface GetNow<uint8_t*> as GtsField;
- interface GetNow<uint32_t> as SfSlotDuration;
- interface GetNow<uint8_t> as FinalCapSlot;
interface Alarm<TSymbolIEEE802154,uint32_t> as CfpSlotAlarm;
interface Alarm<TSymbolIEEE802154,uint32_t> as CfpEndAlarm;
+ interface SuperframeStructure as OutgoingSF;
interface RadioTx;
interface RadioRx;
interface RadioOff;
// the CFP has started, this component now owns the token -
// because GTS is not implemented we pass it back to the
// BeaconTransmitP component
- // Note: this component must not use the Resource
- // interface to release the token!
call TokenToBeaconTransmit.transfer();
}
return 1;
}
- async event void RadioTx.loadDone(){}
- async event void RadioTx.transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime){}
+ async event void RadioTx.transmitDone(ieee154_txframe_t *frame, const ieee154_timestamp_t *timestamp, error_t result){}
- async event void RadioRx.prepareDone(){}
- event message_t* RadioRx.received(message_t *frame, ieee154_reftime_t *timestamp){return frame;}
+ async event void RadioRx.enableRxDone(){}
+ event message_t* RadioRx.received(message_t *frame, const ieee154_timestamp_t *timestamp){return frame;}
async event void TokenRequested.requested()
{
}
async event void TokenRequested.immediateRequested(){ }
- async event void RadioTx.transmitUnslottedCsmaCaDone(ieee154_txframe_t *frame,
- bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result){}
- async event void RadioTx.transmitSlottedCsmaCaDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime,
- bool ackPendingFlag, uint16_t remainingBackoff, ieee154_csma_t *csmaParams, error_t result){}
}
* ========================================================================
*/
+ /** Empty placeholder component for CoordRealignmentP. */
+
#include "TKN154_MAC.h"
module NoCoordRealignmentP
{
+++ /dev/null
-/*
- * Copyright (c) 2008, Technische Universitaet Berlin
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * - Neither the name of the Technische Universitaet Berlin nor the names
- * of its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * - Revision -------------------------------------------------------------
- * $Revision$
- * $Date$
- * @author Jan Hauer <hauer@tkn.tu-berlin.de>
- * ========================================================================
- */
-#include "TKN154_DEBUG.h"
-module NoDebugP
-{
- provides
- {
- interface Ieee802154Debug[uint8_t client];
- }
-}
-implementation
-{
- async command void Ieee802154Debug.log[uint8_t client](
- uint8_t priority,
- uint8_t eventID,
- uint32_t param1,
- uint32_t param2,
- uint32_t param3)
- {
- }
- command void Ieee802154Debug.flush[uint8_t client](){}
-}
interface ResourceTransferred as TokenTransferred;
interface ResourceRequested as TokenRequested;
interface ResourceTransfer as TokenToBeaconSync;
- interface GetNow<ieee154_reftime_t*> as CapStartRefTime;
- interface GetNow<bool> as IsSendingBeacons;
- interface GetNow<uint32_t> as CfpEnd;
- interface GetNow<uint8_t*> as GtsField;
- interface GetNow<uint32_t> as SfSlotDuration;
- interface GetNow<uint8_t> as FinalCapSlot;
interface Alarm<TSymbolIEEE802154,uint32_t> as CfpSlotAlarm;
interface Alarm<TSymbolIEEE802154,uint32_t> as CfpEndAlarm;
+ interface SuperframeStructure as IncomingSF;
interface RadioTx;
interface RadioRx;
interface RadioOff;
// the CFP has started, this component now owns the token -
// because GTS is not implemented we pass it back to the
// BeaconTransmitP component
- // Note: this component must not use the Resource
- // interface to release the token!
call TokenToBeaconSync.transfer();
}
async event void RadioOff.offDone() {}
- async event void RadioTx.loadDone(){}
- async event void RadioTx.transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime){}
-
- async event void RadioRx.prepareDone(){}
- event message_t* RadioRx.received(message_t *frame, ieee154_reftime_t *timestamp){return frame;}
+ async event void RadioTx.transmitDone(ieee154_txframe_t *frame, const ieee154_timestamp_t *timestamp, error_t result){}
+ async event void RadioRx.enableRxDone(){}
+ event message_t* RadioRx.received(message_t *frame, const ieee154_timestamp_t *timestamp){return frame;}
async event void TokenRequested.requested()
{
}
async event void TokenRequested.immediateRequested(){ }
-
- async event void RadioTx.transmitUnslottedCsmaCaDone(ieee154_txframe_t *frame,
- bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result){}
- async event void RadioTx.transmitSlottedCsmaCaDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime,
- bool ackPendingFlag, uint16_t remainingBackoff, ieee154_csma_t *csmaParams, error_t result){}
}
* ========================================================================
*/
+ /** Empty placeholder component for DisassociateP. */
#include "TKN154_MAC.h"
interface FrameUtility;
interface IEEE154Frame as Frame;
interface Get<uint64_t> as LocalExtendedAddress;
- interface Ieee802154Debug as Debug;
}
}
implementation
command error_t Init.init() { return SUCCESS; }
-/* ------------------- MLME_DISASSOCIATE (initiating) ------------------- */
+ /* ------------------- MLME_DISASSOCIATE (initiating) ------------------- */
command ieee154_status_t MLME_DISASSOCIATE.request (
uint8_t DeviceAddrMode,
event void DisassociationDirectTx.transmitDone(ieee154_txframe_t *data, ieee154_status_t status) { }
-/* ------------------- MLME_DISASSOCIATE (receiving) ------------------- */
+ /* ------------------- MLME_DISASSOCIATE (receiving) ------------------- */
event message_t* DisassociationDirectRxFromCoord.received(message_t* frame) { return frame; }
event message_t* DisassociationRxFromDevice.received(message_t* frame) { return frame; }
-/* ------------------- Defaults ------------------- */
+ /* ------------------- Defaults ------------------- */
default event void MLME_DISASSOCIATE.indication (
uint64_t DeviceAddress,
+++ /dev/null
-/*
- * Copyright (c) 2008, Technische Universitaet Berlin
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * - Neither the name of the Technische Universitaet Berlin nor the names
- * of its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * - Revision -------------------------------------------------------------
- * $Revision$
- * $Date$
- * @author Jan Hauer <hauer@tkn.tu-berlin.de>
- * ========================================================================
- */
-
-#include "TKN154_PHY.h"
-#include "TKN154_MAC.h"
-
-generic module NoFrameDispatchP(uint8_t superframeDirection)
-{
- provides
- {
- interface Init as Reset;
- interface FrameTx as FrameTx;
- interface FrameRx as FrameRx[uint8_t frameType];
- interface FrameExtracted as FrameExtracted[uint8_t frameType];
- interface FrameTxNow as BroadcastTx;
- interface Notify<bool> as WasRxEnabled;
- interface Notify<bool> as FindBeacon;
- }
- uses
- {
- interface Alarm<TSymbolIEEE802154,uint32_t> as CapEndAlarm;
- interface Alarm<TSymbolIEEE802154,uint32_t> as BLEAlarm;
- interface Alarm<TSymbolIEEE802154,uint32_t> as IndirectTxWaitAlarm;
- interface Alarm<TSymbolIEEE802154,uint32_t> as BroadcastAlarm;
- interface Resource as Token;
- interface GetNow<bool> as IsTokenRequested;
- interface ResourceTransfer as TokenToCfp;
- interface ResourceTransferred as TokenTransferred;
- interface GetNow<uint32_t> as CapStart;
- interface GetNow<ieee154_reftime_t*> as CapStartRefTime;
- interface GetNow<uint32_t> as CapLen;
- interface GetNow<bool> as IsBLEActive;
- interface GetNow<uint16_t> as BLELen;
- interface GetNow<bool> as IsRxBroadcastPending;
- interface GetNow<bool> as IsRxEnableActive;
- interface Get<ieee154_txframe_t*> as GetIndirectTxFrame;
- interface Notify<bool> as RxEnableStateChange;
- interface GetNow<bool> as IsTrackingBeacons;
- interface FrameUtility;
- interface RadioTx;
- interface RadioRx;
- interface RadioOff;
- interface GetNow<bool> as IsBeaconEnabledPAN;
- interface MLME_GET;
- interface MLME_SET;
- interface Ieee802154Debug as Debug;
- interface TimeCalc;
- interface Leds;
- interface SetNow<ieee154_cap_frame_backup_t*> as FrameBackup;
- interface GetNow<ieee154_cap_frame_backup_t*> as FrameRestore;
- }
-}
-implementation
-{
- command error_t Reset.init()
- {
- return SUCCESS;
- }
-
- async event void TokenTransferred.transferred()
- {
- call TokenToCfp.transfer();
- }
-
- command ieee154_status_t FrameTx.transmit(ieee154_txframe_t *frame)
- {
- return IEEE154_TRANSACTION_OVERFLOW;
- }
-
- async event void RadioTx.loadDone(){ }
- async event void RadioOff.offDone(){ }
- async event void RadioRx.prepareDone(){ }
-
- async event void CapEndAlarm.fired(){ }
- async event void BLEAlarm.fired(){ }
- event void RxEnableStateChange.notify(bool whatever){ }
- async event void BroadcastAlarm.fired(){ }
-
- async event void IndirectTxWaitAlarm.fired() { }
-
- async event void RadioTx.transmitUnslottedCsmaCaDone(ieee154_txframe_t *frame,
- bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result)
- {
- }
-
- async event void RadioTx.transmitSlottedCsmaCaDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime,
- bool ackPendingFlag, uint16_t remainingBackoff, ieee154_csma_t *csmaParams, error_t result)
- {
- }
-
- void transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime,
- bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result)
- {
- }
-
- event message_t* RadioRx.received(message_t* frame, ieee154_reftime_t *timestamp)
- {
- return frame;
- }
-
- async command ieee154_status_t BroadcastTx.transmitNow(ieee154_txframe_t *frame)
- {
- return IEEE154_TRANSACTION_OVERFLOW;
- }
-
- event void Token.granted()
- {
- }
-
- async event void RadioTx.transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime){}
-
- default event void FrameTx.transmitDone(ieee154_txframe_t *data, ieee154_status_t status){}
- default event message_t* FrameRx.received[uint8_t client](message_t* data){return data;}
- default async command bool IsRxEnableActive.getNow(){return FALSE;}
-
- default async command void IndirectTxWaitAlarm.start(uint32_t dt){call Leds.led0On();}
- default async command void IndirectTxWaitAlarm.stop(){call Leds.led0On();}
- default async command void IndirectTxWaitAlarm.startAt(uint32_t t0, uint32_t dt){call Leds.led0On();}
-
- default async command void BroadcastAlarm.start(uint32_t dt){call Leds.led0On();}
- default async command void BroadcastAlarm.stop(){call Leds.led0On();}
- default async command void BroadcastAlarm.startAt(uint32_t t0, uint32_t dt){call Leds.led0On();}
-
- default async command bool IsRxBroadcastPending.getNow(){ return FALSE;}
- default async event void BroadcastTx.transmitNowDone(ieee154_txframe_t *frame, ieee154_status_t status){}
- default event message_t* FrameExtracted.received[uint8_t client](message_t* msg, ieee154_txframe_t *txFrame){return msg;}
- default async command error_t FrameBackup.setNow(ieee154_cap_frame_backup_t* val ){return FAIL;}
- default async command ieee154_cap_frame_backup_t* FrameRestore.getNow(){return NULL;}
-
- command error_t WasRxEnabled.enable(){return FAIL;}
- command error_t WasRxEnabled.disable(){return FAIL;}
- command error_t FindBeacon.enable(){return FAIL;}
- command error_t FindBeacon.disable(){return FAIL;}
-}
* @author Jan Hauer <hauer@tkn.tu-berlin.de>
* ========================================================================
*/
+
+ /** Empty placeholder component for FrameDispatchQueueP. */
+
#include "TKN154_MAC.h"
generic module NoFrameDispatchQueueP() {
provides
* ========================================================================
*/
+ /** Empty placeholder component for PromiscuousModeP. */
+
#include "TKN154_PHY.h"
#include "TKN154_MAC.h"
module NoPromiscuousModeP
interface RadioRx as PromiscuousRx;
interface RadioOff;
interface Set<bool> as RadioPromiscuousMode;
- interface Ieee802154Debug as Debug;
}
}
implementation
command error_t Init.init() { return SUCCESS; }
-/* ----------------------- Promiscuous Mode ----------------------- */
+ /* ----------------------- Promiscuous Mode ----------------------- */
command bool PromiscuousModeGet.get() { return FALSE; }
async event void PromiscuousRx.prepareDone() { }
- event message_t* PromiscuousRx.received(message_t *frame, ieee154_reftime_t *timestamp) { return frame; }
+ event message_t* PromiscuousRx.received(message_t *frame, ieee154_timestamp_t *timestamp) { return frame; }
command error_t PromiscuousMode.stop() { return FAIL; }
* ========================================================================
*/
+ /** Empty placeholder component for RxEnableP. */
+
#include "TKN154_PHY.h"
#include "TKN154_MAC.h"
module NoRxEnableP
}
uses
{
- interface Ieee802154Debug as Debug;
interface Timer<TSymbolIEEE802154> as RxEnableTimer;
- interface GetNow<bool> as IsBeaconEnabledPAN;
interface Get<ieee154_macPanCoordinator_t> as IsMacPanCoordinator;
interface GetNow<bool> as IsTrackingBeacons;
- interface GetNow<uint32_t> as IncomingSfStart;
- interface GetNow<uint32_t> as IncomingBeaconInterval;
interface GetNow<bool> as IsSendingBeacons;
- interface GetNow<uint32_t> as OutgoingSfStart;
- interface GetNow<uint32_t> as OutgoingBeaconInterval;
+ interface SuperframeStructure as IncomingSuperframeStructure;
+ interface SuperframeStructure as OutgoingSuperframeStructure;
interface Notify<bool> as WasRxEnabled;
interface TimeCalc;
}
command error_t Init.init() { return SUCCESS; }
-/* ----------------------- MLME-RX-ENABLE ----------------------- */
+ /* ----------------------- MLME-RX-ENABLE ----------------------- */
command ieee154_status_t MLME_RX_ENABLE.request (
bool DeferPermit,
* ========================================================================
*/
+ /** Empty placeholder component for ScanP. */
+
#include "TKN154_MAC.h"
module NoScanP
event void EnergyDetection.done(error_t status, int8_t EnergyLevel){}
- async event void RadioRx.prepareDone() { }
+ async event void RadioRx.enableRxDone(){}
- event message_t* RadioRx.received(message_t *frame, ieee154_reftime_t *time)
+ event message_t* RadioRx.received(message_t *frame, const ieee154_timestamp_t *timestamp)
{
return frame;
}
- async event void RadioTx.loadDone() { }
-
- async event void RadioTx.transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime){}
-
- async event void RadioTx.transmitUnslottedCsmaCaDone(ieee154_txframe_t *frame,
- bool ackPendingFlag, ieee154_csma_t *csmaParameters, error_t result){}
+ async event void RadioTx.transmitDone(ieee154_txframe_t *frame,
+ const ieee154_timestamp_t *timestamp, error_t result){}
- async event void RadioTx.transmitSlottedCsmaCaDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime,
- bool ackPendingFlag, uint16_t remainingBackoff, ieee154_csma_t *csmaParameters, error_t result){}
-
event void ScanTimer.fired() { }
async event void RadioOff.offDone() { }
--- /dev/null
+/*
+ * Copyright (c) 2008, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+ /** Empty placeholder component for SlottedFrameDispatchP. */
+
+#include "TKN154_PHY.h"
+#include "TKN154_MAC.h"
+
+generic module NoSlottedFrameDispatchP(uint8_t superframeDirection)
+{
+ provides
+ {
+ interface Init as Reset;
+ interface FrameTx as FrameTx;
+ interface FrameRx as FrameRx[uint8_t frameType];
+ interface FrameExtracted as FrameExtracted[uint8_t frameType];
+ interface FrameTxNow as BroadcastTx;
+ interface Notify<bool> as WasRxEnabled;
+ }
+ uses
+ {
+ interface Alarm<TSymbolIEEE802154,uint32_t> as CapEndAlarm;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as BLEAlarm;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as IndirectTxWaitAlarm;
+ interface Alarm<TSymbolIEEE802154,uint32_t> as BroadcastAlarm;
+ interface Resource as Token;
+ interface GetNow<bool> as IsTokenRequested;
+ interface ResourceTransfer as TokenToCfp;
+ interface ResourceTransferred as TokenTransferred;
+ interface SuperframeStructure;
+ interface GetNow<bool> as IsRxEnableActive;
+ interface Get<ieee154_txframe_t*> as GetIndirectTxFrame;
+ interface Notify<bool> as RxEnableStateChange;
+ interface GetNow<bool> as IsTrackingBeacons;
+ interface FrameUtility;
+ interface SlottedCsmaCa;
+ interface RadioRx;
+ interface RadioOff;
+ interface MLME_GET;
+ interface MLME_SET;
+ interface TimeCalc;
+ interface Leds;
+ interface SetNow<ieee154_cap_frame_backup_t*> as FrameBackup;
+ interface GetNow<ieee154_cap_frame_backup_t*> as FrameRestore;
+ interface StdControl as TrackSingleBeacon;
+ }
+}
+implementation
+{
+ command error_t Reset.init() { return SUCCESS; }
+
+ async event void TokenTransferred.transferred() { }
+
+ command ieee154_status_t FrameTx.transmit(ieee154_txframe_t *frame) { return IEEE154_TRANSACTION_OVERFLOW; }
+
+ async event void RadioOff.offDone(){ }
+
+ async event void RadioRx.enableRxDone(){}
+
+ async event void CapEndAlarm.fired(){ }
+
+ async event void BLEAlarm.fired(){ }
+
+ event void RxEnableStateChange.notify(bool whatever){ }
+
+ async event void BroadcastAlarm.fired(){ }
+
+ async event void IndirectTxWaitAlarm.fired() { }
+
+ async event void SlottedCsmaCa.transmitDone(ieee154_txframe_t *frame, ieee154_csma_t *csma,
+ bool ackPendingFlag, uint16_t remainingBackoff, error_t result) { }
+
+ event message_t* RadioRx.received(message_t* frame, const ieee154_timestamp_t *timestamp) { return frame; }
+
+ async command ieee154_status_t BroadcastTx.transmitNow(ieee154_txframe_t *frame) { }
+
+ event void Token.granted() { }
+
+ command error_t WasRxEnabled.enable(){return FAIL;}
+ command error_t WasRxEnabled.disable(){return FAIL;}
+}
* ========================================================================
*/
+/**
+ * The MCPS-DATA.request primitive requests the transfer of a data SPDU (i.e.,
+ * MSDU) from a local SSCS entity to a single peer SSCS entity. (IEEE
+ * 802.15.4-2006, Sect. 7.1.1)
+ */
+
#include "TKN154.h"
#include <message.h>
{
/**
- * "The MCPS-DATA.request primitive requests the transfer of a data
- * SPDU (i.e., MSDU) from a local SSCS entity to a single peer SSCS
- * entity." (IEEE 802.15.4-2006, Sec. 7.1.1.1)
+ * "Requests to transfer a data SPDU (i.e., MSDU) from a local SSCS
+ * entity to a single peer SSCS entity." (IEEE 802.15.4-2006, Sec.
+ * 7.1.1.1)
*
- * The MSDU is the payload portion of a message_t (<tt>frame</tt>
- * parameter) and can be accessed through the <tt>IEEE154Frame</tt>
- * interface. In contrast to the standard interface definition address
- * information is not passed as separate parameters; instead, the
- * address information is already part of the <tt>frame</tt>,
- * i.e. it must have been set (through the <tt>IEEE154Frame</tt>
- * interface) before this command is called.
+ * The source/destination addressing mode, destination PAN
+ * identifier, destination address, the payload and (optionally) the
+ * security mode/key are part of the <tt>frame</tt> and must have
+ * been set (through the <tt>IEEE154Frame</tt> interface) before
+ * calling this command.
*
* If this command returns IEEE154_SUCCESS, then the confirm event
* will be signalled in the future; otherwise, the confirm event
*
* @param frame The frame to send
* @param payloadLen The length of the frame payload
- * @param msduHandle Handle associated with the frame to be transmitted
+ * @param msduHandle Handle associated with the frame
* @param TxOptions Bitwised OR transmission options
*
- * @return IEEE154_SUCCESS if the request succeeded and a confirm event
- * will be signalled, an appropriate error code otherwise
- * (no confirm event will be signalled in this case)
+ * @return IEEE154_SUCCESS if the request succeeded and only
+ * then the <tt>confirm()</tt> event will be signalled;
+ * an appropriate error code otherwise
* @see confirm
*/
);
/**
- * Confirm reports the results of a request to transfer a frame to a
- * peer SSCS entity.
+ * Reports the result of a request to transfer a frame to a peer
+ * SSCS entity.
*
- * @param frame The frame which was requested to send
+ * @param frame The frame which was requested to be sent
* @param msduHandle The handle associated with the frame
* @param status The status of the last MSDU transmission
- * @param timestamp Time of transmission (invalid if status is
- * not IEEE154_SUCCESS)
+ * @param timestamp Time of transmission (invalid if <tt>status</tt>
+ * is not IEEE154_SUCCESS)
*/
event void confirm (
message_t *frame,
);
/**
- * Indicates the arrival of a frame. Address information can be accessed
- * through the <tt>IEEE154Frame</tt> interface.
+ * Indicates the arrival of a frame. Use the <tt>IEEE154Frame</tt>
+ * interface to get the payload, source/destination addresses, DSN
+ * and other information associated with this frame.
*
* @return A frame buffer for the stack to use for the next received frame
*/
* ========================================================================
*/
+/**
+ * The MCPS-PURGE.request primitive allows the next higher layer to purge an
+ * MSDU from the transaction queue. (IEEE 802.15.4-2006, Sect. 7.1.1)
+ */
+
#include "TKN154.h"
interface MCPS_PURGE {
/**
- * Request to purge a frame from the transaction queue.
- * The result will be returned immediately (there
- * is no confirm event for this command).
+ * Requests to purge a frame from the transaction queue. The result
+ * will be returned immediately (there is no confirm event for this
+ * command).
*
* @param msduHandle The handle of the frame to be purged from the
* transaction queue
+ *
* @return IEEE154_SUCCESS if the request succeeded, an
* appropriate error code otherwise
*/
* ========================================================================
*/
+/**
+ * MLME-SAP association primitives define how a device becomes
+ * associated with a PAN. (IEEE 802.15.4-2006, Sect. 7.1.3)
+ */
+
#include "TKN154.h"
interface MLME_ASSOCIATE {
* of the associating device
* @param security The security options (NULL means security is
* disabled)
+ *
* @return IEEE154_SUCCESS if the request succeeded and a confirm event
* will be signalled, an appropriate error code otherwise
* (no confirm event will be signalled in this case)
);
/**
- * Notification that a device has requested to associate with a PAN.
+ * Notification that a device has requested to associate with this PAN.
*
* @param DeviceAddress the 64-bit address of the requesting device
* @param CapabilityInformation Specifies the operational capabilities
);
/**
- * Send a response to a device's request to associate
+ * Sends a response to a device that requested to associate with this PAN.
*
* @param DeviceAddress The 64-bit address of the device to respond to
* @param AssocShortAddress The short device address allocated by the
* @param status The status of the association attempt
* @param security The security options (NULL means security is
* disabled)
+ *
* @return IEEE154_SUCCESS if the request succeeded and an indication event
* will be signalled through the MLME_COMM_STATUS interface later,
- * otherwise an appropriate error code (no MLME_COMM_STATUS.indication
+ * an appropriate error code otherwise (no MLME_COMM_STATUS.indication
* event will be signalled in this case)
*/
command ieee154_status_t response (
);
/**
- * Confirmation of the association attempt.
+ * Confirms an association attempt.
*
* @param AssocShortAddress The short device address allocated by the
* coordinator on successful association
* ========================================================================
*/
+/**
+ * The MLME-SAP beacon notification primitive defines how a device may be
+ * notified when a beacon is received during normal operating conditions.
+ * (IEEE 802.15.4-2006, Sect. 7.1.5)
+ */
+
#include "TKN154.h"
#include <message.h>
+
interface MLME_BEACON_NOTIFY {
/**
- * A beacon frame has been received. This event is signalled only if
- * either the PIB attribute macAutoRequest is set to FALSE or the
- * beacon payload is not empty.
+ * A beacon frame has been received. This event is signalled only if
+ * either the PIB attribute <tt>macAutoRequest</tt> is set to FALSE
+ * or the beacon payload is not empty.
*
- * The beacon parameters can be accessed through the
- * <tt>IEEE154BeaconFrame<\tt> interface. The
- * <tt>IEEE154Frame<\tt> interface can be used to
- * inspect the addressing fields in the MAC header.
+ * The beacon parameters can be accessed through the
+ * <tt>IEEE154BeaconFrame</tt> interface. The <tt>IEEE154Frame</tt>
+ * interface can be used to inspect the addressing fields in the MAC
+ * header.
*
* @param beacon The beacon frame
+ *
* @return A frame buffer for the stack to use for the next received frame
*/
event message_t* indication ( message_t *beaconFrame );
* ========================================================================
*/
+/**
+ * The MLME-SAP communication status primitive defines how the MLME
+ * communicates to the next higher layer about transmission status,
+ * when the transmission was instigated by a response primitive, and
+ * about security errors on incoming packets. (IEEE 802.15.4-2006,
+ * Sect. 7.1.12)
+ */
+
#include "TKN154.h"
interface MLME_COMM_STATUS {
* ========================================================================
*/
+/**
+ * The MLME-SAP disassociation primitives define how a device can
+ * disassociate from a PAN. (IEEE 802.15.4-2006, Sect. 7.1.4)
+ */
+
#include "TKN154.h"
interface MLME_DISASSOCIATE {
/**
- * Request disassociation from a PAN.
+ * Requests disassociation from a PAN.
*
* @param DeviceAddrMode The addressing mode of the device to which to send
* the disassociation notification command.
* indirectly
* @param security The security options (NULL means security is
* disabled)
+ *
* @return IEEE154_SUCCESS if the request succeeded and a confirm event
* will be signalled, an appropriate error code otherwise
* (no confirm event will be signalled in this case)
);
/**
- * Signals that a device has requested disassociation.
+ * Signals that a device has requested disassociation from this PAN.
*
* @param DeviceAddress the 64-bit address of the requesting device
* @param DisassociateReason Reason for the disassociation
);
/**
- * Confirmation of the disassociation attempt.
+ * Confirmsn a disassociation attempt.
*
* @param status The status of the disassociation attempt
* @param DeviceAddrMode The addressing mode of the device that has either
* ========================================================================
*/
-/**
- * This interface can be used to read attribute values from the PHY/MAC PIB.
+/**
+ * This interface allows to read attribute values from the PHY/MAC PIB.
* Instead of passing the PIB attribute identifier, there is a separate
* command per attribute (and there are no confirm events).
*
- * NOTE: for the attributes macBeaconPayload (0x45) and
- * macBeaconPayloadLength (0x46) use the <tt>IEEE154TxBeaconPayload <\tt>
- * interface; for promiscuous mode there is a separate (SplitControl)
- * interface.
- **/
+ * NOTE: for the attributes <tt>macBeaconPayload</tt> (0x45) and
+ * <tt>macBeaconPayloadLength </tt>(0x46) use the
+ * <tt>IEEE154TxBeaconPayload</tt> interface; for promiscuous mode
+ * there is a separate (SplitControl) interface.
+ */
#include "TKN154.h"
interface MLME_GET {
command ieee154_macBattLifeExtPeriods_t macBattLifeExtPeriods();
/* macBeaconPayload (0x45) and macBeaconPayloadLength (0x46) are read
- * through the <tt>IEEE154TxBeaconPayload<\tt> interface. */
+ * through the <tt>IEEE154TxBeaconPayload</tt> interface. */
/** @return PIB attribute macBeaconOrder (0x47) */
command ieee154_macBeaconOrder_t macBeaconOrder();
/** @return PIB attribute macMinSIFSPeriod */
command ieee154_macMinSIFSPeriod_t macMinSIFSPeriod();
+
+ /** @return custom attribute macPanCoordinator */
+ command ieee154_macPanCoordinator_t macPanCoordinator();
}
* ========================================================================
*/
+/**
+ * The MLME-SAP GTS management primitives define how GTSs are
+ * requested and maintained. A device wishing to use these primitives
+ * and GTSs in general will already be tracking the beacons of its PAN
+ * coordinator. (IEEE 802.15.4-2006, Sect. 7.1.7)
+ */
+
#include "TKN154.h"
interface MLME_GTS {
* ========================================================================
*/
+/**
+ * MLME-SAP orphan notification primitives define how a coordinator
+ * can issue a notification of an orphaned device. (IEEE 802.15.4-2006,
+ * Sect. 7.1.8)
+ */
+
#include "TKN154.h"
interface MLME_ORPHAN {
* @author Jan Hauer <hauer@tkn.tu-berlin.de>
* ========================================================================
*/
+
+/**
+ * MLME-SAP polling primitives define how to request data from a
+ * coordinator. (IEEE 802.15.4-2006, Sect. 7.1.16)
+ */
+
#include "TKN154.h"
interface MLME_POLL {
* ========================================================================
*/
+/**
+ * MLME-SAP reset primitives specify how to reset the MAC sublayer to
+ * its default values. (IEEE 802.15.4-2006, Sect. 7.1.9)
+ */
+
#include "TKN154.h"
interface MLME_RESET {
/**
* Allows the next higher layer to request that the MLME performs a
- * reset operation. This command initializes the MAC and must be called
- * before calling any other MAC primitive. It extends the standard
- * interface definition by a parameter <tt>PANType</tt>, which defines
- * whether the device/coordinator will operate on a beacon-enabled PAN
- * or on a nonbeacon-enabled PAN.
+ * reset operation. This command initializes the MAC and must be
+ * called at least once before the MAC can be used.
*
* Two things are important:
* (1) This command will fail while promiscuous mode is enabled
* FALSE, the MAC sublayer is reset but all MAC PIB
* attributes retain their values prior to the
* generation of the reset primitive.
- * @param PANType Either BEACON_ENABLED_PAN for beacon-enabled PANs
- * or NONBEACON_ENABLED_PAN for nonbeacon-enabled PANs
*
* @return IEEE154_SUCCESS if the request succeeded and a confirm event
* will be signalled, an appropriate error code otherwise
*
*/
command ieee154_status_t request (
- bool SetDefaultPIB,
- uint8_t PANType
+ bool SetDefaultPIB
);
/**
* ========================================================================
*/
+/**
+ * MLME-SAP receiver state primitives define how a device can enable
+ * or disable the receiver at a given time. (IEEE 802.15.4-2006, Sect.
+ * 7.1.10)
+ */
+
#include "TKN154.h"
interface MLME_RX_ENABLE {
* ========================================================================
*/
+/**
+ * MLME-SAP scan primitives define how a device can determine the
+ * energy usage or the presence or absence of PANs in a communications
+ * channel. (IEEE 802.15.4-2006, Sect. 7.1.10)
+ */
+
#include "TKN154.h"
interface MLME_SCAN
{
/**
- * This interface can be used to set attribute values in the PHY/MAC PIB.
+ * This interface allows to set attribute values in the PHY/MAC PIB.
* Instead of passing the PIB attribute identifier, there is a separate
* command per attribute (and there are no confirm events).
*
- * NOTE: for the attributes macBeaconPayload (0x45) and
- * macBeaconPayloadLength (0x46) use the <tt>IEEE154TxBeaconPayload <\tt>
- * interface; for promiscuous mode there is a separate (SplitControl)
- * interface.
- **/
+ * NOTE: for the attributes <tt>macBeaconPayload</tt> (0x45) and
+ * <tt>macBeaconPayloadLength</tt> (0x46) use the
+ * <tt>IEEE154TxBeaconPayload</tt> interface; for promiscuous mode
+ * there is a separate (SplitControl) interface.
+ */
#include "TKN154.h"
interface MLME_SET {
command ieee154_status_t macBattLifeExtPeriods(ieee154_macBattLifeExtPeriods_t value);
/* macBeaconPayload (0x45) and macBeaconPayloadLength (0x46) are set
- * through the <tt>IEEE154TxBeaconPayload<\tt> interface. */
+ * through the <tt>IEEE154TxBeaconPayload</tt> interface. */
/** @param value new PIB attribute value for macBeaconOrder (0x47)
* @returns IEEE154_SUCCESS if PIB attribute was updated, INVALID_PARAMETER if
command ieee154_status_t macPANId(ieee154_macPANId_t value);
/* macPromiscuousMode (0x51) is (re-)set through the
- * <tt>PromiscuousMode<\tt> (SplitControl) interface. */
+ * <tt>PromiscuousMode</tt> (SplitControl) interface. */
/** @param value new PIB attribute value for macRxOnWhenIdle (0x52)
* @returns IEEE154_SUCCESS if PIB attribute was updated, INVALID_PARAMETER if
* ========================================================================
*/
+/**
+ * MLME-SAP start primitives define how an FFD can request to start
+ * using a new superframe configuration in order to initiate a PAN,
+ * begin transmitting beacons on an already existing PAN, thus
+ * facilitating device discovery, or to stop transmitting beacons.
+ * (IEEE 802.15.4-2006, Sect. 7.1.14)
+ */
+
#include "TKN154.h"
interface MLME_START {
* @author Jan Hauer <hauer@tkn.tu-berlin.de>
* ========================================================================
*/
+
+/**
+ * MLME-SAP synchronization primitives define how synchronization with
+ * a coordinator may be achieved and how a loss of synchronization is
+ * communicated to the next higher layer. (IEEE 802.15.4-2006, Sect.
+ * 7.1.15)
+ */
+
interface MLME_SYNC {
/**
* ========================================================================
*/
+/**
+ * MLME-SAP synchronization primitives define how synchronization with
+ * a coordinator may be achieved and how a loss of synchronization is
+ * communicated to the next higher layer. (IEEE 802.15.4-2006, Sect.
+ * 7.1.15)
+ */
+
#include "TKN154.h"
interface MLME_SYNC_LOSS {
command error_t start(uint32_t duration);
/**
- * Signalled in response to a call to <tt>start<\tt>;
+ * Signalled in response to a call to <tt>start</tt>;
* returns the maximum energy measured on the channel over the
* specified period of time.
*
* @param status SUCCESS if the measurement succeeded
- * and only then <tt>EnergyLevel<\tt> is valid, FAIL
+ * and only then <tt>EnergyLevel</tt> is valid, FAIL
* otherwise
* @param EnergyLevel The maximum energy on the channel
**/
interface FrameRx
{
/**
- * Received a frame buffer, returning a buffer for the signaling
- * component to use for the next reception.
+ * Received a frame.
*
* @param frame the received frame
* @return a buffer to be used by the stack for the next
interface FrameTx
{
/**
- * Transmits a frame buffer.
+ * Transmits a frame.
*
* @param txFrame the frame to transmit
* @return IEEE154_SUCCESS if the request was accepted and
command ieee154_status_t transmit(ieee154_txframe_t *txFrame);
/**
- * Signals the completion of the transmission of a frame buffer.
+ * Signals the completion of the transmission of a frame.
*
* @param txFrame the frame that was transmitted
* @param status the result of the transmission
interface FrameTxNow
{
/**
- * Transmits a frame buffer.
+ * Transmits a frame.
*
* @param txFrame the frame to transmit
* @return IEEE154_SUCCESS if the request was accepted and
/**
- * Signals the completion of the transmission of a frame buffer.
+ * Signals the completion of the transmission of a frame.
*
* @param txFrame the frame that was transmitted
* @param status the result of the transmission
+++ /dev/null
-/*
- * Copyright (c) 2008, Technische Universitaet Berlin
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * - Neither the name of the Technische Universitaet Berlin nor the names
- * of its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * - Revision -------------------------------------------------------------
- * $Revision$
- * $Date$
- * @author Jan Hauer <hauer@tkn.tu-berlin.de>
- * ========================================================================
- */
-interface Ieee802154Debug
-{
- async command void log(uint8_t priority, uint8_t eventID, uint32_t param1, uint32_t param2, uint32_t param3);
- command void flush();
-}
interface RadioOff
{
-
/**
* Disables the transceiver and changes the radio state to RADIO_OFF. This
- * command will succeed only if the current state of the radio is either
- * TX_LOADED, RX_PREPARED or RECEIVING.
+ * command will succeed only if the current state of the radio is RECEIVING.
*
* @return SUCCESS if the command was accepted and the <tt>offDone()</tt>
- * event will be signalled; EALREADY if radio is already switched off; FAIL
- * if the current radio state is neither TX_LOADED, RX_PREPARED nor
- * RECEIVING.
+ * event will be signalled; EALREADY if the radio is already switched off,
+ * i.e. in state RADIO_OFF; FAIL if the radio was not switched of because
+ * the current state is not RECEIVING.
*/
async command error_t off();
/**
* Tells whether the radio is in state RADIO_OFF.
+ *
* @return TRUE if the radio is in the state RADIO_OFF, FALSE otherwise
*/
async command bool isOff();
* @author Jan Hauer <hauer@tkn.tu-berlin.de>
* ========================================================================
*/
+
#include "TKN154_platform.h"
interface RadioRx
{
/**
- * Prepares the radio for receive mode. This command will fail, if the radio
- * is not in the state RADIO_OFF. The actual receive operation will be
- * triggered through a call to <tt>receive()</tt>.
+ * Switches the radio to receive mode at time <tt>t0 + dt</tt> or immediately
+ * if <tt>t0 + dt</tt> lies in the past. Analogous to the <tt>Timer</tt>
+ * interface <tt>t0</tt> is interpreted as a time in the past. Consequently,
+ * if <tt>dt = 0</tt> then the radio is always switched to receive mode
+ * immediately. This command will fail, if the radio is currently not in
+ * state RADIO_OFF. Once the radio is in receive mode an event
+ * <tt>enableRxDone</tt> will be signalled.
*
- * @return SUCCESS if the command was accepted and <tt>prepareDone()</tt>
- * will be signalled; EALREADY if the radio is already in state RX_PREPARED,
- * FAIL otherwise
- **/
- async command error_t prepare();
-
- /**
- * Signalled in response to a successful call to <tt>prepare()</tt>. This
- * event is completing the preparation of a receive operation, the radio is
- * now in the state RX_PREPARED. The actual receive operation will be
- * triggered through a call to <tt>receive()</tt>.
- **/
- async event void prepareDone();
-
- /**
- * Tells whether the radio is in state RX_PREPARED.
- * @return TRUE if the radio is in the state RX_PREPARED, FALSE otherwise
- */
- async command bool isPrepared();
-
- /**
- * Switches the radio to receive mode at time <tt>t0 + dt</tt>. If
- * <tt>t0</tt> is NULL, then the callee interprets <tt>t0</tt> as now.
- *
- * @param t0 Reference time for receive operation (NULL means now)
+ * @param t0 Reference time for receive operation
*
* @param dt A positive offset relative to <tt>t0</tt>.
*
- * @return SUCCESS if the the command was accepted and the radio will be
- * switched to receive mode; FAIL, if the radio is not in the state
- * RX_PREPARED
+ * @return SUCCESS if the command was accepted and only then the
+ * <tt>enableRxDone()</tt> event will be signalled; FAIL, if the command was
+ * not accepted, because the radio is currently not in the state RADIO_OFF.
*/
- async command error_t receive(ieee154_reftime_t *t0, uint32_t dt);
-
+ async command error_t enableRx(uint32_t t0, uint32_t dt);
+
+ /**
+ * Signalled in response to a successful call to <tt>enableRx()</tt>. This
+ * event is completing the <tt>enableRx()</tt> operation, the radio is now in
+ * the state RECEIVING. It will stay in receive mode until it is switched off
+ * through the <tt>RadioOff</tt> interface. Received frames will be signalled
+ * through the <tt>received()</tt> event.
+ **/
+ async event void enableRxDone();
+
/**
- * Tells whether the radio is in state RECEIVING.
+ * Tells whether the radio is in state RECEIVING, i.e. in receive
+ * mode.
+ *
* @return TRUE if the radio is in the state RECEIVING, FALSE otherwise
*/
async command bool isReceiving();
* A frame was received and passed the filters described in
* IEEE 802.15.4-2006 Sec. 7.5.6.2 ("Reception and rejection").
*
- * @param timestamp The point in time when the first bit of the PPDU
- * was received or NULL if timestamp is not available.
+ * @param timestamp The point in time when the first bit of the PPDU was
+ * received or NULL if a timestamp is not available. The timestamp's data
+ * type is platform-specific, you can use the
+ * <tt>IEEE154Frame.getTimestamp()</tt> command to get a platform-
+ * independent variant (uint32_t) of the timestamp. This pointer is only
+ * valid while the event is signalled and no reference must be kept to it
+ * afterwards.
*
* @param frame The received frame
*
* @return a buffer to be used by the driver for the next
* incoming frame
*/
- event message_t* received(message_t *frame, ieee154_reftime_t *timestamp);
+ event message_t* received(message_t *frame, const ieee154_timestamp_t *timestamp);
}
* ========================================================================
*/
#include "TKN154_MAC.h"
-#include "TKN154_PHY.h"
+#include "TKN154_platform.h"
interface RadioTx
{
-
- /**
- * Prepares the transmission of a frame. This command will fail, if the
- * radio is neither in state RADIO_OFF nor in state TX_LOADED. The actual
- * transmission will be triggered through a call to <tt>transmit()</tt>. Any
- * frame that was previously prepared for transmission ("loaded") will be
- * overwritten. The <tt>loadDone()</tt> event signals the completion of the
- * <tt>load()</tt> command.
- *
- * The frame will be loaded (and the radio will stay in the state
- * TX_LOADED) until either the transmission was successful, i.e.
- * <tt>transmitDone()</tt> was signalled with a status IEEE154_SUCCESS, or
- * the radio is switched off through the <tt>RadioOff</tt>
- * interface. Until then the callee might have to reserve certain resources
- * (e.g. the bus connected to the radio), so the caller should keep the time
- * while a frame is loaded as short as possible.
- *
- * @param frame The frame to transmit.
- *
- * @return SUCCESS if the command was accepted and <tt>loadDone()</tt> will
- * be signalled; FAIL otherwise
- **/
- async command error_t load(ieee154_txframe_t *frame);
-
- /**
- * Signalled in response to a successful call to <tt>load()</tt>. This
- * event is completing the preparation of a transmission, the radio is
- * now in the state TX_LOADED. The actual transmission is triggered
- * through a call to <tt>transmit()</tt>.
- **/
- async event void loadDone();
-
/**
- * If the radio is in state TX_LOADED then this commands returns the
- * the frame that was loaded last; it returns NULL otherwise.
+ * Transmits a frame at time <tt>t0 + dt</tt> or immediately if <tt>t0 +
+ * dt</tt> lies in the past. The frame is transmitted in any case (without
+ * prior CCA). Analogous to the <tt>Timer</tt> interface <tt>t0</tt> is
+ * interpreted as a time in the past. If <tt>t0</tt> is NULL or if
+ * <tt>dt</tt> is zero then the frame is transmitted immediately. This
+ * command will fail, if the radio is currently not in state RADIO_OFF.
*
- * @return last frame loaded if radio is in the state TX_LOADED,
- * NULL otherwise
- **/
- async command ieee154_txframe_t* getLoadedFrame();
-
- /**
- * Transmits the frame whose transmission has previously been prepared
- * through a call to <tt>load()</tt> at time <tt>t0+dt</tt> or immediately if
- * <tt>t0</tt> is NULL. In the first case the caller has to guarantee (through
- * platform-specific guard times and by calling <tt>transmit</tt> in an
- * atomic block) that the callee can start the transmission on time.
- * The frame is transmitted without carrier sense (without CCA).
- * The <tt>transmitDone()</tt> event will signal the result
- * of the transmission.
+ * Iff the ACK_REQUESTED flag is set in the frame's header a successful
+ * transmission will include an acknowledgement from the destination; then,
+ * the callee will perform the necessary steps for receiving this
+ * acknowledgement following the specification in IEEE 802.15.4-2006 Sect.
+ * 7.5.6.4.
*
- * @param t0 Reference time for transmission (NULL means now)
- * @param dt A positive offset relative to <tt>t0</tt>.
+ * @param frame The frame to transmit
*
- * @return SUCCESS if the transmission was triggered successfully and only
- * then <tt>transmitDone()</tt> will be signalled; FAIL, if the transmission
- * was not triggered because no frame was loaded.
- */
- async command error_t transmit(ieee154_reftime_t *t0, uint32_t dt);
-
- /**
- * Signalled in response to a call to <tt>transmit()</tt> and completing the transmission. Depending on the
- * <tt>error</tt> parameter the radio is now in the state RADIO_OFF
- * (<tt>error == IEEE154_SUCCESS</tt>) or back in state TX_LOADED
- * (<tt>error != IEEE154_SUCCESS</tt>).
+ * @param t0 Reference time for transmission, NULL means frame will be
+ * transmitted immediately
*
- * @param frame The frame that was transmitted.
- * @param txTime The time of transmission of the first symbol of the PPDU or NULL if the transmission failed.
- */
- async event void transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime);
-
-
- /**
- * Transmits the frame whose transmission has previously been prepared
- * through a call to <tt>load()</tt> using the unslotted CSMA-CA
- * algorithm as specified in the IEEE 802.15.4-2006 standard Sect. 7.5.1.4. The initial
- * CSMA-CA parameters are passed as a parameter, the algorithm should start immediately.
- * The <tt>transmitUnslottedCsmaCaDone()</tt> event will signal the result
- * of the transmission.
- * A successful transmission may include an acknowledgement from the
- * destination if the ACK_REQUESTED flag is set in the loaded frame's header; then,
- * the callee also has to perform the necessary steps for receiving the
- * acknowledgement (switching the radio to Rx mode immediately after
- * transmission, etc., as specified in IEEE 802.15.4-2006 Sect. 7.5.6.4).
+ * @param dt A positive offset relative to <tt>t0</tt>, ignored
+ * if <tt>t0</tt> is NULL
*
- * @param csmaParameters parameters for the unslotted CSMA-CA algorithm.
- *
- * @return SUCCESS if the unslotted CSMA-CA was triggered successfully,
- * FAIL otherwise.
+ * @return SUCCESS if the transmission was triggered successfully and only
+ * then <tt>transmitDone()</tt> will be signalled; FAIL, if the command was
+ * not accepted, because the radio is currently not in the state RADIO_OFF;
+ * EINVAL if <tt>frame</tt> or a pointer therein is invalid, or the length
+ * of the frame is invalid
*/
- async command error_t transmitUnslottedCsmaCa(ieee154_csma_t *csmaParameters);
+ async command error_t transmit(ieee154_txframe_t *frame, const ieee154_timestamp_t *t0, uint32_t dt);
/**
- * Signalled in response to a call to <tt>transmitUnslottedCsmaCa()</tt>.
- * Depending on the
- * <tt>error</tt> parameter the radio is now in the state RADIO_OFF
- * (<tt>error == IEEE154_SUCCESS</tt>) or still in state TX_LOADED
- * (<tt>error != IEEE154_SUCCESS</tt>). If the transmission succeeded then
- * the time of the transmission -- the point in time when the first symbol of the
- * PPDU was transmitted -- will be stored in the metadata field of the frame.
+ * Signalled in response to a call to <tt>transmit()</tt> and completing
+ * the transmission of a frame. The radio is now back in state RADIO_OFF.
+ * The time of the transmission -- the point in time when the first bit of the
+ * PPDU was transmitted -- is given by <tt>timestamp</tt>. Since the
+ * frame was transmitted without CCA the transmission can only have
+ * failed if no acknowledgement was received although one was requested.
*
* @param frame The frame that was transmitted.
- * @param csmaParameters csmaParameters parameters for the unslotted CSMA-CA algorithm
- * @param ackPendingFlag TRUE if an acknowledgement was received and the
- * "pending" flag is set in the header of the ACK frame, FALSE otherwise
- * @param result SUCCESS if the the frame was transmitted (and a matching
- * acknowledgement was received, if requested); FAIL if the CSMA-CA algorithm failed
- * because NB > macMaxCsmaBackoffs.
- *
- * unslotted CSMA-CA was triggered successfully,
- * FAIL otherwiseThe time of transmission or NULL if the transmission failed.
- */
- async event void transmitUnslottedCsmaCaDone(ieee154_txframe_t *frame,
- bool ackPendingFlag, ieee154_csma_t *csmaParameters, error_t result);
-
-
- /**
- * Transmits the frame whose transmission has previously been prepared
- * through a call to <tt>load()</tt> using the slotted CSMA-CA
- * algorithm as specified in the IEEE 802.15.4-2006 standard Sect. 7.5.1.4. The initial
- * CSMA-CA parameters are passed as a parameter, the algorithm should start immediately,
- * but the frame transmission should start no later than <tt>slot0Time+dtMax</tt>. The backoff slot boundaries
- * are defined relative to <tt>slot0Time</tt>, if the <tt>resume</tt>
- * then the initial backoff (in symbols) is passed as the <tt>initialBackoff</tt> parameter.
*
- * The <tt>transmitSlottedCsmaCaDone()</tt> event will signal the result
- * of the transmission.
- * A successful transmission may include an acknowledgement from the
- * destination if the ACK_REQUESTED flag is set in the loaded frame's header; then,
- * the callee also has to perform the necessary steps for receiving the
- * acknowledgement (switching the radio to Rx mode immediately after
- * transmission, etc., as specified in IEEE 802.15.4-2006 Sect. 7.5.6.4).
- *
- * @param slot0Time Reference time (last beacon)
- * @param dtMax <tt>slot0Time+dtMax</tt> is the last time the frame may be transmitted.
- * @param resume TRUE means that the initial backoff is defined by the
- * <tt>initialBackoff</tt> parameter, FALSE means the <tt>initialBackoff</tt>
- * should be ignored.
- * @param initialBackoff initial backoff.
- * @param csmaParameters parameters for the slotted CSMA-CA algorithm.
- *
- * @return SUCCESS if the slotted CSMA-CA was triggered successfully,
- * FAIL otherwise.
- */
- async command error_t transmitSlottedCsmaCa(ieee154_reftime_t *slot0Time, uint32_t dtMax,
- bool resume, uint16_t initialBackoff, ieee154_csma_t *csmaParameters);
-
- /**
- * Signalled in response to a call to <tt>transmitSlottedCsmaCa()</tt>.
- * Depending on the
- * <tt>error</tt> parameter the radio is now in the state RADIO_OFF
- * (<tt>error == IEEE154_SUCCESS</tt>) or still in state TX_LOADED
- * (<tt>error != IEEE154_SUCCESS</tt>). If the transmission succeeded then
- * the time of the transmission -- the point in time when the first symbol of the
- * PPDU was transmitted -- will be stored in the metadata field of the frame.
- * It will also passed (possibly with higher precision) through the
- * <tt>txTime</tt> parameter.
- *
- * @param frame The frame that was transmitted.
- * @param txTime The time of transmission of the first symbol of the PPDU or NULL if the transmission failed.
- * @param ackPendingFlag TRUE if an acknowledgement was received and the
- * "pending" flag is set in the header of the ACK frame, FALSE otherwise
- * @param remainingBackoff only valid if <tt>error == ERETRY</tt>, i.e.
- * when the frame could not be transmitted because transmission would have
- * started later than <tt>slot0Time+dtMax</tt>; then it
- * specifies the remaining offset (in symbols) relative to <tt>slot0Time+dtMax</tt>,
- * when the frame would have been transmitted
- * @param csmaParameters csmaParameters parameters for the unslotted CSMA-CA algorithm
+ * @param timestamp The point in time when the first bit of the PPDU
+ * was received or NULL if a timestamp is not available. The
+ * timestamp's data type is platform-specific, you can use the
+ * <tt>IEEE154Frame.getTimestamp()</tt> command to get a platform-
+ * independent variant (uint32_t) of the timestamp. This pointer
+ * is only valid while the event is signalled and no reference must
+ * be kept to it afterwards.
*
- * @result result SUCCESS if the the frame was transmitted (and a matching
- * acknowledgement was received, if requested); FAIL if the CSMA-CA algorithm failed
- * because NB > macMaxCsmaBackoffs; ERETRY if the frame could not be transmitted because transmission would have
- * started later than <tt>slot0Time+dtMax</tt>
- */
- async event void transmitSlottedCsmaCaDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime,
- bool ackPendingFlag, uint16_t remainingBackoff, ieee154_csma_t *csmaParameters, error_t result);
+ * @param result SUCCESS if the frame was transmitted (and a matching
+ * acknowledgement was received, if requested); ENOACK if the frame was
+ * transmitted, but no matching acknowledgement was received although one
+ * was requested
+ **/
+ async event void transmitDone(ieee154_txframe_t *frame, const ieee154_timestamp_t *timestamp, error_t result);
}
--- /dev/null
+/*
+ * Copyright (c) 2008, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+#include "TKN154_MAC.h"
+#include "TKN154_PHY.h"
+
+interface SlottedCsmaCa
+{
+ /**
+ * Transmits a frame using the slotted CSMA-CA algorithm as specified in IEEE
+ * 802.15.4-2006 standard Sect. 7.5.1.4. This command will fail if the
+ * current state of the radio is not RADIO_OFF. The initial CSMA-CA
+ * parameters are passed as a parameter and may be modified by the callee.
+ * The caller must not access <tt>csma</tt> until the <tt>transmitDone</tt>
+ * event has been signalled.
+ *
+ * <tt>slot0Time</tt> defines the beginning of the first slot in the CAP.
+ * Any transmission must commence on a backoff slot boundary relative to
+ * <tt>slot0Time</tt>. The last possible time for transmission is defined by
+ * <tt>slot0Time+dtMax</tt>. If the transmission cannot commence at or before
+ * <tt>slot0Time+dtMax</tt> then an event <tt>transmitDone()</tt> with error
+ * code ERETRY will be signalled and <tt>csma</tt> will reflect the current
+ * state of the CSMA-CA algorithm. The caller can then resume the
+ * transmission of this frame in the next CAP based on the
+ * <tt>remainingBackoff</tt> passed in the <tt>transmitDone()</tt> event, by
+ * setting <tt>resume</tt> to TRUE in the <tt>transmit()</tt> call.
+ *
+ * Iff the ACK_REQUESTED flag is set in the frame's header a successful
+ * transmission will include an acknowledgement from the destination; then,
+ * the callee will perform the necessary steps for receiving this
+ * acknowledgement following the specification in IEEE 802.15.4-2006 Sect.
+ * 7.5.6.4.
+ *
+ * @param frame The frame to transmit.
+ *
+ * @param csma Initial parameters for the slotted CSMA-CA algorithm.
+ *
+ * @param slot0Time Reference time for the backoff slot boundaries
+ *
+ * @param dtMax <tt>slot0Time+dtMax</tt> is the last time the frame may be
+ * transmitted.
+ *
+ * @param resume TRUE means that the initial backoff is defined by the
+ * <tt>remainingBackoff</tt> parameter, FALSE means the
+ * <tt>remainingBackoff</tt> is to be ignored.
+ *
+ * @param remainingBackoff initial backoff (ignored if <tt>resume</tt>
+ * is FALSE.
+ *
+ * @return SUCCESS if the slotted CSMA-CA was triggered successfully;
+ * EINVAL if <tt>frame</tt> or a pointer therein is invalid; FAIL otherwise.
+ */
+ async command error_t transmit(ieee154_txframe_t *frame, ieee154_csma_t *csma,
+ const ieee154_timestamp_t *slot0Time, uint32_t dtMax, bool resume, uint16_t remainingBackoff);
+
+ /**
+ * Signalled in response to a call to <tt>transmit()</tt>. This event
+ * completes the <tt>transmit</tt> operation. A transmission failed if either
+ * the channel was never idle during any of the <tt>macMaxCsmaBackoffs+1</tt>
+ * transmission attempts, if no acknowledgement was received although one was
+ * requested or if the frame could not be transmitted before the specified
+ * deadline (<tt>slot0Time+dtMax</tt>).
+ *
+ * @param frame The frame that was to be transmitted.
+ *
+ * @param csma Parameters for the slotted CSMA-CA algorithm; this pointer is
+ * identical to the one passed to the <tt>transmit</tt> command, the content,
+ * however, may have changed.
+ *
+ * @param ackPendingFlag TRUE if an acknowledgement was received and the
+ * "pending" flag is set in the header of the ACK frame, FALSE otherwise
+ * (this is typically only relevant for indirect transmissions)
+ *
+ * @param remainingBackoff Only valid if <tt>result = ERETRY</tt>, and
+ * then it describes the remaining backoff time (in symbols) to be used
+ * for the transmission of the frame in the following CAP.
+ *
+ * @result result SUCCESS if the the frame was transmitted (and a matching
+ * acknowledgement was received, if requested); FAIL if the CSMA-CA algorithm
+ * failed because NB > macMaxCsmaBackoffs; ERETRY if the frame could not be
+ * transmitted because transmission would have started later than
+ * <tt>slot0Time+dtMax</tt>
+ */
+ async event void transmitDone(ieee154_txframe_t *frame, ieee154_csma_t *csma,
+ bool ackPendingFlag, uint16_t remainingBackoff, error_t result);
+}
--- /dev/null
+/*
+ * Copyright (c) 2008, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer. - Redistributions in
+ * binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution. - Neither the name of the
+ * Technische Universitaet Berlin nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+ /* A superframe is bounded by beacons and divided into 16 equally-sized slots,
+ * which are part of CAP, CFP (GTS) or the inactive period. This interface
+ * can be used to determine the various parameters of a superframe,
+ * for example the begin of an inactive period would be calculated as
+ * "sfStartTime + (numCapSlot + numGtsSlots) * sfSlotDuration"
+ **/
+
+interface SuperframeStructure
+{
+ /**
+ * Returns the absolute time (in symbols) when the superframe started,
+ * i.e. the timestamp of the beacon marking the first slot.
+ *
+ * @returns superframe start time
+ **/
+ async command uint32_t sfStartTime();
+
+ /**
+ * Duration (in symbols) of a single superframe slot.
+ * Zero means, the CAP is not valid (no valid beacon was received).
+ *
+ * @returns superframe slot duration
+ **/
+ async command uint16_t sfSlotDuration();
+
+ /**
+ * Number of CAP slots.
+ *
+ * @returns number of CAP slots
+ **/
+ async command uint8_t numCapSlots();
+
+ /**
+ * Number of CAP slots (following the last CAP slot).
+ *
+ * @returns number of CAP slots
+ **/
+ async command uint8_t numGtsSlots();
+
+ /**
+ * Duration of the battery life extension period (in symbols),
+ * Zero means battery life extension is not used (disabled).
+ *
+ * @returns duration of the battery life extension period,
+ * zero means battery life extension is disabled
+ **/
+ async command uint16_t battLifeExtDuration();
+
+ /**
+ * Returns a pointer to the content of the GTS fields of the
+ * last received/transmitted beacon.
+ *
+ * @returns GTS fields
+ **/
+ async command const uint8_t* gtsFields();
+
+ /**
+ * The last "guardTime" symbols of CAP/CFP should not be used,
+ * i.e. transmission/reception should stop "guardTime" symbols
+ * before the actual end of the CAP/CFP.
+ *
+ * @returns guard time
+ **/
+ async command uint16_t guardTime();
+
+ /**
+ * Platform-specific representation of "sfStartTime" marking
+ * the reception/tranmission time of a beacon.
+ *
+ * @returns reception/tranmission time of the beacon
+ **/
+ async command const ieee154_timestamp_t* sfStartTimeRef();
+
+ /**
+ * Tells whether the frame pending bit is set in the header
+ * of the beacon frame.
+ *
+ * @returns TRUE is frame pending bit in beacon header is set, FALSE otherwise
+ **/
+ async command bool isBroadcastPending();
+}
--- /dev/null
+/*
+ * Copyright (c) 2008, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+#include "TKN154_MAC.h"
+#include "TKN154_platform.h"
+
+interface UnslottedCsmaCa
+{
+ /**
+ * Transmits a frame using the unslotted CSMA-CA algorithm as specified in
+ * IEEE 802.15.4-2006 standard Sect. 7.5.1.4. This command will fail if the
+ * current state of the radio is not RADIO_OFF. The initial CSMA-CA parameters
+ * are passed as a parameter and may be modified by the callee. The caller
+ * must not access <tt>csma</tt> until the <tt>transmitDone</tt> event
+ * has been signalled.
+ *
+ * Iff the ACK_REQUESTED flag is set in the frame's header a successful
+ * transmission will include an acknowledgement from the destination;
+ * then, the callee will perform the necessary steps for receiving this
+ * acknowledgement following the specification in IEEE 802.15.4-2006
+ * Sect. 7.5.6.4.
+ *
+ * @param frame The frame to transmit.
+ *
+ * @param csma Parameters for the unslotted CSMA-CA algorithm.
+ *
+ * @return SUCCESS if the unslotted CSMA-CA algorithm was triggered
+ * successfully; EINVAL if <tt>frame</tt> or a pointer therein is invalid;
+ * FAIL if the radio is not in state RADIO_OFF.
+ */
+ async command error_t transmit(ieee154_txframe_t *frame, ieee154_csma_t *csma);
+
+ /**
+ * Signalled in response to a call to <tt>transmit()</tt>. This event completes
+ * the <tt>transmit</tt> operation. If the transmission succeeded then
+ * the time of the transmission -- the point in time when the first bit of the
+ * PPDU was transmitted -- will be stored in the metadata field of the frame.
+ * A transmission failed if either all CCA operation(s) failed (including
+ * backoffs, i.e. NB > macMaxCsmaBackoffs) or if no acknowledgement was received
+ * although one was requested.
+ *
+ * @param frame The frame that was to be transmitted.
+ *
+ * @param csma Parameters for the unslotted CSMA-CA algorithm; this
+ * pointer is identical to the one passed to the <tt>transmit</tt> command,
+ * the content, however, may have changed.
+ *
+ * @param ackPendingFlag TRUE if an acknowledgement was received and the
+ * "pending" flag is set in the header of the ACK frame, FALSE otherwise
+ * (this is typically only relevant for indirect transmissions)
+ *
+ * @param result SUCCESS if the frame was transmitted (and a matching
+ * acknowledgement was received, if requested); ENOACK if the frame was
+ * transmitted, but no matching acknowledgement was received, although one
+ * was requested; FAIL if the CSMA-CA algorithm failed because
+ * NB > macMaxCsmaBackoffs.
+ */
+ async event void transmitDone(ieee154_txframe_t *frame, ieee154_csma_t *csma, bool ackPendingFlag, error_t result);
+}
* ========================================================================
*/
+/**
+ * The IEEE154BeaconFrame interface allows to access the content of a beacon
+ * frame.
+ */
#include <TKN154.h>
* ========================================================================
*/
+/**
+ * The IEEE154Frame interface allows to access the content of a IEEE 802.15.4
+ * frame.
+ */
#include <TKN154.h>
#include <message.h>
/**
* Returns the point in time when the frame was received. If
- * <tt>isTimestampValid()<\tt> returns FALSE then the
+ * <tt>isTimestampValid()</tt> returns FALSE then the
* timestamp is not valid and must be ignored.
*
* @param frame the frame
* Returns the type of the frame
* BEACON=0, DATA=1, ACK=2, COMMAND=3.
*
- * Note: For beacon frames one can use the <tt>IEEE154BeaconFrame<\tt>
+ * Note: For beacon frames one can use the <tt>IEEE154BeaconFrame</tt>
* interface to inspect additional fields of the frame.
*
* @param frame the frame
* ========================================================================
*/
+/**
+ * The IEEE154TxBeaconPayload interface allows to access the payload portion of
+ * the beacon frame that is periodically transmitted by a coordinator in a
+ * beacon-enabled PAN. This interface replaces the MLME-SET command for the PIB
+ * attribute values 0x45 (macBeaconPayload) and 0x46 (macBeaconPayloadLength).
+ */
#include <TKN154.h>
* Sets the beacon payload portion for all subsequently transmitted beacons.
* This command replaces the MLME-SET command for the PIB attribute values
* 0x45 (macBeaconPayload) and 0x46 (macBeaconPayloadLength). The
- * <tt>setBeaconPayloadDone()<\tt> event will be signalled when the
- * beacon payload has been set -- until then <tt>beaconPayload<\tt> must
+ * <tt>setBeaconPayloadDone()</tt> event will be signalled when the
+ * beacon payload has been set -- until then <tt>beaconPayload</tt> must
* not be modified.
*
* @param beaconPayload the new beacon payload
* @param length the length of the new beacon payload (in byte)
*
* @return EBUSY if another transaction is pending, ESIZE if length is too big,
- * SUCCESS otherwise (and only then the <tt>setBeaconPayloadDone<\tt> event
+ * SUCCESS otherwise (and only then the <tt>setBeaconPayloadDone</tt> event
* will be signalled)
*/
command error_t setBeaconPayload(void *beaconPayload, uint8_t length);
/**
- * Signalled in response to a <tt>setBeaconPayload()<\tt> request.
+ * Signalled in response to a <tt>setBeaconPayload()</tt> request.
* Indicates that the beacon payload has been copied and returns the
* ownership of the buffer to the next higher layer.
*
- * @param beaconPayload the <tt>beaconPayload<\tt> passed in the
- * <tt>setBeaconPayload()<\tt> command
- * @param length the <tt>length<\tt> passed in the
- * <tt>setBeaconPayload()<\tt> command
+ * @param beaconPayload the <tt>beaconPayload</tt> passed in the
+ * <tt>setBeaconPayload()</tt> command
+ * @param length the <tt>length</tt> passed in the
+ * <tt>setBeaconPayload()</tt> command
*/
event void setBeaconPayloadDone(void *beaconPayload, uint8_t length);
/**
- * Returns a pointer to the current beacon payload.
+ * Returns a pointer to the current beacon payload.
*
* @return the current beacon payload
*/
/**
* Replaces (overwrites) a portion of the current beacon payload. Whenever
* possible, to minimize overhead, the next higher layer should prefer this
- * command over the <tt>setBeaconPayload()<\tt> command. The
- * <tt>modifyBeaconPayloadDone()<\tt> event will be signalled when the
- * beacon payload has been updated -- until then <tt>buffer<\tt> must
- * not be modified.
+ * command over the <tt>setBeaconPayload()</tt> command. The
+ * <tt>modifyBeaconPayloadDone()</tt> event will be signalled when the beacon
+ * payload has been updated -- until then <tt>buffer</tt> must not be
+ * modified.
*
* @param offset offset into the current beacon payload
* @param buffer the buffer to be written
* @param length the length of the buffer
*
- * @return EBUSY if another transaction is pending, ESIZE if offset+length is too big,
- * SUCCESS otherwise (and only then the <tt>modifyBeaconPayloadDone<\tt> event
- * will be signalled)
+ * @return EBUSY if another transaction is pending, ESIZE if offset+length is
+ * too big, SUCCESS otherwise (and only then the
+ * <tt>modifyBeaconPayloadDone</tt> event will be signalled)
*/
command error_t modifyBeaconPayload(uint8_t offset, void *buffer, uint8_t bufferLength);
/**
- * Signalled in response to a <tt>modifyBeaconPayload()<\tt> request.
+ * Signalled in response to a <tt>modifyBeaconPayload()</tt> request.
* Indicates that the beacon payload has been updated.
*
- * @param offset the <tt>offset<\tt> passed in the
- * <tt>modifyBeaconPayload()<\tt> command
- * @param buffer the <tt>buffer<\tt> passed in the
- * <tt>modifyBeaconPayload()<\tt> command
- * @param bufferLength the <tt>bufferLength<\tt> passed in the
- * <tt>modifyBeaconPayload()<\tt> command
+ * @param offset the <tt>offset</tt> passed in the
+ * <tt>modifyBeaconPayload()</tt> command
+ * @param buffer the <tt>buffer</tt> passed in the
+ * <tt>modifyBeaconPayload()</tt> command
+ * @param bufferLength the <tt>bufferLength</tt> passed in the
+ * <tt>modifyBeaconPayload()</tt> command
*/
event void modifyBeaconPayloadDone(uint8_t offset, void *buffer, uint8_t bufferLength);
* time to update the beacon payload (if desired).
*
* The usual policy is that (1) this event is signalled before every beacon
- * transmission, and (2) that a subsequent call to <tt>setPayload<\tt>
- * will update the beacon payload portion of this beacon. However,
+ * transmission, and (2) that a subsequent call to <tt>setPayload</tt>
+ * will still update the beacon payload portion of this beacon. However,
* because of tight timing constraints in beacon-enabled mode neither can be
* guaranteed!
*/
/**
* Indicates that a beacon frame has been transmitted (the
- * <tt>getBeaconPayload<\tt> command can be used to inspect the
+ * <tt>getBeaconPayload</tt> command can be used to inspect the
* beacon payload).
*/
event void beaconTransmitted();
--- /dev/null
+/*
+ * Copyright (c) 2008, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author: Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+#include "TKN154.h"
+#include "TKN154_DEBUG.h"
+configuration Ieee802154BeaconEnabledC
+{
+ provides
+ {
+ // MCPS-SAP
+ interface MCPS_DATA;
+ interface MCPS_PURGE;
+
+ // MLME-SAP
+ interface MLME_ASSOCIATE;
+ interface MLME_BEACON_NOTIFY;
+ interface MLME_COMM_STATUS;
+ interface MLME_DISASSOCIATE;
+ interface MLME_GET;
+/* interface MLME_GTS;*/
+ interface MLME_ORPHAN;
+ interface MLME_POLL;
+ interface MLME_RESET;
+ interface MLME_RX_ENABLE;
+ interface MLME_SCAN;
+ interface MLME_SET;
+ interface MLME_START;
+ interface MLME_SYNC;
+ interface MLME_SYNC_LOSS;
+ interface IEEE154Frame;
+ interface IEEE154BeaconFrame;
+ interface IEEE154TxBeaconPayload;
+ interface SplitControl as PromiscuousMode;
+ interface Get<uint64_t> as LocalExtendedAddress;
+ interface Timestamp;
+ interface Packet;
+ }
+}
+implementation
+{
+ components TKN154BeaconEnabledP as MAC;
+
+ MLME_START = MAC;
+ MLME_GET = MAC;
+ MLME_SET = MAC;
+ MLME_RESET = MAC;
+ MLME_SYNC = MAC;
+ MLME_SYNC_LOSS = MAC;
+ MLME_BEACON_NOTIFY = MAC;
+ MLME_SCAN = MAC;
+ MCPS_DATA = MAC;
+ MCPS_PURGE = MAC;
+ MLME_ASSOCIATE = MAC;
+ MLME_DISASSOCIATE = MAC;
+ MLME_COMM_STATUS = MAC;
+ MLME_RX_ENABLE = MAC;
+ MLME_POLL = MAC;
+ MLME_ORPHAN = MAC;
+ IEEE154Frame = MAC;
+ IEEE154BeaconFrame = MAC;
+ LocalExtendedAddress = MAC;
+ IEEE154TxBeaconPayload = MAC;
+ PromiscuousMode = MAC;
+ Packet = MAC;
+
+ components CC2420TKN154C as PHY,
+ new Alarm62500hz32C() as PHYAlarm1,
+ new Alarm62500hz32VirtualizedC() as PHYAlarm2,
+ new Alarm62500hz32C() as TKN154TimingPAlarm,
+ LocalTime62500hzC, TKN154TimingP;
+
+ // wire PHY to the PIB
+ PHY.PIBUpdate[IEEE154_macShortAddress] -> MAC.PIBUpdate[IEEE154_macShortAddress];
+ PHY.PIBUpdate[IEEE154_macPANId] -> MAC.PIBUpdate[IEEE154_macPANId];
+ PHY.PIBUpdate[IEEE154_phyCurrentChannel] -> MAC.PIBUpdate[IEEE154_phyCurrentChannel];
+ PHY.PIBUpdate[IEEE154_phyTransmitPower] -> MAC.PIBUpdate[IEEE154_phyTransmitPower];
+ PHY.PIBUpdate[IEEE154_phyCCAMode] -> MAC.PIBUpdate[IEEE154_phyCCAMode];
+ PHY.PIBUpdate[IEEE154_macPanCoordinator] -> MAC.PIBUpdate[IEEE154_macPanCoordinator];
+
+ Timestamp = PHY;
+ PHY.Alarm1 -> PHYAlarm1;
+ PHY.Alarm2 -> PHYAlarm2;
+ PHY.LocalTime -> LocalTime62500hzC;
+ PHY.CaptureTime -> TKN154TimingP;
+ PHY.ReliableWait -> TKN154TimingP;
+ PHY.ReferenceTime -> TKN154TimingP;
+ PHY.TimeCalc -> MAC;
+ TKN154TimingP.TimeCalc -> MAC;
+ TKN154TimingP.Leds -> LedsC;
+ TKN154TimingP.CCA -> PHY;
+ TKN154TimingP.SymbolAlarm -> TKN154TimingPAlarm;
+
+ components new Alarm62500hz32VirtualizedC() as MACAlarm1,
+ new Alarm62500hz32VirtualizedC() as MACAlarm2,
+ new Alarm62500hz32VirtualizedC() as MACAlarm3,
+ new Alarm62500hz32VirtualizedC() as MACAlarm4,
+ new Alarm62500hz32VirtualizedC() as MACAlarm5,
+ new Alarm62500hz32VirtualizedC() as MACAlarm6,
+ new Alarm62500hz32VirtualizedC() as MACAlarm7,
+ new Alarm62500hz32VirtualizedC() as MACAlarm8,
+ new Alarm62500hz32VirtualizedC() as MACAlarm9,
+
+ new Timer62500C() as MACTimer1,
+ new Timer62500C() as MACTimer2,
+ new Timer62500C() as MACTimer3,
+ new Timer62500C() as MACTimer4,
+ new Timer62500C() as MACTimer5;
+
+ MAC.Alarm1 -> MACAlarm1;
+ MAC.Alarm2 -> MACAlarm2;
+ MAC.Alarm3 -> MACAlarm3;
+ MAC.Alarm4 -> MACAlarm4;
+ MAC.Alarm5 -> MACAlarm5;
+ MAC.Alarm6 -> MACAlarm6;
+ MAC.Alarm7 -> MACAlarm7;
+ MAC.Alarm8 -> MACAlarm8;
+ MAC.Alarm9 -> MACAlarm9;
+
+ MAC.Timer1 -> MACTimer1;
+ MAC.Timer2 -> MACTimer2;
+ MAC.Timer3 -> MACTimer3;
+ MAC.Timer4 -> MACTimer4;
+ MAC.Timer5 -> MACTimer5;
+ MAC.LocalTime -> LocalTime62500hzC;
+
+ // wire MAC <-> PHY
+ MAC.RadioTx -> PHY;
+ MAC.SlottedCsmaCa -> PHY;
+ MAC.RadioRx -> PHY;
+ MAC.RadioOff -> PHY;
+ MAC.EnergyDetection -> PHY;
+ MAC.PhySplitControl -> PHY;
+ MAC.RadioPromiscuousMode -> PHY.RadioPromiscuousMode;
+ PHY.FrameUtility -> MAC;
+
+ components RandomC, LedsC, NoLedsC;
+ MAC.Random -> RandomC;
+ MAC.Leds -> LedsC;
+ PHY.Random -> RandomC;
+
+#ifdef TKN154_DEBUG
+ components DebugC;
+#endif
+}
--- /dev/null
+/*
+ * Copyright (c) 2008, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author: Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+#include "TKN154.h"
+#include "TKN154_DEBUG.h"
+configuration Ieee802154NonBeaconEnabledC
+{
+ provides
+ {
+ // MCPS-SAP
+ interface MCPS_DATA;
+ interface MCPS_PURGE;
+
+ // MLME-SAP
+ interface MLME_ASSOCIATE;
+ interface MLME_BEACON_NOTIFY;
+ interface MLME_COMM_STATUS;
+ interface MLME_DISASSOCIATE;
+ interface MLME_GET;
+ interface MLME_ORPHAN;
+ interface MLME_POLL;
+ interface MLME_RESET;
+ interface MLME_RX_ENABLE;
+ interface MLME_SCAN;
+ interface MLME_SET;
+ interface MLME_START;
+ interface IEEE154Frame;
+ interface IEEE154BeaconFrame;
+ interface SplitControl as PromiscuousMode;
+ interface Get<uint64_t> as LocalExtendedAddress;
+ interface Timestamp;
+ interface Packet;
+ }
+}
+implementation
+{
+ components TKN154NonBeaconEnabledP as MAC;
+
+ MLME_START = MAC;
+ MLME_GET = MAC;
+ MLME_SET = MAC;
+ MLME_RESET = MAC;
+ MLME_BEACON_NOTIFY = MAC;
+ MLME_SCAN = MAC;
+ MCPS_DATA = MAC;
+ MCPS_PURGE = MAC;
+ MLME_ASSOCIATE = MAC;
+ MLME_DISASSOCIATE = MAC;
+ MLME_COMM_STATUS = MAC;
+ MLME_RX_ENABLE = MAC;
+ MLME_POLL = MAC;
+ MLME_ORPHAN = MAC;
+ IEEE154Frame = MAC;
+ IEEE154BeaconFrame = MAC;
+ LocalExtendedAddress = MAC;
+ PromiscuousMode = MAC;
+ Packet = MAC;
+
+ components CC2420TKN154C as PHY,
+ new Alarm62500hz32C() as PHYAlarm1,
+ new Alarm62500hz32VirtualizedC() as PHYAlarm2,
+ new Alarm62500hz32C() as TKN154TimingPAlarm,
+ LocalTime62500hzC, TKN154TimingP;
+
+ // wire PHY to the PIB
+ PHY.PIBUpdate[IEEE154_macShortAddress] -> MAC.PIBUpdate[IEEE154_macShortAddress];
+ PHY.PIBUpdate[IEEE154_macPANId] -> MAC.PIBUpdate[IEEE154_macPANId];
+ PHY.PIBUpdate[IEEE154_phyCurrentChannel] -> MAC.PIBUpdate[IEEE154_phyCurrentChannel];
+ PHY.PIBUpdate[IEEE154_phyTransmitPower] -> MAC.PIBUpdate[IEEE154_phyTransmitPower];
+ PHY.PIBUpdate[IEEE154_phyCCAMode] -> MAC.PIBUpdate[IEEE154_phyCCAMode];
+ PHY.PIBUpdate[IEEE154_macPanCoordinator] -> MAC.PIBUpdate[IEEE154_macPanCoordinator];
+
+ Timestamp = PHY;
+ PHY.Alarm1 -> PHYAlarm1;
+ PHY.Alarm2 -> PHYAlarm2;
+ PHY.LocalTime -> LocalTime62500hzC;
+ PHY.CaptureTime -> TKN154TimingP;
+ PHY.ReliableWait -> TKN154TimingP;
+ PHY.ReferenceTime -> TKN154TimingP;
+ PHY.TimeCalc -> MAC;
+ TKN154TimingP.TimeCalc -> MAC;
+ TKN154TimingP.Leds -> LedsC;
+ TKN154TimingP.CCA -> PHY;
+ TKN154TimingP.SymbolAlarm -> TKN154TimingPAlarm;
+
+ components new Timer62500C() as MACTimer1,
+ new Timer62500C() as MACTimer2,
+ new Timer62500C() as MACTimer3,
+ new Timer62500C() as MACTimer4,
+ new Timer62500C() as MACTimer5;
+
+ MAC.Timer1 -> MACTimer1;
+ MAC.Timer2 -> MACTimer2;
+ MAC.Timer3 -> MACTimer3;
+ MAC.Timer4 -> MACTimer4;
+ MAC.Timer5 -> MACTimer5;
+ MAC.LocalTime -> LocalTime62500hzC;
+
+ // wire MAC <-> PHY
+ MAC.RadioTx -> PHY;
+ MAC.UnslottedCsmaCa -> PHY;
+ MAC.RadioRx -> PHY;
+ MAC.RadioOff -> PHY;
+ MAC.EnergyDetection -> PHY;
+ MAC.PhySplitControl -> PHY;
+ MAC.RadioPromiscuousMode -> PHY.RadioPromiscuousMode;
+ PHY.FrameUtility -> MAC;
+
+ components RandomC, LedsC, NoLedsC;
+ MAC.Random -> RandomC;
+ MAC.Leds -> LedsC;
+ PHY.Random -> RandomC;
+
+#ifdef TKN154_DEBUG
+ components DebugC;
+#endif
+}
/**
* In slotted CSMA-CA frames must be sent on backoff boundaries (slot width:
- * 320 us). The TelosB platform lacks a clock with sufficient precision/
- * accuracy, i.e. for slotted CSMA-CA the timing is *not* standard compliant.
+ * 320 us). The TelosB platform lacks a clock with sufficient precision and
+ * accuracy, i.e. for slotted CSMA-CA the timing is *not* standard compliant
+ * (this code is experimental)
*/
#include "TKN154_platform.h"
provides interface ReliableWait;
provides interface ReferenceTime;
uses interface TimeCalc;
+ uses interface GetNow<bool> as CCA;
uses interface Alarm<T62500hz,uint32_t> as SymbolAlarm;
uses interface Leds;
}
};
uint8_t m_state = S_WAIT_OFF;
- async command void CaptureTime.convert(uint16_t time, ieee154_reftime_t *localTime, int16_t offset)
+ async command error_t CaptureTime.convert(uint16_t time, ieee154_timestamp_t *localTime, int16_t offset)
{
// TimerB is used for capturing, it is sourced by ACLK (32768Hz),
- // we now need to convert the capture "time" into ieee154_reftime_t.
+ // we now need to convert the capture "time" into ieee154_timestamp_t.
// With the 32768Hz quartz we don't have enough precision anyway,
// so the code below generates a timestamp that is not accurate
- // (deviating about +-50 microseconds, which could probably
- // improved if we don't go through LocalTime)
uint16_t tbr1, tbr2, delta;
uint32_t now;
atomic {
delta = tbr1 - time;
else
delta = ~(time - tbr1) + 1;
- *localTime = now - delta*2 + offset;
+ *localTime = now - delta * 2 + offset; /* one tick of TimerB ~ two symbols */
+ return SUCCESS;
}
- async command void ReliableWait.busyWait(uint16_t dt)
+ async command bool ReliableWait.ccaOnBackoffBoundary(ieee154_timestamp_t *slot0)
{
- uint16_t tbr1, tbr2, tbrVal;
- atomic {
- do {
- tbr1 = TBR;
- tbr2 = TBR;
- } while (tbr1 != tbr2); // majority vote required (see msp430 manual)
- }
- tbrVal = tbr1 + dt;
- atomic {
- do {
- tbr1 = TBR;
- tbr2 = TBR;
- } while (tbr1 != tbr2 || tbr1 != tbrVal); // majority vote required (see msp430 manual)
- }
+ // There is no point in trying
+ return (call CCA.getNow() ? 20: 0);
+ }
+
+ async command bool CaptureTime.isValidTimestamp(uint16_t risingSFDTime, uint16_t fallingSFDTime)
+ {
+ // smallest packet (ACK) takes
+ // length field (1) + MPDU (5) = 6 byte => 12 * 16 us = 192 us
+ return (fallingSFDTime - risingSFDTime) > 5;
}
- async command void ReliableWait.waitRx(ieee154_reftime_t *t0, uint16_t dt)
+ async command void ReliableWait.waitRx(uint32_t t0, uint32_t dt)
{
if (m_state != S_WAIT_OFF){
- call Leds.led0On();
+ ASSERT(0);
return;
}
m_state = S_WAIT_RX;
- call SymbolAlarm.startAt(*t0 - 12, dt); // subtract 12 symbols required for Rx calibration
- //signal SymbolAlarm.fired();
+ call SymbolAlarm.startAt(t0 - 16, dt); // subtract 12 symbols required for Rx calibration
}
- async command void ReliableWait.waitTx(ieee154_reftime_t *t0, uint16_t dt)
+ async command void ReliableWait.waitTx(ieee154_timestamp_t *t0, uint32_t dt)
{
if (m_state != S_WAIT_OFF){
- call Leds.led0On();
+ ASSERT(0);
return;
}
m_state = S_WAIT_TX;
- call SymbolAlarm.startAt(*t0 - 12, dt); // subtract 12 symbols required for Tx calibration
+ call SymbolAlarm.startAt(*t0 - 16, dt); // subtract 12 symbols required for Tx calibration
}
- async command void ReliableWait.waitBackoff(ieee154_reftime_t *t0, uint16_t dt)
+ async command void ReliableWait.waitBackoff(uint32_t dt)
{
if (m_state != S_WAIT_OFF){
- call Leds.led0On();
+ ASSERT(0);
return;
}
m_state = S_WAIT_BACKOFF;
- call SymbolAlarm.startAt(*t0, dt);
- //signal SymbolAlarm.fired();
+ call SymbolAlarm.start(dt);
}
async event void SymbolAlarm.fired()
case S_WAIT_RX: m_state = S_WAIT_OFF; signal ReliableWait.waitRxDone(); break;
case S_WAIT_TX: m_state = S_WAIT_OFF; signal ReliableWait.waitTxDone(); break;
case S_WAIT_BACKOFF: m_state = S_WAIT_OFF; signal ReliableWait.waitBackoffDone(); break;
- default: call Leds.led0On(); break;
+ default: ASSERT(0); break;
}
}
- async command void ReliableWait.busyWaitSlotBoundaryCCA(ieee154_reftime_t *t0, uint16_t *dt) { }
- async command void ReliableWait.busyWaitSlotBoundaryTx(ieee154_reftime_t *t0, uint16_t dt)
- {
- // we cannot meet the timing constraints, but there should at least roughly
- // be 20 symbols between the first and the seconds CCA
- call ReliableWait.busyWait(20);
- }
-
- async command void ReferenceTime.getNow(ieee154_reftime_t* reftime, uint16_t dt)
+ async command void ReferenceTime.getNow(ieee154_timestamp_t* timestamp, uint16_t dt)
{
- *reftime = call SymbolAlarm.getNow() + dt;
+ *timestamp = call SymbolAlarm.getNow() + dt;
}
- async command uint32_t ReferenceTime.toLocalTime(ieee154_reftime_t* refTime)
+ async command uint32_t ReferenceTime.toLocalTime(const ieee154_timestamp_t* timestamp)
{
- return *refTime;
+ return *timestamp;
}
}
/****************************************************
* The following constants define guard times on Tmote Sky / TelosB.
- * All values are in symbol time (1 symbol = 16 us)
+ * All values are in symbol time (1 symbol = 16 us) and assume the
+ * default system configuration (MCLK running at 4.6 MHz)
*/
enum {
- // guard time to give up the token before actual end of CAP/CFP
- IEEE154_ACTIVE_PERIOD_GUARD_TIME = 300,
+ // the expected maximum time between calling a transmit() operation and
+ // the radio putting the first byte on the channel assuming no CSMA-CA
+ IEEE154_RADIO_TX_DELAY = 400,
- // the expected time for a RadioTx.prepare() operation to execute (return)
- IEEE154_RADIO_TX_PREPARE_DELAY = 220,
+ // the expected maximum time between calling a receive() operation and the
+ // the radio actually being put in receive mode
+ IEEE154_RADIO_RX_DELAY = 400,
- // the *guaranteed maximum* time between calling a RadioTx.transmit() and the
- // first PPDU bit being put onto the channel, assuming that RadioTx.transmit()
- // is called inside an atomic block
- IEEE154_RADIO_TX_SEND_DELAY = 100,
-
- // the expected time for a RadioRx.prepare() operation to execute (return)
- IEEE154_RADIO_RX_PREPARE_DELAY = 300,
-
- // the *guaranteed maximum* time between calling a RadioTx.transmit() and the
- // first PPDU bit being put onto the channel, assuming that RadioTx.transmit()
- // is called inside an atomic block
- IEEE154_RADIO_RX_DELAY = 100,
-
- // defines at what time the MAC payload for a beacon frame is assembled prior
- // to the next scheduled beacon transmission time; must be smaller than both
- // the beacon interval and IEEE154_RADIO_TX_PREPARE_DELAY
+ // defines at what time the MAC payload for a beacon frame is assembled before
+ // the next scheduled beacon transmission time; the value must be smaller than
+ // the beacon interval plus the time for preparing the Tx operation
BEACON_PAYLOAD_UPDATE_INTERVAL = 2500,
};
-typedef uint32_t ieee154_reftime_t;
+typedef uint32_t ieee154_timestamp_t;
#endif
#else
typedef struct {
uint8_t control; // stores length (lower 7 bits), top bit -> promiscuous mode
- uint8_t mhr[23];
+ uint8_t mhr[23]; // maximum header size without security
} ieee154_header_t;
typedef struct {
} ieee154_metadata_t;
#endif
-#ifdef TOSH_DATA_LENGTH
-#undef TOSH_DATA_LENGTH
-#endif
+//#ifdef TOSH_DATA_LENGTH
+//#undef TOSH_DATA_LENGTH
+//#endif
// TOSH_DATA_LENGTH may be smaller than 118, but then we'll
// not be able to receive/send all IEEE 802.15.4 packets
#define TOSH_DATA_LENGTH 118
}
implementation
{
-/**
- * TelosB lacks a clock with the precision and accuracy
- * required by the 802.15.4 standard (62500 Hz, 40 ppm).
- * As a workaround, we cast one tick of the 32768 Hz clock to
- * two 802.15.4 symbols, which introduces a small (5%) error.
- * Thus the channel access in particular in beacon-enabled PANs
- * (slotted CSMA-CA) is not be standard-compliant!
- */
-#warning "Warning: MAC timing is not standard compliant (the symbol clock is based on the 32768 Hz oscillator)!"
+
+ /**
+ * TelosB lacks a clock that satisfies the precision and accuracy
+ * requirements of the IEEE 802.15.4 standard (62500 Hz, +-40 ppm).
+ * As a workaround, we cast one tick of the 32768 Hz clock to two
+ * IEEE 802.15.4 symbols, which introduces a small (5%) error.
+ * As a consequence the timing of the beacon interval and slotted
+ * CSMA-CA algorithm is not standard-compliant anymore.
+ */
+
+#warning "Warning: MAC timing is not standard compliant!"
async command void Alarm.start[ uint8_t num ](uint32_t dt){ call AlarmFrom.start[num](dt >> 1);}
async command void Alarm.stop[ uint8_t num ](){ call AlarmFrom.stop[num]();}