From 280de4fedba9a7080138600e623cdadf22bf728a Mon Sep 17 00:00:00 2001 From: janhauer Date: Wed, 4 Mar 2009 18:30:50 +0000 Subject: [PATCH] - re-designed the radio driver interfaces, restructured/improved the CC2420 radio driver - 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 --- apps/tests/tkn154/Makefile.include | 6 + .../coordinator/TestAssociateAppC.nc | 20 +- .../TestAssociate/coordinator/TestCoordC.nc | 2 +- .../TestAssociate/device/TestAssociateAppC.nc | 24 +- .../TestAssociate/device/TestDeviceC.nc | 2 +- apps/tests/tkn154/TestData/app_profile.h | 1 + .../coordinator/TestCoordReceiverC.nc | 2 +- .../TestData/coordinator/TestDataAppC.nc | 18 +- apps/tests/tkn154/TestData/device/Makefile | 1 + .../tkn154/TestData/device/TestDataAppC.nc | 26 +- .../TestData/device/TestDeviceSenderC.nc | 16 +- .../coordinator/TestCoordSenderC.nc | 2 +- .../coordinator/TestIndirectAppC.nc | 18 +- .../device/TestDeviceReceiverC.nc | 8 +- .../TestIndirect/device/TestIndirectAppC.nc | 20 +- apps/tests/tkn154/TestPromiscuous/Makefile | 1 - .../TestPromiscuous/TestPromiscuousAppC.nc | 16 +- .../TestPromiscuous/TestPromiscuousC.nc | 2 +- .../TestStartSync/coordinator/TestCoordC.nc | 2 +- .../coordinator/TestStartSyncAppC.nc | 12 +- .../TestStartSync/device/TestDeviceC.nc | 9 +- .../TestStartSync/device/TestStartSyncAppC.nc | 18 +- tos/chips/cc2420_tkn154/CC2420ControlP.nc | 6 +- .../cc2420_tkn154/CC2420ControlTransmitC.nc | 5 +- tos/chips/cc2420_tkn154/CC2420Power.nc | 2 +- tos/chips/cc2420_tkn154/CC2420Receive.nc | 2 +- tos/chips/cc2420_tkn154/CC2420ReceiveC.nc | 2 - tos/chips/cc2420_tkn154/CC2420ReceiveP.nc | 34 +- tos/chips/cc2420_tkn154/CC2420Rx.nc | 2 +- tos/chips/cc2420_tkn154/CC2420TKN154C.nc | 10 +- tos/chips/cc2420_tkn154/CC2420TKN154P.nc | 872 +++++++++--------- tos/chips/cc2420_tkn154/CC2420TransmitP.nc | 23 +- tos/chips/cc2420_tkn154/CC2420Tx.nc | 2 +- tos/chips/cc2420_tkn154/CaptureTime.nc | 16 +- tos/chips/cc2420_tkn154/ReferenceTime.nc | 6 +- tos/chips/cc2420_tkn154/ReliableWait.nc | 11 +- tos/chips/cc2420_tkn154/Timestamp.nc | 2 +- tos/lib/mac/tkn154/AssociateP.nc | 51 +- tos/lib/mac/tkn154/BeaconSynchronizeP.nc | 514 ++++++----- tos/lib/mac/tkn154/BeaconTransmitP.nc | 592 ++++++------ tos/lib/mac/tkn154/CoordBroadcastP.nc | 18 +- tos/lib/mac/tkn154/CoordRealignmentP.nc | 27 +- tos/lib/mac/tkn154/DataP.nc | 30 +- .../private/Ieee802154Debug.nc => DebugC.nc} | 43 +- tos/lib/mac/tkn154/DebugP.nc | 147 +++ tos/lib/mac/tkn154/DisassociateP.nc | 34 +- tos/lib/mac/tkn154/FrameDispatchQueueP.nc | 18 +- tos/lib/mac/tkn154/IndirectTxP.nc | 48 +- tos/lib/mac/tkn154/PibP.nc | 275 +++--- tos/lib/mac/tkn154/PollP.nc | 50 +- tos/lib/mac/tkn154/PromiscuousModeP.nc | 108 +-- tos/lib/mac/tkn154/README.txt | 25 +- tos/lib/mac/tkn154/RadioClientC.nc | 7 +- tos/lib/mac/tkn154/RadioControlImplP.nc | 175 ++-- tos/lib/mac/tkn154/RadioControlP.nc | 10 +- tos/lib/mac/tkn154/RxEnableP.nc | 113 ++- tos/lib/mac/tkn154/ScanP.nc | 177 ++-- tos/lib/mac/tkn154/SimpleTransferArbiterP.nc | 2 +- ...eDispatchP.nc => SlottedFrameDispatchP.nc} | 600 ++++++------ .../{TKN154P.nc => TKN154BeaconEnabledP.nc} | 144 ++- tos/lib/mac/tkn154/TKN154NonBeaconEnabledP.nc | 341 +++++++ tos/lib/mac/tkn154/TKN154_DEBUG.h | 161 ---- tos/lib/mac/tkn154/TKN154_MAC.h | 74 +- tos/lib/mac/tkn154/TKN154_PIB.h | 17 +- tos/lib/mac/tkn154/TransferClientP.nc | 8 +- tos/lib/mac/tkn154/UnslottedFrameDispatchP.nc | 497 ++++++++++ tos/lib/mac/tkn154/dummies/NoAssociateP.nc | 8 +- .../tkn154/dummies/NoBeaconSynchronizeP.nc | 95 +- .../mac/tkn154/dummies/NoBeaconTransmitP.nc | 103 +-- .../mac/tkn154/dummies/NoCoordBroadcastP.nc | 3 + tos/lib/mac/tkn154/dummies/NoCoordCfpP.nc | 23 +- .../mac/tkn154/dummies/NoCoordRealignmentP.nc | 2 + tos/lib/mac/tkn154/dummies/NoDebugP.nc | 54 -- tos/lib/mac/tkn154/dummies/NoDeviceCfpP.nc | 22 +- tos/lib/mac/tkn154/dummies/NoDisassociateP.nc | 8 +- .../tkn154/dummies/NoFrameDispatchQueueP.nc | 3 + .../mac/tkn154/dummies/NoPromiscuousModeP.nc | 7 +- tos/lib/mac/tkn154/dummies/NoRxEnableP.nc | 12 +- tos/lib/mac/tkn154/dummies/NoScanP.nc | 17 +- ...ispatchP.nc => NoSlottedFrameDispatchP.nc} | 91 +- .../mac/tkn154/interfaces/MCPS/MCPS_DATA.nc | 47 +- .../mac/tkn154/interfaces/MCPS/MCPS_PURGE.nc | 12 +- .../tkn154/interfaces/MLME/MLME_ASSOCIATE.nc | 15 +- .../interfaces/MLME/MLME_BEACON_NOTIFY.nc | 22 +- .../interfaces/MLME/MLME_COMM_STATUS.nc | 8 + .../interfaces/MLME/MLME_DISASSOCIATE.nc | 12 +- .../mac/tkn154/interfaces/MLME/MLME_GET.nc | 19 +- .../mac/tkn154/interfaces/MLME/MLME_GTS.nc | 7 + .../mac/tkn154/interfaces/MLME/MLME_ORPHAN.nc | 6 + .../mac/tkn154/interfaces/MLME/MLME_POLL.nc | 6 + .../mac/tkn154/interfaces/MLME/MLME_RESET.nc | 17 +- .../tkn154/interfaces/MLME/MLME_RX_ENABLE.nc | 6 + .../mac/tkn154/interfaces/MLME/MLME_SCAN.nc | 6 + .../mac/tkn154/interfaces/MLME/MLME_SET.nc | 16 +- .../mac/tkn154/interfaces/MLME/MLME_START.nc | 8 + .../mac/tkn154/interfaces/MLME/MLME_SYNC.nc | 8 + .../tkn154/interfaces/MLME/MLME_SYNC_LOSS.nc | 7 + .../interfaces/private/EnergyDetection.nc | 4 +- .../mac/tkn154/interfaces/private/FrameRx.nc | 3 +- .../mac/tkn154/interfaces/private/FrameTx.nc | 4 +- .../tkn154/interfaces/private/FrameTxNow.nc | 4 +- .../mac/tkn154/interfaces/private/RadioOff.nc | 11 +- .../mac/tkn154/interfaces/private/RadioRx.nc | 71 +- .../mac/tkn154/interfaces/private/RadioTx.nc | 206 +---- .../interfaces/private/SlottedCsmaCa.nc | 117 +++ .../interfaces/private/SuperframeStructure.nc | 115 +++ .../interfaces/private/UnslottedCsmaCa.nc | 90 ++ .../interfaces/public/IEEE154BeaconFrame.nc | 4 + .../tkn154/interfaces/public/IEEE154Frame.nc | 8 +- .../public/IEEE154TxBeaconPayload.nc | 58 +- .../mac/tkn154/Ieee802154BeaconEnabledC.nc | 175 ++++ .../mac/tkn154/Ieee802154NonBeaconEnabledC.nc | 148 +++ .../telosb/mac/tkn154/TKN154TimingP.nc | 78 +- .../telosb/mac/tkn154/TKN154_platform.h | 34 +- .../telosb/mac/tkn154/platform_message.h | 8 +- .../timer/Alarm32khzTo62500hzTransformC.nc | 20 +- 116 files changed, 4319 insertions(+), 3036 deletions(-) rename tos/lib/mac/tkn154/{interfaces/private/Ieee802154Debug.nc => DebugC.nc} (80%) create mode 100644 tos/lib/mac/tkn154/DebugP.nc rename tos/lib/mac/tkn154/{FrameDispatchP.nc => SlottedFrameDispatchP.nc} (50%) rename tos/lib/mac/tkn154/{TKN154P.nc => TKN154BeaconEnabledP.nc} (78%) create mode 100644 tos/lib/mac/tkn154/TKN154NonBeaconEnabledP.nc delete mode 100644 tos/lib/mac/tkn154/TKN154_DEBUG.h create mode 100644 tos/lib/mac/tkn154/UnslottedFrameDispatchP.nc delete mode 100644 tos/lib/mac/tkn154/dummies/NoDebugP.nc rename tos/lib/mac/tkn154/dummies/{NoFrameDispatchP.nc => NoSlottedFrameDispatchP.nc} (55%) create mode 100644 tos/lib/mac/tkn154/interfaces/private/SlottedCsmaCa.nc create mode 100644 tos/lib/mac/tkn154/interfaces/private/SuperframeStructure.nc create mode 100644 tos/lib/mac/tkn154/interfaces/private/UnslottedCsmaCa.nc create mode 100644 tos/platforms/telosb/mac/tkn154/Ieee802154BeaconEnabledC.nc create mode 100644 tos/platforms/telosb/mac/tkn154/Ieee802154NonBeaconEnabledC.nc diff --git a/apps/tests/tkn154/Makefile.include b/apps/tests/tkn154/Makefile.include index 06212b52..13604c3f 100644 --- a/apps/tests/tkn154/Makefile.include +++ b/apps/tests/tkn154/Makefile.include @@ -12,6 +12,12 @@ ifdef IEEE154_EXTENDED_ADDRESS 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) diff --git a/apps/tests/tkn154/TestAssociate/coordinator/TestAssociateAppC.nc b/apps/tests/tkn154/TestAssociate/coordinator/TestAssociateAppC.nc index 5945ddf5..7a4ca06e 100644 --- a/apps/tests/tkn154/TestAssociate/coordinator/TestAssociateAppC.nc +++ b/apps/tests/tkn154/TestAssociate/coordinator/TestAssociateAppC.nc @@ -36,19 +36,19 @@ 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; } diff --git a/apps/tests/tkn154/TestAssociate/coordinator/TestCoordC.nc b/apps/tests/tkn154/TestAssociate/coordinator/TestCoordC.nc index ceb793c6..b0d8ca9a 100644 --- a/apps/tests/tkn154/TestAssociate/coordinator/TestCoordC.nc +++ b/apps/tests/tkn154/TestAssociate/coordinator/TestCoordC.nc @@ -56,7 +56,7 @@ module TestCoordC 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) diff --git a/apps/tests/tkn154/TestAssociate/device/TestAssociateAppC.nc b/apps/tests/tkn154/TestAssociate/device/TestAssociateAppC.nc index c99e233a..992d3dcb 100644 --- a/apps/tests/tkn154/TestAssociate/device/TestAssociateAppC.nc +++ b/apps/tests/tkn154/TestAssociate/device/TestAssociateAppC.nc @@ -36,23 +36,23 @@ 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; } diff --git a/apps/tests/tkn154/TestAssociate/device/TestDeviceC.nc b/apps/tests/tkn154/TestAssociate/device/TestDeviceC.nc index 1c22739f..55a07084 100644 --- a/apps/tests/tkn154/TestAssociate/device/TestDeviceC.nc +++ b/apps/tests/tkn154/TestAssociate/device/TestDeviceC.nc @@ -67,7 +67,7 @@ module TestDeviceC 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) diff --git a/apps/tests/tkn154/TestData/app_profile.h b/apps/tests/tkn154/TestData/app_profile.h index bf736a00..5a331de9 100644 --- a/apps/tests/tkn154/TestData/app_profile.h +++ b/apps/tests/tkn154/TestData/app_profile.h @@ -43,5 +43,6 @@ enum { BEACON_ORDER = 5, SUPERFRAME_ORDER = 5, }; +//#define IEEE154_DEFAULT_TRANSMITPOWER_dBm -25 #endif diff --git a/apps/tests/tkn154/TestData/coordinator/TestCoordReceiverC.nc b/apps/tests/tkn154/TestData/coordinator/TestCoordReceiverC.nc index db59ec06..8ae7d636 100644 --- a/apps/tests/tkn154/TestData/coordinator/TestCoordReceiverC.nc +++ b/apps/tests/tkn154/TestData/coordinator/TestCoordReceiverC.nc @@ -53,7 +53,7 @@ module TestCoordReceiverC 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) diff --git a/apps/tests/tkn154/TestData/coordinator/TestDataAppC.nc b/apps/tests/tkn154/TestData/coordinator/TestDataAppC.nc index eeb8d0db..4c485161 100644 --- a/apps/tests/tkn154/TestData/coordinator/TestDataAppC.nc +++ b/apps/tests/tkn154/TestData/coordinator/TestDataAppC.nc @@ -32,21 +32,21 @@ * @author: Jan Hauer * ======================================================================== */ - +#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; } diff --git a/apps/tests/tkn154/TestData/device/Makefile b/apps/tests/tkn154/TestData/device/Makefile index 42f11300..d6b49165 100644 --- a/apps/tests/tkn154/TestData/device/Makefile +++ b/apps/tests/tkn154/TestData/device/Makefile @@ -1,3 +1,4 @@ COMPONENT=TestDataAppC +PFLAGS += -DIEEE154_BEACON_TX_DISABLED CFLAGS += -I$(shell pwd)/.. include ../../Makefile.include diff --git a/apps/tests/tkn154/TestData/device/TestDataAppC.nc b/apps/tests/tkn154/TestData/device/TestDataAppC.nc index f59355c3..147f4834 100644 --- a/apps/tests/tkn154/TestData/device/TestDataAppC.nc +++ b/apps/tests/tkn154/TestData/device/TestDataAppC.nc @@ -32,25 +32,25 @@ * @author: Jan Hauer * ======================================================================== */ - +#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; } diff --git a/apps/tests/tkn154/TestData/device/TestDeviceSenderC.nc b/apps/tests/tkn154/TestData/device/TestDeviceSenderC.nc index 4534df2e..279e43e2 100644 --- a/apps/tests/tkn154/TestData/device/TestDeviceSenderC.nc +++ b/apps/tests/tkn154/TestData/device/TestDeviceSenderC.nc @@ -73,7 +73,7 @@ module TestDeviceSenderC 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); } } @@ -110,6 +110,7 @@ module TestDeviceSenderC 0 // security ); } + bool m_ready; event message_t* MLME_BEACON_NOTIFY.indication (message_t* frame) { @@ -117,6 +118,8 @@ module TestDeviceSenderC 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 @@ -158,6 +161,7 @@ module TestDeviceSenderC NULL // security ); post packetSendTask(); + m_ready = TRUE; } else startApp(); } @@ -169,11 +173,12 @@ module TestDeviceSenderC &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, @@ -184,7 +189,8 @@ module TestDeviceSenderC m_sending = FALSE; if (status == IEEE154_SUCCESS && m_ledCount++ == 20){ m_ledCount = 0; - call Leds.led1Toggle(); + if (m_useLeds) + call Leds.led1Toggle(); } post packetSendTask(); } @@ -196,7 +202,9 @@ module TestDeviceSenderC uint8_t ChannelPage, ieee154_security_t *security) { - startApp(); + m_useLeds = FALSE; + call Leds.led1Off(); + //startApp(); } event message_t* MCPS_DATA.indication (message_t* frame) diff --git a/apps/tests/tkn154/TestIndirect/coordinator/TestCoordSenderC.nc b/apps/tests/tkn154/TestIndirect/coordinator/TestCoordSenderC.nc index 454cbdad..381aba9f 100644 --- a/apps/tests/tkn154/TestIndirect/coordinator/TestCoordSenderC.nc +++ b/apps/tests/tkn154/TestIndirect/coordinator/TestCoordSenderC.nc @@ -73,7 +73,7 @@ module TestCoordSenderC &deviceShortAddress, // DstAddr, NULL // security ); - call MLME_RESET.request(TRUE, BEACON_ENABLED_PAN); + call MLME_RESET.request(TRUE); } } diff --git a/apps/tests/tkn154/TestIndirect/coordinator/TestIndirectAppC.nc b/apps/tests/tkn154/TestIndirect/coordinator/TestIndirectAppC.nc index c64332b9..2ba70e27 100644 --- a/apps/tests/tkn154/TestIndirect/coordinator/TestIndirectAppC.nc +++ b/apps/tests/tkn154/TestIndirect/coordinator/TestIndirectAppC.nc @@ -35,18 +35,18 @@ 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; } diff --git a/apps/tests/tkn154/TestIndirect/device/TestDeviceReceiverC.nc b/apps/tests/tkn154/TestIndirect/device/TestDeviceReceiverC.nc index 45396db7..197a0430 100644 --- a/apps/tests/tkn154/TestIndirect/device/TestDeviceReceiverC.nc +++ b/apps/tests/tkn154/TestIndirect/device/TestDeviceReceiverC.nc @@ -59,7 +59,7 @@ module TestDeviceReceiverC 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) @@ -99,6 +99,12 @@ module TestDeviceReceiverC { // 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){ diff --git a/apps/tests/tkn154/TestIndirect/device/TestIndirectAppC.nc b/apps/tests/tkn154/TestIndirect/device/TestIndirectAppC.nc index 4583acb1..f077e5d0 100644 --- a/apps/tests/tkn154/TestIndirect/device/TestIndirectAppC.nc +++ b/apps/tests/tkn154/TestIndirect/device/TestIndirectAppC.nc @@ -36,18 +36,18 @@ 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; } diff --git a/apps/tests/tkn154/TestPromiscuous/Makefile b/apps/tests/tkn154/TestPromiscuous/Makefile index c3b7be81..780854a9 100644 --- a/apps/tests/tkn154/TestPromiscuous/Makefile +++ b/apps/tests/tkn154/TestPromiscuous/Makefile @@ -1,5 +1,4 @@ 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 diff --git a/apps/tests/tkn154/TestPromiscuous/TestPromiscuousAppC.nc b/apps/tests/tkn154/TestPromiscuous/TestPromiscuousAppC.nc index e48ac507..c771d29d 100644 --- a/apps/tests/tkn154/TestPromiscuous/TestPromiscuousAppC.nc +++ b/apps/tests/tkn154/TestPromiscuous/TestPromiscuousAppC.nc @@ -37,16 +37,16 @@ configuration TestPromiscuousAppC { } 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; } diff --git a/apps/tests/tkn154/TestPromiscuous/TestPromiscuousC.nc b/apps/tests/tkn154/TestPromiscuous/TestPromiscuousC.nc index bc3699f7..ab9ea599 100644 --- a/apps/tests/tkn154/TestPromiscuous/TestPromiscuousC.nc +++ b/apps/tests/tkn154/TestPromiscuous/TestPromiscuousC.nc @@ -58,7 +58,7 @@ module TestPromiscuousC }; 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) diff --git a/apps/tests/tkn154/TestStartSync/coordinator/TestCoordC.nc b/apps/tests/tkn154/TestStartSync/coordinator/TestCoordC.nc index f752bdad..e401db6c 100644 --- a/apps/tests/tkn154/TestStartSync/coordinator/TestCoordC.nc +++ b/apps/tests/tkn154/TestStartSync/coordinator/TestCoordC.nc @@ -51,7 +51,7 @@ module TestCoordC 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) diff --git a/apps/tests/tkn154/TestStartSync/coordinator/TestStartSyncAppC.nc b/apps/tests/tkn154/TestStartSync/coordinator/TestStartSyncAppC.nc index d0913c7f..6020c4b5 100644 --- a/apps/tests/tkn154/TestStartSync/coordinator/TestStartSyncAppC.nc +++ b/apps/tests/tkn154/TestStartSync/coordinator/TestStartSyncAppC.nc @@ -37,14 +37,14 @@ configuration TestStartSyncAppC { } 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; } diff --git a/apps/tests/tkn154/TestStartSync/device/TestDeviceC.nc b/apps/tests/tkn154/TestStartSync/device/TestDeviceC.nc index 93713b8a..c11193a2 100644 --- a/apps/tests/tkn154/TestStartSync/device/TestDeviceC.nc +++ b/apps/tests/tkn154/TestStartSync/device/TestDeviceC.nc @@ -58,7 +58,7 @@ module TestDeviceC 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) @@ -69,13 +69,14 @@ module TestDeviceC 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 @@ -83,7 +84,7 @@ module TestDeviceC call MLME_SET.macAutoRequest(TRUE); call MLME_SCAN.request ( PASSIVE_SCAN, // ScanType - supportedChannels, // ScanChannels + scanChannels, // ScanChannels scanDuration, // ScanDuration 0x00, // ChannelPage 0, // EnergyDetectListNumEntries diff --git a/apps/tests/tkn154/TestStartSync/device/TestStartSyncAppC.nc b/apps/tests/tkn154/TestStartSync/device/TestStartSyncAppC.nc index 9373400a..c6f1f676 100644 --- a/apps/tests/tkn154/TestStartSync/device/TestStartSyncAppC.nc +++ b/apps/tests/tkn154/TestStartSync/device/TestStartSyncAppC.nc @@ -37,20 +37,20 @@ configuration TestStartSyncAppC { } 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; diff --git a/tos/chips/cc2420_tkn154/CC2420ControlP.nc b/tos/chips/cc2420_tkn154/CC2420ControlP.nc index 6b8eac0d..12315c7a 100644 --- a/tos/chips/cc2420_tkn154/CC2420ControlP.nc +++ b/tos/chips/cc2420_tkn154/CC2420ControlP.nc @@ -73,10 +73,7 @@ module CC2420ControlP { uses interface CC2420Strobe as SFLUSHRX; uses interface CC2420Register as TXCTRL; uses interface AMPacket; - uses interface Resource as SpiResource; - - uses interface Leds; uses interface FrameUtility; } @@ -290,7 +287,7 @@ implementation { // 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 @@ -398,6 +395,7 @@ implementation { 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 diff --git a/tos/chips/cc2420_tkn154/CC2420ControlTransmitC.nc b/tos/chips/cc2420_tkn154/CC2420ControlTransmitC.nc index 83aa7d31..64e1834f 100644 --- a/tos/chips/cc2420_tkn154/CC2420ControlTransmitC.nc +++ b/tos/chips/cc2420_tkn154/CC2420ControlTransmitC.nc @@ -64,7 +64,6 @@ configuration CC2420ControlTransmitC { interface Alarm as AckAlarm; interface CaptureTime; interface ReferenceTime; - interface Leds; } } @@ -76,7 +75,6 @@ implementation { CC2420Config = CC2420ControlP; CC2420Power = CC2420ControlP; FrameUtility = CC2420ControlP; - CC2420ControlP.Leds = Leds; components MainC; MainC.SoftwareInit -> CC2420ControlP; @@ -119,13 +117,14 @@ implementation { 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; diff --git a/tos/chips/cc2420_tkn154/CC2420Power.nc b/tos/chips/cc2420_tkn154/CC2420Power.nc index 9d62b049..403bfb0b 100644 --- a/tos/chips/cc2420_tkn154/CC2420Power.nc +++ b/tos/chips/cc2420_tkn154/CC2420Power.nc @@ -99,7 +99,7 @@ interface CC2420Power { /** * 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); diff --git a/tos/chips/cc2420_tkn154/CC2420Receive.nc b/tos/chips/cc2420_tkn154/CC2420Receive.nc index 1ba224ed..a49e988c 100644 --- a/tos/chips/cc2420_tkn154/CC2420Receive.nc +++ b/tos/chips/cc2420_tkn154/CC2420Receive.nc @@ -45,7 +45,7 @@ interface CC2420Receive { * * @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 diff --git a/tos/chips/cc2420_tkn154/CC2420ReceiveC.nc b/tos/chips/cc2420_tkn154/CC2420ReceiveC.nc index f8381822..77aac38c 100644 --- a/tos/chips/cc2420_tkn154/CC2420ReceiveC.nc +++ b/tos/chips/cc2420_tkn154/CC2420ReceiveC.nc @@ -43,7 +43,6 @@ configuration CC2420ReceiveC { 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; } @@ -56,7 +55,6 @@ implementation { components HplCC2420PinsC as Pins; components HplCC2420InterruptsC as InterruptsC; - CC2420ReceiveP.Leds = Leds; CC2420AsyncSplitControl = CC2420ReceiveP; CC2420Receive = CC2420ReceiveP; CC2420Rx = CC2420ReceiveP; diff --git a/tos/chips/cc2420_tkn154/CC2420ReceiveP.nc b/tos/chips/cc2420_tkn154/CC2420ReceiveP.nc index 4824d540..d8f8386f 100644 --- a/tos/chips/cc2420_tkn154/CC2420ReceiveP.nc +++ b/tos/chips/cc2420_tkn154/CC2420ReceiveP.nc @@ -59,8 +59,6 @@ module CC2420ReceiveP { uses interface FrameUtility; uses interface CC2420Config; uses interface CC2420Ram as RXFIFO_RAM; - - uses interface Leds; } implementation { @@ -82,8 +80,8 @@ 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; @@ -156,10 +154,7 @@ implementation { // 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! @@ -209,8 +204,7 @@ implementation { 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); @@ -244,13 +238,13 @@ implementation { * 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++; } } @@ -281,10 +275,7 @@ implementation { 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(); } } @@ -408,9 +399,9 @@ implementation { } 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--; @@ -465,12 +456,7 @@ implementation { 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 diff --git a/tos/chips/cc2420_tkn154/CC2420Rx.nc b/tos/chips/cc2420_tkn154/CC2420Rx.nc index 1f1abf2e..bb794342 100644 --- a/tos/chips/cc2420_tkn154/CC2420Rx.nc +++ b/tos/chips/cc2420_tkn154/CC2420Rx.nc @@ -42,7 +42,7 @@ interface CC2420Rx { * 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); } diff --git a/tos/chips/cc2420_tkn154/CC2420TKN154C.nc b/tos/chips/cc2420_tkn154/CC2420TKN154C.nc index 18da878a..99098390 100644 --- a/tos/chips/cc2420_tkn154/CC2420TKN154C.nc +++ b/tos/chips/cc2420_tkn154/CC2420TKN154C.nc @@ -41,10 +41,13 @@ configuration CC2420TKN154C interface SplitControl; interface RadioRx; interface RadioTx; + interface SlottedCsmaCa; + interface UnslottedCsmaCa; interface EnergyDetection; interface RadioOff; interface Set as RadioPromiscuousMode; interface Timestamp; + interface GetNow as CCA; } uses { interface Notify as PIBUpdate[uint8_t attributeID]; interface LocalTime; @@ -55,7 +58,6 @@ configuration CC2420TKN154C interface ReferenceTime; interface ReliableWait; interface TimeCalc; - interface Leds; interface Random; } } implementation { @@ -65,6 +67,8 @@ configuration CC2420TKN154C SplitControl = PHY; RadioRx = PHY; RadioTx = PHY; + SlottedCsmaCa = PHY; + UnslottedCsmaCa = PHY; RadioOff = PHY; EnergyDetection = PHY; PIBUpdate = PHY; @@ -74,9 +78,9 @@ configuration CC2420TKN154C ReliableWait = PHY; ReferenceTime = PHY; TimeCalc = PHY; + CCA = PHY; PHY.Random = Random; - Leds = PHY.Leds; components CC2420ControlTransmitC; PHY.SpiResource -> CC2420ControlTransmitC; @@ -84,7 +88,6 @@ configuration CC2420TKN154C PHY.CC2420Config -> CC2420ControlTransmitC; CC2420ControlTransmitC.StartupAlarm = Alarm2; FrameUtility = CC2420ControlTransmitC; - Leds = CC2420ControlTransmitC; PHY.TxControl -> CC2420ControlTransmitC; PHY.CC2420Tx -> CC2420ControlTransmitC; @@ -96,7 +99,6 @@ configuration CC2420TKN154C PHY.RxControl -> CC2420ReceiveC; PHY.CC2420Rx -> CC2420ReceiveC.CC2420Rx; ReferenceTime = CC2420ReceiveC; - Leds = CC2420ReceiveC; FrameUtility = CC2420ReceiveC; CC2420ReceiveC.CC2420Config -> CC2420ControlTransmitC; } diff --git a/tos/chips/cc2420_tkn154/CC2420TKN154P.nc b/tos/chips/cc2420_tkn154/CC2420TKN154P.nc index 73e0a7d7..67c42c2c 100644 --- a/tos/chips/cc2420_tkn154/CC2420TKN154P.nc +++ b/tos/chips/cc2420_tkn154/CC2420TKN154P.nc @@ -43,12 +43,15 @@ module CC2420TKN154P provides { interface SplitControl; + interface RadioOff; interface RadioRx; interface RadioTx; - interface RadioOff; + interface SlottedCsmaCa; + interface UnslottedCsmaCa; interface EnergyDetection; interface Set as RadioPromiscuousMode; interface Timestamp; + interface GetNow as CCA; } uses { interface Notify as PIBUpdate[uint8_t attributeID]; interface LocalTime as LocalTime; @@ -72,78 +75,83 @@ module CC2420TKN154P 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(); } @@ -154,7 +162,6 @@ module CC2420TKN154P async event void CC2420Power.startOscillatorDone() { - // default configuration (addresses, etc) has been written call CC2420Power.rfOff(); call CC2420Power.flushRxFifo(); call CC2420Tx.unlockChipSpi(); @@ -172,7 +179,6 @@ module CC2420TKN154P 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); } @@ -182,61 +188,46 @@ module CC2420TKN154P 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) @@ -274,10 +265,10 @@ module CC2420TKN154P 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: @@ -291,76 +282,63 @@ module CC2420TKN154P 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; } @@ -369,7 +347,7 @@ module CC2420TKN154P if (call SpiResource.immediateRequest() == SUCCESS) offSpiReserved(); else - call SpiResource.request(); // will trigger offSpiReserved() + call SpiResource.request(); /* will continue in offSpiReserved() */ } void offSpiReserved() @@ -388,72 +366,51 @@ module CC2420TKN154P 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); @@ -462,341 +419,413 @@ module CC2420TKN154P } 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) { @@ -805,40 +834,51 @@ module CC2420TKN154P 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) {} } diff --git a/tos/chips/cc2420_tkn154/CC2420TransmitP.nc b/tos/chips/cc2420_tkn154/CC2420TransmitP.nc index 87388ce9..4e4c9554 100644 --- a/tos/chips/cc2420_tkn154/CC2420TransmitP.nc +++ b/tos/chips/cc2420_tkn154/CC2420TransmitP.nc @@ -59,6 +59,8 @@ module CC2420TransmitP { 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; @@ -101,7 +103,7 @@ implementation { }; norace ieee154_txframe_t *m_frame; - ieee154_reftime_t m_timestamp; + ieee154_timestamp_t m_timestamp; cc2420_transmit_state_t m_state = S_STOPPED; @@ -230,6 +232,7 @@ implementation { 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; } @@ -259,8 +262,9 @@ implementation { 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; @@ -289,6 +293,7 @@ implementation { /** Fall Through because the next interrupt was already received */ default: + // The CC2420 is in receive mode. if ( !m_receiving ) { sfdHigh = TRUE; call CaptureSFD.captureFallingEdge(); @@ -306,13 +311,8 @@ implementation { 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; } @@ -397,8 +397,11 @@ implementation { } 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(); } diff --git a/tos/chips/cc2420_tkn154/CC2420Tx.nc b/tos/chips/cc2420_tkn154/CC2420Tx.nc index 8d7fe923..d27f8925 100644 --- a/tos/chips/cc2420_tkn154/CC2420Tx.nc +++ b/tos/chips/cc2420_tkn154/CC2420Tx.nc @@ -41,7 +41,7 @@ interface CC2420Tx { 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(); diff --git a/tos/chips/cc2420_tkn154/CaptureTime.nc b/tos/chips/cc2420_tkn154/CaptureTime.nc index 45e7300e..14980fda 100644 --- a/tos/chips/cc2420_tkn154/CaptureTime.nc +++ b/tos/chips/cc2420_tkn154/CaptureTime.nc @@ -38,6 +38,20 @@ interface CaptureTime * @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); } diff --git a/tos/chips/cc2420_tkn154/ReferenceTime.nc b/tos/chips/cc2420_tkn154/ReferenceTime.nc index e91e0e6b..3e77e3c8 100644 --- a/tos/chips/cc2420_tkn154/ReferenceTime.nc +++ b/tos/chips/cc2420_tkn154/ReferenceTime.nc @@ -33,12 +33,12 @@ 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); } diff --git a/tos/chips/cc2420_tkn154/ReliableWait.nc b/tos/chips/cc2420_tkn154/ReliableWait.nc index 0ac64324..9cd3b0df 100644 --- a/tos/chips/cc2420_tkn154/ReliableWait.nc +++ b/tos/chips/cc2420_tkn154/ReliableWait.nc @@ -32,14 +32,11 @@ */ 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); } diff --git a/tos/chips/cc2420_tkn154/Timestamp.nc b/tos/chips/cc2420_tkn154/Timestamp.nc index 0f041631..9a1270d8 100644 --- a/tos/chips/cc2420_tkn154/Timestamp.nc +++ b/tos/chips/cc2420_tkn154/Timestamp.nc @@ -69,7 +69,7 @@ interface Timestamp /** * Modify (overwrite) the contents of the MAC payload. This command must * only be called in the context of a 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 * transmittedSFD()<\code> must be finished (offset of zero might not work). * * @param token the token signalled by transmittedSFD()<\code> diff --git a/tos/lib/mac/tkn154/AssociateP.nc b/tos/lib/mac/tkn154/AssociateP.nc index 57409419..11f96f0d 100644 --- a/tos/lib/mac/tkn154/AssociateP.nc +++ b/tos/lib/mac/tkn154/AssociateP.nc @@ -60,7 +60,6 @@ module AssociateP interface FrameUtility; interface IEEE154Frame as Frame; interface Get as LocalExtendedAddress; - interface Ieee802154Debug as Debug; } } implementation @@ -87,7 +86,7 @@ implementation return SUCCESS; } -/* ------------------- MLME_ASSOCIATE Request ------------------- */ + /* ------------------- MLME_ASSOCIATE Request ------------------- */ command ieee154_status_t MLME_ASSOCIATE.request ( uint8_t LogicalChannel, @@ -96,8 +95,7 @@ implementation 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; @@ -112,11 +110,11 @@ implementation 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); @@ -146,13 +144,13 @@ implementation 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; } @@ -160,15 +158,15 @@ implementation { 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() @@ -182,7 +180,7 @@ implementation 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(); @@ -192,7 +190,7 @@ implementation 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); } @@ -201,15 +199,16 @@ implementation 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) { @@ -226,8 +225,7 @@ implementation 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; @@ -240,7 +238,7 @@ implementation 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 { @@ -263,7 +261,7 @@ implementation *((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); @@ -288,18 +286,16 @@ implementation 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, @@ -307,6 +303,5 @@ implementation uint8_t DstAddrMode, ieee154_address_t DstAddr, ieee154_status_t status, - ieee154_security_t *security - ){} + ieee154_security_t *security) {} } diff --git a/tos/lib/mac/tkn154/BeaconSynchronizeP.nc b/tos/lib/mac/tkn154/BeaconSynchronizeP.nc index eadfc4bc..87412974 100644 --- a/tos/lib/mac/tkn154/BeaconSynchronizeP.nc +++ b/tos/lib/mac/tkn154/BeaconSynchronizeP.nc @@ -33,9 +33,12 @@ * ======================================================================== */ +/** + * This module is responsible for periodic beacon tracking in a + * beacon-enabled PAN. + */ #include "TKN154_MAC.h" -#include "TKN154_DEBUG.h" module BeaconSynchronizeP { @@ -45,33 +48,19 @@ module BeaconSynchronizeP interface MLME_SYNC; interface MLME_BEACON_NOTIFY; interface MLME_SYNC_LOSS; + interface SuperframeStructure as IncomingSF; interface GetNow as IsTrackingBeacons; - interface GetNow as CapStart; - interface GetNow as CapStartRefTime; - interface GetNow as CapLen; - interface GetNow as CapEnd; - interface GetNow as CfpEnd; - interface GetNow as CfpLen; - interface GetNow as BeaconInterval; - interface GetNow as IsBLEActive; - interface GetNow as BLELen; - interface GetNow as GtsField; - interface GetNow as SfSlotDuration; - interface GetNow as FinalCapSlot; - interface GetNow as NumGtsSlots; - interface GetNow as IsRxBroadcastPending; + interface StdControl as TrackSingleBeacon; } uses { interface MLME_GET; interface MLME_SET; interface FrameUtility; - interface Notify as FindBeacon; interface IEEE154BeaconFrame as BeaconFrame; interface Alarm as TrackAlarm; interface RadioRx as BeaconRx; interface RadioOff; - interface GetNow as IsBeaconEnabledPAN; interface DataRequest; interface FrameRx as CoordRealignmentRx; interface Resource as Token; @@ -81,56 +70,57 @@ module BeaconSynchronizeP 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, @@ -142,65 +132,52 @@ implementation 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) @@ -210,229 +187,234 @@ implementation 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; @@ -446,55 +428,98 @@ implementation 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) { @@ -506,8 +531,7 @@ implementation panID, // PANId payload[5], // LogicalChannel, call Frame.getPayloadLength(frame) == 9 ? payload[8] : call MLME_GET.phyCurrentPage(), - NULL - ); + NULL); return frame; } } diff --git a/tos/lib/mac/tkn154/BeaconTransmitP.nc b/tos/lib/mac/tkn154/BeaconTransmitP.nc index 04ef7641..8d977ae7 100644 --- a/tos/lib/mac/tkn154/BeaconTransmitP.nc +++ b/tos/lib/mac/tkn154/BeaconTransmitP.nc @@ -33,6 +33,11 @@ * ======================================================================== */ +/** + * This module is responsible for periodic beacon transmission in a + * beacon-enabled PAN. + */ + #include "TKN154_MAC.h" #include "TKN154_PHY.h" module BeaconTransmitP @@ -41,31 +46,16 @@ module BeaconTransmitP { interface Init as Reset; interface MLME_START; - interface WriteBeaconField as SuperframeSpecWrite; - interface GetNow as IsSendingBeacons; - interface GetNow as CapStart; - interface GetNow as CapStartRefTime; - interface GetNow as CapLen; - interface GetNow as CapEnd; - interface GetNow as CfpEnd; - interface GetNow as CfpLen; - interface GetNow as IsBLEActive; - interface GetNow as BLELen; - interface GetNow as GtsField; - interface GetNow as SfSlotDuration; - interface GetNow as BeaconInterval; - interface GetNow as FinalCapSlot; - interface GetNow as NumGtsSlots; - interface GetNow as BeaconFramePendingBit; interface IEEE154TxBeaconPayload; + interface SuperframeStructure as OutgoingSF; + interface GetNow as IsSendingBeacons; } uses { interface Notify as GtsSpecUpdated; interface Notify as PendingAddrSpecUpdated; interface Notify as PIBUpdate[uint8_t attributeID]; - interface Alarm as BeaconTxAlarm; + interface Alarm as BeaconSendAlarm; interface Timer as BeaconPayloadUpdateTimer; interface RadioOff; - interface GetNow as IsBeaconEnabledPAN; interface RadioTx as BeaconTx; interface MLME_GET; interface MLME_SET; @@ -80,9 +70,7 @@ module BeaconTransmitP interface WriteBeaconField as PendingAddrWrite; interface FrameUtility; interface GetNow as IsTrackingBeacons; - interface GetNow as LastBeaconRxTime; - interface GetNow as LastBeaconRxRefTime; - interface Ieee802154Debug as Debug; + interface SuperframeStructure as IncomingSF; interface Set as SetMacSuperframeOrder; interface Set as SetMacBeaconTxTime; interface Set as SetMacPanCoordinator; @@ -94,6 +82,51 @@ module BeaconTransmitP } 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, @@ -116,55 +149,9 @@ implementation 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(); @@ -173,30 +160,32 @@ implementation 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, @@ -211,9 +200,10 @@ implementation 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; @@ -228,21 +218,16 @@ implementation 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; @@ -250,12 +235,18 @@ implementation 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; } @@ -266,12 +257,12 @@ implementation 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; } @@ -284,11 +275,11 @@ implementation *((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 { @@ -296,12 +287,12 @@ implementation // 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 { @@ -309,7 +300,7 @@ implementation // 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; @@ -319,30 +310,26 @@ implementation 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(); @@ -350,11 +337,11 @@ implementation // (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(); @@ -362,9 +349,9 @@ implementation 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 { @@ -375,13 +362,13 @@ implementation 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); } } @@ -393,30 +380,31 @@ implementation 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 @@ -430,117 +418,136 @@ implementation 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(); } @@ -550,23 +557,23 @@ implementation 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) { @@ -648,56 +655,69 @@ implementation // 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); @@ -707,7 +727,7 @@ implementation 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 @@ -716,32 +736,12 @@ implementation } } -/* ----------------------- 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) { @@ -756,79 +756,83 @@ implementation 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() {} } diff --git a/tos/lib/mac/tkn154/CoordBroadcastP.nc b/tos/lib/mac/tkn154/CoordBroadcastP.nc index 3046a12d..43bc8554 100644 --- a/tos/lib/mac/tkn154/CoordBroadcastP.nc +++ b/tos/lib/mac/tkn154/CoordBroadcastP.nc @@ -51,7 +51,7 @@ module CoordBroadcastP interface FrameTxNow as CapTransmitNow; interface ResourceTransfer as TokenToCap; interface ResourceTransferred as TokenTransferred; - interface GetNow as BeaconFramePendingBit; + interface SuperframeStructure as OutgoingSF; interface Leds; } } @@ -90,7 +90,7 @@ implementation command ieee154_status_t RealignmentTx.transmit(ieee154_txframe_t *frame) { atomic { - if (!m_realignmentFrame){ + if (!m_realignmentFrame) { m_realignmentFrame = frame; return IEEE154_SUCCESS; } else @@ -109,15 +109,13 @@ implementation 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(); } @@ -133,10 +131,10 @@ implementation { 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); diff --git a/tos/lib/mac/tkn154/CoordRealignmentP.nc b/tos/lib/mac/tkn154/CoordRealignmentP.nc index 70421aa9..3287adb6 100644 --- a/tos/lib/mac/tkn154/CoordRealignmentP.nc +++ b/tos/lib/mac/tkn154/CoordRealignmentP.nc @@ -67,6 +67,7 @@ implementation ORPHAN_RESPONSE, BEACON_REALIGNMENT, }; + uint8_t m_payload[9]; bool m_busy = FALSE; void destroyRealignmentFrame(ieee154_txframe_t *frame); @@ -96,8 +97,7 @@ implementation call Frame.getSrcAddr(frame, &srcAddress) == SUCCESS) signal MLME_ORPHAN.indication ( srcAddress.extendedAddress, - NULL // security - ); + NULL); return frame; } @@ -105,8 +105,7 @@ implementation uint64_t OrphanAddress, uint16_t ShortAddress, bool AssociatedMember, - ieee154_security_t *security - ) + ieee154_security_t *security) { ieee154_txframe_t *txFrame; ieee154_status_t txStatus; @@ -125,7 +124,7 @@ implementation 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); } @@ -140,8 +139,8 @@ implementation 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 { @@ -150,7 +149,7 @@ implementation 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; @@ -185,7 +184,8 @@ implementation 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 ( @@ -195,8 +195,7 @@ implementation 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; @@ -210,11 +209,9 @@ implementation 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) {} } diff --git a/tos/lib/mac/tkn154/DataP.nc b/tos/lib/mac/tkn154/DataP.nc index e20f9ffa..af60e699 100644 --- a/tos/lib/mac/tkn154/DataP.nc +++ b/tos/lib/mac/tkn154/DataP.nc @@ -80,8 +80,7 @@ implementation 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); @@ -123,12 +122,12 @@ implementation // 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 @@ -137,7 +136,7 @@ implementation sfType = INCOMING_SUPERFRAME; // GTS? - if (txOptions & TX_OPTIONS_GTS){ + if (txOptions & TX_OPTIONS_GTS) { if (sfType == INCOMING_SUPERFRAME) txStatus = call DeviceCfpTx.transmit(txFrame); else @@ -146,8 +145,8 @@ implementation // 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 @@ -160,7 +159,7 @@ implementation else txStatus = call CoordCapTx.transmit(txFrame); - if (txStatus != IEEE154_SUCCESS){ + if (txStatus != IEEE154_SUCCESS) { call TxFramePool.put(txFrame); } } @@ -168,8 +167,7 @@ implementation } 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 || @@ -222,7 +220,7 @@ implementation 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) @@ -230,6 +228,7 @@ implementation 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); } @@ -269,10 +268,9 @@ implementation 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;} } diff --git a/tos/lib/mac/tkn154/interfaces/private/Ieee802154Debug.nc b/tos/lib/mac/tkn154/DebugC.nc similarity index 80% rename from tos/lib/mac/tkn154/interfaces/private/Ieee802154Debug.nc rename to tos/lib/mac/tkn154/DebugC.nc index c25e8cfc..91d3dde9 100644 --- a/tos/lib/mac/tkn154/interfaces/private/Ieee802154Debug.nc +++ b/tos/lib/mac/tkn154/DebugC.nc @@ -1,39 +1,42 @@ -/* +/* * 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 + * 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 + * - 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 + * - 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 + * 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 + * 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 + * @author: Jan Hauer * ======================================================================== */ -interface Ieee802154Debug -{ - async command void log(uint8_t priority, uint8_t eventID, uint32_t param1, uint32_t param2, uint32_t param3); - command void flush(); + +configuration DebugC { } +implementation { + components DebugP, LedsC; + DebugP.Leds -> LedsC; +} + diff --git a/tos/lib/mac/tkn154/DebugP.nc b/tos/lib/mac/tkn154/DebugP.nc new file mode 100644 index 00000000..8cad827c --- /dev/null +++ b/tos/lib/mac/tkn154/DebugP.nc @@ -0,0 +1,147 @@ +/* + * 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 + * ======================================================================== + */ + +#include "printf.h" +#include +#ifdef __STDC__ +#include +#else +#include +#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(); + } +} diff --git a/tos/lib/mac/tkn154/DisassociateP.nc b/tos/lib/mac/tkn154/DisassociateP.nc index a229f50a..dbc58a99 100644 --- a/tos/lib/mac/tkn154/DisassociateP.nc +++ b/tos/lib/mac/tkn154/DisassociateP.nc @@ -58,7 +58,6 @@ module DisassociateP interface FrameUtility; interface IEEE154Frame as Frame; interface Get as LocalExtendedAddress; - interface Ieee802154Debug as Debug; } } implementation @@ -78,7 +77,7 @@ implementation return SUCCESS; } -/* ------------------- MLME_DISASSOCIATE (initiating) ------------------- */ + /* ------------------- MLME_DISASSOCIATE (initiating) ------------------- */ command ieee154_status_t MLME_DISASSOCIATE.request ( uint8_t DeviceAddrMode, @@ -86,8 +85,7 @@ implementation 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; @@ -101,11 +99,11 @@ implementation 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(); @@ -129,20 +127,20 @@ implementation 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; } @@ -158,7 +156,7 @@ implementation 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); } @@ -176,15 +174,14 @@ implementation 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) { @@ -205,25 +202,24 @@ implementation { // 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) {} } diff --git a/tos/lib/mac/tkn154/FrameDispatchQueueP.nc b/tos/lib/mac/tkn154/FrameDispatchQueueP.nc index 4e34605f..6693ade0 100644 --- a/tos/lib/mac/tkn154/FrameDispatchQueueP.nc +++ b/tos/lib/mac/tkn154/FrameDispatchQueueP.nc @@ -54,7 +54,7 @@ implementation 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); } @@ -75,16 +75,16 @@ implementation 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; } } @@ -106,16 +106,16 @@ implementation 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 1) { + for (i=0; iheader->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; } @@ -124,5 +124,5 @@ implementation 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) {} } diff --git a/tos/lib/mac/tkn154/IndirectTxP.nc b/tos/lib/mac/tkn154/IndirectTxP.nc index d17ac67f..e1eacd6f 100644 --- a/tos/lib/mac/tkn154/IndirectTxP.nc +++ b/tos/lib/mac/tkn154/IndirectTxP.nc @@ -53,7 +53,6 @@ module IndirectTxP interface Timer as IndirectTxTimeout; interface TimeCalc; interface Leds; - interface Ieee802154Debug as Debug; } } implementation @@ -117,11 +116,11 @@ implementation return 0; pendingAddrField[0] = 0; adrPtr = (nxle_uint16_t *) &pendingAddrField[1]; - for (i=0; iheader->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)]); @@ -130,7 +129,6 @@ implementation 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; } @@ -143,8 +141,8 @@ implementation { // 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; @@ -160,7 +158,7 @@ implementation 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; } @@ -185,7 +183,7 @@ implementation src += 10; if (!((mhr[0] & FC1_PAN_ID_COMPRESSION) && (mhr[1] & FC2_DEST_MODE_SHORT))) src += 2; - for (i=0; iclient |= SEND_THIS_FRAME; post tryCoordCapTxTask(); @@ -220,14 +219,14 @@ implementation // 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; iclient & 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(); @@ -250,8 +249,8 @@ implementation uint8_t i; for (i=0; imetadata->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; @@ -262,11 +261,11 @@ implementation 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); @@ -278,7 +277,7 @@ implementation uint8_t i; // TODO: if CSMA-CA algorithm failed, then frame shall still remain in transaction queue for (i=0; iclient](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) {} } diff --git a/tos/lib/mac/tkn154/PibP.nc b/tos/lib/mac/tkn154/PibP.nc index d8f1c286..bf8a0ac2 100644 --- a/tos/lib/mac/tkn154/PibP.nc +++ b/tos/lib/mac/tkn154/PibP.nc @@ -32,8 +32,10 @@ * ======================================================================== */ -/* 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" @@ -49,8 +51,6 @@ module PibP { interface Set as SetMacSuperframeOrder; interface Set as SetMacBeaconTxTime; interface Set as SetMacPanCoordinator; - interface Get as IsMacPanCoordinator; - interface GetNow as IsBeaconEnabledPAN; interface FrameUtility; interface IEEE154Frame as Frame; interface IEEE154BeaconFrame as BeaconFrame; @@ -62,8 +62,8 @@ module PibP { uses { interface Get 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; @@ -77,8 +77,6 @@ implementation 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 @@ -152,7 +150,7 @@ implementation 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; } @@ -162,7 +160,7 @@ implementation 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 @@ -172,21 +170,22 @@ implementation // 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(); } @@ -197,15 +196,18 @@ implementation 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(); @@ -213,18 +215,17 @@ implementation 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) @@ -245,90 +246,92 @@ implementation 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; } @@ -339,13 +342,13 @@ implementation 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; @@ -353,7 +356,7 @@ implementation 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; @@ -361,25 +364,25 @@ implementation 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; @@ -387,7 +390,7 @@ implementation 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; @@ -395,37 +398,37 @@ implementation 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; @@ -434,7 +437,7 @@ implementation 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; @@ -443,37 +446,37 @@ implementation 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; @@ -482,7 +485,7 @@ implementation 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 ?? @@ -491,7 +494,7 @@ implementation 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; @@ -499,7 +502,7 @@ implementation 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; @@ -507,31 +510,27 @@ implementation 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) { @@ -553,7 +552,7 @@ implementation return (elapsed >= dt); } -/* ----------------------- Frame Access ----------------------- */ + /* ----------------------- Frame Access ----------------------- */ command void Packet.clear(message_t* msg) { @@ -595,10 +594,10 @@ implementation 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 { @@ -606,12 +605,12 @@ implementation 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 { @@ -636,10 +635,10 @@ implementation 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; } @@ -654,12 +653,12 @@ implementation 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; @@ -790,7 +789,7 @@ implementation 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; } @@ -849,20 +848,19 @@ implementation 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) { @@ -892,11 +890,11 @@ implementation 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> 4) && idata; - 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); @@ -945,7 +943,7 @@ implementation { 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); } @@ -961,25 +959,27 @@ implementation 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 @@ -994,12 +994,12 @@ implementation 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() { @@ -1010,7 +1010,7 @@ implementation { uint8_t i; uint64_t srcCopy = *src; - for (i=0; i<8; i++){ + for (i=0; i<8; i++) { destLE[i] = srcCopy; srcCopy >>= 8; } @@ -1049,12 +1049,7 @@ implementation 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;} } diff --git a/tos/lib/mac/tkn154/PollP.nc b/tos/lib/mac/tkn154/PollP.nc index 26972788..d00e986f 100644 --- a/tos/lib/mac/tkn154/PollP.nc +++ b/tos/lib/mac/tkn154/PollP.nc @@ -52,7 +52,6 @@ module PollP interface FrameUtility; interface Pool as TxFramePool; interface Pool as TxControlPool; - interface Ieee802154Debug as Debug; interface MLME_GET; interface Get as LocalExtendedAddress; } @@ -78,25 +77,24 @@ implementation 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; @@ -108,14 +106,16 @@ implementation 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, @@ -124,12 +124,13 @@ implementation 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 { @@ -138,10 +139,10 @@ implementation 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++; } @@ -187,26 +188,25 @@ implementation 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; @@ -218,6 +218,6 @@ implementation 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]() {} } diff --git a/tos/lib/mac/tkn154/PromiscuousModeP.nc b/tos/lib/mac/tkn154/PromiscuousModeP.nc index 8261c7d8..76a7f743 100644 --- a/tos/lib/mac/tkn154/PromiscuousModeP.nc +++ b/tos/lib/mac/tkn154/PromiscuousModeP.nc @@ -47,80 +47,66 @@ module PromiscuousModeP interface RadioRx as PromiscuousRx; interface RadioOff; interface Set 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 @@ -129,31 +115,33 @@ implementation 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) {} } diff --git a/tos/lib/mac/tkn154/README.txt b/tos/lib/mac/tkn154/README.txt index b5377075..01e3989e 100644 --- a/tos/lib/mac/tkn154/README.txt +++ b/tos/lib/mac/tkn154/README.txt @@ -1,18 +1,21 @@ 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 diff --git a/tos/lib/mac/tkn154/RadioClientC.nc b/tos/lib/mac/tkn154/RadioClientC.nc index 551679c2..4412d21a 100644 --- a/tos/lib/mac/tkn154/RadioClientC.nc +++ b/tos/lib/mac/tkn154/RadioClientC.nc @@ -32,14 +32,17 @@ * @author Jan Hauer * ======================================================================== */ + #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; @@ -60,6 +63,8 @@ implementation 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]; diff --git a/tos/lib/mac/tkn154/RadioControlImplP.nc b/tos/lib/mac/tkn154/RadioControlImplP.nc index ae0b7041..57dc48ac 100644 --- a/tos/lib/mac/tkn154/RadioControlImplP.nc +++ b/tos/lib/mac/tkn154/RadioControlImplP.nc @@ -32,66 +32,50 @@ * @author Jan Hauer * ======================================================================== */ + #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 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) @@ -110,96 +94,103 @@ implementation 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; } } @@ -218,38 +209,8 @@ implementation 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); } } diff --git a/tos/lib/mac/tkn154/RadioControlP.nc b/tos/lib/mac/tkn154/RadioControlP.nc index ad9d541b..08742945 100644 --- a/tos/lib/mac/tkn154/RadioControlP.nc +++ b/tos/lib/mac/tkn154/RadioControlP.nc @@ -39,6 +39,8 @@ configuration RadioControlP { 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]; @@ -48,10 +50,11 @@ configuration RadioControlP } uses { interface RadioRx as PhyRx; interface RadioTx as PhyTx; + interface SlottedCsmaCa as PhySlottedCsmaCa; + interface UnslottedCsmaCa as PhyUnslottedCsmaCa; interface RadioOff as PhyRadioOff; interface Get as RadioPromiscuousMode; interface Leds; - interface Ieee802154Debug as Debug; } } implementation @@ -59,13 +62,16 @@ 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; diff --git a/tos/lib/mac/tkn154/RxEnableP.nc b/tos/lib/mac/tkn154/RxEnableP.nc index 100ddac1..5e260174 100644 --- a/tos/lib/mac/tkn154/RxEnableP.nc +++ b/tos/lib/mac/tkn154/RxEnableP.nc @@ -39,23 +39,19 @@ module RxEnableP { provides { - interface Init; + interface Init as Reset; interface MLME_RX_ENABLE; interface GetNow as IsRxEnableActive; interface Notify as RxEnableStateChange; } uses { - interface Ieee802154Debug as Debug; interface Timer as RxEnableTimer; - interface GetNow as IsBeaconEnabledPAN; interface Get as IsMacPanCoordinator; + interface SuperframeStructure as IncomingSuperframeStructure; + interface SuperframeStructure as OutgoingSuperframeStructure; interface GetNow as IsTrackingBeacons; - interface GetNow as IncomingSfStart; - interface GetNow as IncomingBeaconInterval; interface GetNow as IsSendingBeacons; - interface GetNow as OutgoingSfStart; - interface GetNow as OutgoingBeaconInterval; interface Notify as WasRxEnabled; interface TimeCalc; } @@ -67,12 +63,12 @@ implementation 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; @@ -80,70 +76,79 @@ implementation 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); } } @@ -155,15 +160,23 @@ implementation 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;} } diff --git a/tos/lib/mac/tkn154/ScanP.nc b/tos/lib/mac/tkn154/ScanP.nc index cf49f222..ce332ba2 100644 --- a/tos/lib/mac/tkn154/ScanP.nc +++ b/tos/lib/mac/tkn154/ScanP.nc @@ -33,6 +33,10 @@ * ======================================================================== */ +/** + * This module is responsible for channel scanning. + */ + #include "TKN154_MAC.h" module ScanP { @@ -82,6 +86,7 @@ implementation bool m_busy = FALSE; void nextIteration(); + void continueScanRequest(); task void startTimerTask(); task void nextIterationTask(); @@ -89,22 +94,22 @@ implementation { // 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, @@ -115,24 +120,23 @@ implementation 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())) { @@ -156,7 +160,7 @@ implementation 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 { @@ -167,20 +171,35 @@ implementation 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; @@ -219,7 +238,7 @@ implementation 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++; @@ -227,26 +246,25 @@ implementation } 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; } @@ -255,7 +273,7 @@ implementation 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); } @@ -263,6 +281,7 @@ implementation if (call Token.isOwner()) call Token.release(); m_busy = FALSE; + dbg_serial("ScanP", "MLME_SCAN.confirm()\n"); signal MLME_SCAN.confirm ( result, m_scanType, @@ -273,12 +292,16 @@ implementation ((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) { @@ -293,37 +316,26 @@ implementation 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(); } @@ -336,34 +348,36 @@ implementation 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 as WasRxEnabled; - interface Notify as FindBeacon; } uses { @@ -79,39 +81,32 @@ generic module FrameDispatchP(uint8_t superframeDirection) interface GetNow as IsTokenRequested; interface ResourceTransfer as TokenToCfp; interface ResourceTransferred as TokenTransferred; - interface GetNow as CapStart; - interface GetNow as CapStartRefTime; - interface GetNow as CapLen; - interface GetNow as IsBLEActive; - interface GetNow as BLELen; - interface GetNow as IsRxBroadcastPending; + interface SuperframeStructure; interface GetNow as IsRxEnableActive; interface Get as GetIndirectTxFrame; interface Notify as RxEnableStateChange; interface GetNow as IsTrackingBeacons; interface FrameUtility; - interface RadioTx; + interface SlottedCsmaCa; interface RadioRx; interface RadioOff; - interface GetNow as IsBeaconEnabledPAN; interface MLME_GET; interface MLME_SET; - interface Ieee802154Debug as Debug; interface TimeCalc; interface Leds; interface SetNow as FrameBackup; interface GetNow as FrameRestore; + interface StdControl as TrackSingleBeacon; } } implementation { typedef enum { - SWITCH_OFF, - LOAD_TX, - PREPARE_RX, - DO_NOTHING, - WAIT_FOR_TXDONE, - } next_state_t; + SWITCH_OFF, + WAIT_FOR_RXDONE, + WAIT_FOR_TXDONE, + DO_NOTHING, + } next_state_t; typedef enum { INDIRECT_TX_ALARM, @@ -120,55 +115,31 @@ implementation } rx_alarm_t; enum { - COORD_ROLE = (superframeDirection == OUTGOING_SUPERFRAME), + 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 ieee154_csma_t m_csmaParams; - norace bool m_resume; 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 bool m_slottedCsma; norace ieee154_macMaxFrameRetries_t m_macMaxFrameRetries; - norace ieee154_status_t m_result; + 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; - -#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 - + /* function / task prototypes */ void stopAllAlarms(); next_state_t tryReceive(rx_alarm_t alarmType); next_state_t tryTransmit(); @@ -178,12 +149,32 @@ implementation 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(); +#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) @@ -199,69 +190,70 @@ implementation 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){ + // 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, + // 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(); + // 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 (actualCapLen < IEEE154_ACTIVE_PERIOD_GUARD_TIME){ - call Debug.log(DEBUG_LEVEL_IMPORTANT, 1, superframeDirection, actualCapLen, IEEE154_ACTIVE_PERIOD_GUARD_TIME); + } else if (capDuration < guardTime) { + // CAP is too short to do anything practical + dbg_serial("SlottedFrameDispatchP", "CAP too short!\n"); call TokenToCfp.transfer(); return; } else { - actualCapLen -= IEEE154_ACTIVE_PERIOD_GUARD_TIME; + capDuration -= guardTime; if (DEVICE_ROLE) - m_broadcastRxPending = call IsRxBroadcastPending.getNow(); + m_broadcastRxPending = call SuperframeStructure.isBroadcastPending(); 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 + // 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(); - call Debug.log(DEBUG_LEVEL_INFO, 7, 0,0,0); + dbg_serial("SlottedFrameDispatchP", "Preparing broadcast.\n"); } } - 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); + 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) { - //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); + 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); - 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(); + 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; } } @@ -270,17 +262,17 @@ implementation { 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, + 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, + // 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){ + 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] = @@ -298,27 +290,26 @@ implementation 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; + 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_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(); + // 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; } @@ -326,7 +317,7 @@ implementation void stopAllAlarms() { call CapEndAlarm.stop(); - if (DEVICE_ROLE){ + if (DEVICE_ROLE) { call IndirectTxWaitAlarm.stop(); call BroadcastAlarm.stop(); } @@ -334,79 +325,83 @@ implementation } /** - * 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. + * 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() { - error_t result = SUCCESS; + 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 (no loops, etc.) + // 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: 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())){ + 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, locked through isOwner() + 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){ + 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(); - 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){ + // 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){ + } 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() && call IsBeaconEnabledPAN.getNow()) { + 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(); - call Debug.log(DEBUG_LEVEL_INFO, 9, call IsTokenRequested.getNow(),0,0); - dbgHistoryFlush(); return; } else next = SWITCH_OFF; @@ -414,38 +409,41 @@ implementation // 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()) && + 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 && call IsRxEnableActive.getNow()){ + 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 + // 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 && - (!call IsBeaconEnabledPAN.getNow() || (DEVICE_ROLE && call CapLen.getNow() == 0))){ + 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 - call Debug.log(DEBUG_LEVEL_INFO, 10, 0,0,0); - dbgHistoryFlush(); + dbg_serial("SlottedFrameDispatchP", "Releasing token\n"); call Token.release(); return; } @@ -455,61 +453,46 @@ implementation 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 SWITCH_OFF: ASSERT(call RadioOff.off() == SUCCESS); break; + case WAIT_FOR_RXDONE: 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 + // tries to transmit m_currentFrame + uint32_t capDuration = (uint32_t) call SuperframeStructure.numCapSlots() * + (uint32_t) call SuperframeStructure.sfSlotDuration(); 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 - } + + 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; } - } else { - // the frame to transmit has not yet been loaded -> load it now - if (!call RadioOff.isOff()) - next = SWITCH_OFF; + if (call TimeCalc.hasExpired(call SuperframeStructure.sfStartTime(), dtMax)) + next = DO_NOTHING; // frame doesn't fit in the remaining CAP 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; + 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; @@ -518,21 +501,20 @@ implementation next_state_t tryReceive(rx_alarm_t alarmType) { next_state_t next; - if (call RadioRx.isReceiving()){ + if (call RadioRx.isReceiving()) next = DO_NOTHING; - } else if (call RadioRx.isPrepared()){ - call RadioRx.receive(NULL, 0); + 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 = DO_NOTHING; - } else if (call RadioOff.isOff()) - next = PREPARE_RX; - else - next = SWITCH_OFF; + next = WAIT_FOR_RXDONE; + } return next; } @@ -546,110 +528,106 @@ implementation 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 RadioOff.offDone() { m_lock = FALSE; updateState();} + async event void RadioRx.enableRxDone() { m_lock = FALSE; updateState();} - async event void CapEndAlarm.fired(){ - call Debug.log(DEBUG_LEVEL_IMPORTANT, 3, superframeDirection, 0, 0); + 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 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){ + 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) + async event void SlottedCsmaCa.transmitDone(ieee154_txframe_t *frame, ieee154_csma_t *csma, + bool ackPendingFlag, uint16_t remainingBackoff, error_t result) { bool done = TRUE; - //call Debug.log(DEBUG_LEVEL_INFO, 11, result,0,0); + 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 also - m_result = IEEE154_SUCCESS; + // 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){ + ((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){ + m_txStatus = IEEE154_NO_DATA; // pessimistic + if (ackPendingFlag) { // the coordinator has data for us; switch to Rx - // to complete the indirect transmission + // 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(); + ASSERT(call RadioRx.enableRx(0, 0) == SUCCESS); 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; + // 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 (and - // the AckRequest flag was set in the frame header) - // note: coordinator never retransmits an indirect transmission (see above) + // 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_csmaParams.NB = 0; - m_csmaParams.macMaxCsmaBackoffs = m_macMaxCSMABackoffs; - m_csmaParams.macMaxBE = m_macMaxBE; - m_csmaParams.BE = m_BE; + m_csma.NB = 0; + m_csma.macMaxCsmaBackoffs = m_macMaxCSMABackoffs; + m_csma.macMaxBE = m_macMaxBE; + m_csma.BE = m_BE; m_macMaxFrameRetries -= 1; } else - m_result = IEEE154_NO_ACK; + 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){ + + if (COORD_ROLE && frame == m_bcastFrame) { // always signal result of broadcast transmissions immediately restoreFrameFromBackup(); - signalTxBroadcastDone(m_bcastFrame, (!done) ? IEEE154_CHANNEL_ACCESS_FAILURE : m_result); + 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(); } @@ -657,33 +635,37 @@ implementation task void signalTxDoneTask() { ieee154_txframe_t *lastFrame = m_lastFrame; - m_lastFrame = NULL; // only now can a next transmission begin + ieee154_status_t status = m_txStatus; m_indirectTxPending = FALSE; - if (lastFrame) - signal FrameTx.transmitDone(lastFrame, m_result); + 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, ieee154_reftime_t *timestamp) + event message_t* RadioRx.received(message_t* frame, const ieee154_timestamp_t *timestamp) { - // received a frame during CAP - find out frame type and - // signal it to corresponding client component + // 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){ + 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; + // 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; @@ -694,32 +676,32 @@ implementation void backupCurrentFrame() { - ieee154_cap_frame_backup_t backup = {m_currentFrame, m_csmaParams, m_transactionTime}; + 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){ + if (backup != NULL) { m_currentFrame = backup->frame; - memcpy(&m_csmaParams, &backup->csmaParams, sizeof(ieee154_csma_t)); + 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 be called only once per CAP (max. one broadcast - // is allowed after a beacon transmission) + // 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){ + if (!call Token.isOwner() && m_bcastFrame == NULL) { m_bcastFrame = frame; return IEEE154_SUCCESS; } else { - call Leds.led0On(); + ASSERT(0); return IEEE154_TRANSACTION_OVERFLOW; } } @@ -737,34 +719,28 @@ implementation 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(); + ASSERT(0); // should never happen } - 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 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 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){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;} + 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;} } diff --git a/tos/lib/mac/tkn154/TKN154P.nc b/tos/lib/mac/tkn154/TKN154BeaconEnabledP.nc similarity index 78% rename from tos/lib/mac/tkn154/TKN154P.nc rename to tos/lib/mac/tkn154/TKN154BeaconEnabledP.nc index bcfdecc6..2f718b0c 100644 --- a/tos/lib/mac/tkn154/TKN154P.nc +++ b/tos/lib/mac/tkn154/TKN154BeaconEnabledP.nc @@ -36,18 +36,19 @@ #include "TKN154_PHY.h" #include "TKN154_MAC.h" #include "TKN154_PIB.h" -#include "TKN154_DEBUG.h" -configuration TKN154P +#define IEEE154_BEACON_ENABLED_PAN TRUE + +configuration TKN154BeaconEnabledP { provides { - // MCPS-SAP + /* MCPS-SAP */ interface MCPS_DATA; interface MCPS_PURGE; interface Packet; - // MLME-SAP + /* MLME-SAP */ interface MLME_ASSOCIATE; interface MLME_BEACON_NOTIFY; interface MLME_COMM_STATUS; @@ -78,6 +79,7 @@ configuration TKN154P interface RadioRx; interface RadioTx; interface RadioOff; + interface SlottedCsmaCa; interface EnergyDetection; interface SplitControl as PhySplitControl; interface Set as RadioPromiscuousMode; @@ -101,7 +103,6 @@ configuration TKN154P interface Timer as Timer4; interface Timer as Timer5; - interface Ieee802154Debug[uint8_t client]; interface LocalTime; interface Random; interface Leds; @@ -136,22 +137,22 @@ implementation #ifndef IEEE154_BEACON_SYNC_DISABLED BeaconSynchronizeP, new FrameDispatchQueueP() as DeviceCapQueue, - new FrameDispatchP(INCOMING_SUPERFRAME) as DeviceCap, + new SlottedFrameDispatchP(INCOMING_SUPERFRAME) as DeviceCap, #else NoBeaconSynchronizeP as BeaconSynchronizeP, new NoFrameDispatchQueueP() as DeviceCapQueue, - new NoFrameDispatchP(INCOMING_SUPERFRAME) as DeviceCap, + new NoSlottedFrameDispatchP(INCOMING_SUPERFRAME) as DeviceCap, #endif NoDeviceCfpP as DeviceCfp, #ifndef IEEE154_BEACON_TX_DISABLED BeaconTransmitP, new FrameDispatchQueueP() as CoordCapQueue, - new FrameDispatchP(OUTGOING_SUPERFRAME) as CoordCap, + new SlottedFrameDispatchP(OUTGOING_SUPERFRAME) as CoordCap, #else NoBeaconTransmitP as BeaconTransmitP, new NoFrameDispatchQueueP() as CoordCapQueue, - new NoFrameDispatchP(OUTGOING_SUPERFRAME) as CoordCap, + new NoSlottedFrameDispatchP(OUTGOING_SUPERFRAME) as CoordCap, #endif NoCoordCfpP as CoordCfp, @@ -188,11 +189,11 @@ implementation components MainC; - // MCPS + /* MCPS */ MCPS_DATA = DataP; MCPS_PURGE = DataP; - //MLME + /* MLME */ MLME_START = BeaconTransmitP; MLME_ASSOCIATE = AssociateP; MLME_DISASSOCIATE = DisassociateP; @@ -202,7 +203,7 @@ implementation MLME_COMM_STATUS = CoordRealignmentP; MLME_GET = PibP; MLME_ORPHAN = CoordRealignmentP; -/* MLME_GTS = CfpTransmitP;*/ + /* MLME_GTS = CfpTransmitP;*/ MLME_POLL = PollP; MLME_RESET = PibP; MLME_RX_ENABLE = RxEnableP; @@ -219,7 +220,7 @@ implementation TimeCalc = PibP; FrameUtility = PibP; -/* ----------------------- Scanning (MLME-SCAN) ----------------------- */ + /* ----------------------- Scanning (MLME-SCAN) ----------------------- */ components new RadioClientC() as ScanRadioClient; PibP.MacReset -> ScanP; @@ -235,19 +236,18 @@ implementation ScanP.TxFramePool -> TxFramePoolP; ScanP.TxControlPool -> TxControlPoolP; ScanP.Token -> ScanRadioClient; - ScanP.FrameUtility -> PibP; ScanP.Leds = Leds; + ScanP.FrameUtility -> PibP; -/* ----------------- Beacon Transmission (MLME-START) ----------------- */ + /* ----------------- 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.BeaconSendAlarm = Alarm1; BeaconTransmitP.BeaconPayloadUpdateTimer = Timer2; BeaconTransmitP.RadioOff -> BeaconTxRadioClient; - BeaconTransmitP.IsBeaconEnabledPAN -> PibP.IsBeaconEnabledPAN; BeaconTransmitP.BeaconTx -> BeaconTxRadioClient; BeaconTransmitP.MLME_SET -> PibP.MLME_SET; BeaconTransmitP.MLME_GET -> PibP; @@ -266,16 +266,14 @@ implementation BeaconTransmitP.PendingAddrWrite -> IndirectTxP.PendingAddrWrite; BeaconTransmitP.FrameUtility -> PibP.FrameUtility; BeaconTransmitP.IsTrackingBeacons -> BeaconSynchronizeP.IsTrackingBeacons; - BeaconTransmitP.LastBeaconRxRefTime -> BeaconSynchronizeP.CapStartRefTime; - BeaconTransmitP.LastBeaconRxTime -> BeaconSynchronizeP.CapStart; + BeaconTransmitP.IncomingSF -> BeaconSynchronizeP.IncomingSF; 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) ------------------ */ + /* ------------------ Beacon Tracking (MLME-SYNC) ------------------ */ components new RadioClientC() as SyncRadioClient; PibP.MacReset -> BeaconSynchronizeP; @@ -283,13 +281,10 @@ implementation 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; @@ -298,10 +293,9 @@ implementation 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) -------------------- */ + /* -------------------- Association (MLME-ASSOCIATE) -------------------- */ PibP.MacReset -> AssociateP; AssociateP.AssociationRequestRx -> CoordCap.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_ASSOCIATION_REQUEST]; @@ -317,9 +311,8 @@ implementation AssociateP.FrameUtility -> PibP; AssociateP.Frame -> PibP; AssociateP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress; - AssociateP.Debug = Ieee802154Debug[DEBUG_ASSOCIATE_ID]; -/* --------------- Disassociation (MLME-DISASSOCIATE) --------------- */ + /* --------------- Disassociation (MLME-DISASSOCIATE) --------------- */ PibP.MacReset -> DisassociateP; DisassociateP.DisassociationIndirectTx -> IndirectTxP.FrameTx[unique(INDIRECT_TX_CLIENT)]; @@ -337,18 +330,16 @@ implementation DisassociateP.FrameUtility -> PibP; DisassociateP.Frame -> PibP; DisassociateP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress; - DisassociateP.Debug = Ieee802154Debug[DEBUG_DISASSOCIATE_ID]; -/* ------------------ Data Transmission (MCPS-DATA) ------------------- */ + /* ------------------ 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.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; @@ -360,11 +351,10 @@ implementation DataP.PurgeGtsDevice -> DeviceCfp; DataP.PurgeGtsCoord -> CoordCfp; DataP.MLME_GET -> PibP; - DataP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress; DataP.Packet -> PibP; DataP.Leds = Leds; -/* ------------------------ Polling (MLME-POLL) ----------------------- */ + /* ------------------------ Polling (MLME-POLL) ----------------------- */ PibP.MacReset -> PollP; PollP.PollTx -> DeviceCapQueue.FrameTx[unique(CAP_TX_CLIENT)]; @@ -372,11 +362,10 @@ implementation 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 ----------------------- */ + /* ---------------------- Indirect transmission ----------------------- */ PibP.MacReset -> IndirectTxP; IndirectTxP.CoordCapTx -> CoordCapQueue.FrameTx[unique(CAP_TX_CLIENT)]; @@ -386,9 +375,8 @@ implementation IndirectTxP.IndirectTxTimeout = Timer4; IndirectTxP.TimeCalc -> PibP; IndirectTxP.Leds = Leds; - IndirectTxP.Debug = Ieee802154Debug[DEBUG_INDIRECTTX_ID]; -/* ---------------------------- Realignment --------------------------- */ + /* ---------------------------- Realignment --------------------------- */ PibP.MacReset -> CoordRealignmentP; CoordRealignmentP.CoordRealignmentTx -> CoordCapQueue.FrameTx[unique(CAP_TX_CLIENT)]; @@ -400,30 +388,30 @@ implementation CoordRealignmentP.MLME_GET -> PibP; CoordRealignmentP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress; -/* ---------------------------- Broadcasts ---------------------------- */ + /* ---------------------------- Broadcasts ---------------------------- */ components new RadioClientC() as CoordBroadcastRadioClient; PibP.MacReset -> CoordBroadcastP; CoordBroadcastP.TokenTransferred -> CoordBroadcastRadioClient; CoordBroadcastP.TokenToCap -> CoordBroadcastRadioClient; CoordBroadcastRadioClient.TransferTo -> CoordCapRadioClient.TransferFrom; - CoordBroadcastP.BeaconFramePendingBit -> BeaconTransmitP.BeaconFramePendingBit; + CoordBroadcastP.OutgoingSF -> BeaconTransmitP.OutgoingSF; CoordBroadcastP.CapTransmitNow -> CoordCap.BroadcastTx; CoordBroadcastP.Queue -> BroadcastQueueC; CoordBroadcastP.Leds = Leds; -/* --------------------- CAP (incoming superframe) -------------------- */ + /* --------------------- CAP (incoming superframe) -------------------- */ - PibP.CapQueueReset -> DeviceCapQueue; + PibP.FrameDispatchQueueReset -> DeviceCapQueue; DeviceCapQueue.Queue -> DeviceCapQueueC; DeviceCapQueue.FrameTxCsma -> DeviceCap; - PibP.CapQueueReset -> CoordCapQueue; + PibP.FrameDispatchQueueReset -> CoordCapQueue; CoordCapQueue.Queue -> CoordCapQueueC; CoordCapQueue.FrameTxCsma -> CoordCap; components new RadioClientC() as DeviceCapRadioClient; - PibP.CapReset -> DeviceCap; + PibP.FrameDispatchReset -> DeviceCap; DeviceCap.CapEndAlarm = Alarm3; DeviceCap.BLEAlarm = Alarm4; DeviceCap.IndirectTxWaitAlarm = Alarm5; @@ -432,75 +420,58 @@ implementation 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.SuperframeStructure -> BeaconSynchronizeP.IncomingSF; DeviceCap.IsRxEnableActive -> RxEnableP.IsRxEnableActive; DeviceCap.GetIndirectTxFrame -> IndirectTxP; DeviceCap.RxEnableStateChange -> RxEnableP.RxEnableStateChange; DeviceCap.IsTrackingBeacons -> BeaconSynchronizeP.IsTrackingBeacons; DeviceCap.FrameUtility -> PibP; - DeviceCap.RadioTx -> DeviceCapRadioClient; + DeviceCap.SlottedCsmaCa -> 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; + DeviceCap.TrackSingleBeacon -> BeaconSynchronizeP.TrackSingleBeacon; DeviceCapRadioClient.TransferTo -> DeviceCfpRadioClient.TransferFrom; -/* ---------------------- CAP (outgoing superframe) ------------------- */ + /* ---------------------- CAP (outgoing superframe) ------------------- */ components new RadioClientC() as CoordCapRadioClient, new BackupP(ieee154_cap_frame_backup_t); - PibP.CapReset -> CoordCap; + PibP.FrameDispatchReset -> 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.SuperframeStructure -> BeaconTransmitP.OutgoingSF; CoordCap.IsRxEnableActive -> RxEnableP.IsRxEnableActive; CoordCap.GetIndirectTxFrame -> IndirectTxP; CoordCap.RxEnableStateChange -> RxEnableP.RxEnableStateChange; CoordCap.IsTrackingBeacons -> BeaconSynchronizeP.IsTrackingBeacons; CoordCap.FrameUtility -> PibP; - CoordCap.RadioTx -> CoordCapRadioClient; + CoordCap.SlottedCsmaCa -> 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) --------------------- */ + /* -------------------- 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.IncomingSF -> BeaconSynchronizeP.IncomingSF; DeviceCfp.CfpSlotAlarm = Alarm9; DeviceCfp.CfpEndAlarm = Alarm10; DeviceCfp.RadioTx -> DeviceCfpRadioClient; @@ -510,19 +481,14 @@ implementation DeviceCfp.MLME_SET -> PibP.MLME_SET; DeviceCfpRadioClient.TransferTo -> SyncRadioClient.TransferFrom; -/* -------------------- GTS (outgoing superframe) --------------------- */ + /* -------------------- 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.OutgoingSF -> BeaconTransmitP.OutgoingSF; CoordCfp.CfpSlotAlarm = Alarm11; CoordCfp.CfpEndAlarm = Alarm12; CoordCfp.RadioTx -> CoordCfpRadioClient; @@ -532,7 +498,7 @@ implementation CoordCfp.MLME_SET -> PibP.MLME_SET; CoordCfpRadioClient.TransferTo -> BeaconTxRadioClient.TransferFrom; -/* -------------------------- promiscuous mode ------------------------ */ + /* -------------------------- promiscuous mode ------------------------ */ components new RadioClientC() as PromiscuousModeRadioClient; PibP.MacReset -> PromiscuousModeP; @@ -540,26 +506,20 @@ implementation PromiscuousModeP.PromiscuousRx -> PromiscuousModeRadioClient; PromiscuousModeP.RadioOff -> PromiscuousModeRadioClient; PromiscuousModeP.RadioPromiscuousMode = RadioPromiscuousMode; - PromiscuousModeP.Debug = Ieee802154Debug[DEBUG_PROMISCUOUSMODE_ID]; -/* --------------------------- MLME-RX-ENABLE ------------------------ */ + /* --------------------------- MLME-RX-ENABLE ------------------------ */ PibP.MacReset -> RxEnableP; - RxEnableP.IncomingSfStart -> BeaconSynchronizeP.CapStart; - RxEnableP.OutgoingSfStart -> BeaconTransmitP.CapStart; - RxEnableP.IncomingBeaconInterval -> BeaconSynchronizeP.BeaconInterval; - RxEnableP.OutgoingBeaconInterval -> BeaconTransmitP.BeaconInterval; + RxEnableP.IncomingSuperframeStructure -> BeaconSynchronizeP; + RxEnableP.OutgoingSuperframeStructure -> BeaconTransmitP; 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 -------------------------------- */ + /* ------------------------------- PIB -------------------------------- */ components new RadioClientC() as PibRadioClient; PIBUpdate = PibP; @@ -571,12 +531,12 @@ implementation PibP.Token -> PibRadioClient; PibP.RadioOff -> PibRadioClient; -/* ------------------------- Radio Control ---------------------------- */ + /* ------------------------- Radio Control ---------------------------- */ RadioControlP.PhyTx = RadioTx; + RadioControlP.PhySlottedCsmaCa = SlottedCsmaCa; RadioControlP.PhyRx = RadioRx; RadioControlP.PhyRadioOff = RadioOff; RadioControlP.RadioPromiscuousMode -> PromiscuousModeP; RadioControlP.Leds = Leds; - RadioControlP.Debug = Ieee802154Debug[DEBUG_RADIOCONTROL_ID]; } diff --git a/tos/lib/mac/tkn154/TKN154NonBeaconEnabledP.nc b/tos/lib/mac/tkn154/TKN154NonBeaconEnabledP.nc new file mode 100644 index 00000000..f5bc50a4 --- /dev/null +++ b/tos/lib/mac/tkn154/TKN154NonBeaconEnabledP.nc @@ -0,0 +1,341 @@ +/* + * 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 + * ======================================================================== + */ + +#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 as PIBUpdate[uint8_t attributeID]; + interface IEEE154Frame; + interface IEEE154BeaconFrame; + interface SplitControl as PromiscuousMode; + interface Get as GetLocalExtendedAddress; + interface TimeCalc; + interface FrameUtility; + + } uses { + + interface RadioRx; + interface RadioTx; + interface RadioOff; + interface UnslottedCsmaCa; + interface EnergyDetection; + interface SplitControl as PhySplitControl; + interface Set as RadioPromiscuousMode; + + interface Timer as Timer1; + interface Timer as Timer2; + interface Timer as Timer3; + interface Timer as Timer4; + interface Timer as Timer5; + + interface LocalTime; + 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; +} diff --git a/tos/lib/mac/tkn154/TKN154_DEBUG.h b/tos/lib/mac/tkn154/TKN154_DEBUG.h deleted file mode 100644 index 41bf8fdf..00000000 --- a/tos/lib/mac/tkn154/TKN154_DEBUG.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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 - * ======================================================================== - */ - -#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 diff --git a/tos/lib/mac/tkn154/TKN154_MAC.h b/tos/lib/mac/tkn154/TKN154_MAC.h index 6f1d3a90..64d6af06 100644 --- a/tos/lib/mac/tkn154/TKN154_MAC.h +++ b/tos/lib/mac/tkn154/TKN154_MAC.h @@ -37,6 +37,7 @@ #include "TKN154.h" #include "TKN154_PHY.h" +#include "TKN154_platform.h" /**************************************************** * IEEE 802.15.4 PAN information base identifiers @@ -74,9 +75,7 @@ enum { 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, @@ -89,7 +88,7 @@ enum { IEEE154_macTimestampSupported = 0x5C, IEEE154_macTransactionPersistenceTime = 0x55, -// attributes not present in the standard PIB: + // custom attributes (not present in the standard PIB) IEEE154_macPanCoordinator = 0xF0, }; @@ -128,6 +127,7 @@ enum { 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" @@ -139,6 +139,24 @@ enum { 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]; @@ -166,7 +184,7 @@ typedef struct 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 @@ -176,7 +194,7 @@ typedef struct ieee154_csma { typedef struct { ieee154_txframe_t *frame; - ieee154_csma_t csmaParams; + ieee154_csma_t csma; uint32_t transactionTime; } ieee154_cap_frame_backup_t; @@ -217,8 +235,8 @@ enum { // 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) @@ -240,5 +258,47 @@ enum { 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 diff --git a/tos/lib/mac/tkn154/TKN154_PIB.h b/tos/lib/mac/tkn154/TKN154_PIB.h index f90d6b02..896ef9df 100644 --- a/tos/lib/mac/tkn154/TKN154_PIB.h +++ b/tos/lib/mac/tkn154/TKN154_PIB.h @@ -41,11 +41,9 @@ */ -typedef struct ieee154_PIB_t { +typedef struct ieee154_PIB { - /**************/ - /* bool types */ - /**************/ + /** bool types */ // 0x41 ieee154_macAssociationPermit_t macAssociationPermit; @@ -63,11 +61,10 @@ typedef struct ieee154_PIB_t { 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; @@ -100,9 +97,7 @@ typedef struct ieee154_PIB_t { // 0x5a ieee154_macResponseWaitTime_t macResponseWaitTime; - /*****************************/ - /* larger than uint8_t types */ - /*****************************/ + /** larger than uint8_t types */ // 0x4B ieee154_macCoordShortAddress_t macCoordShortAddress; diff --git a/tos/lib/mac/tkn154/TransferClientP.nc b/tos/lib/mac/tkn154/TransferClientP.nc index 9273f001..305750ae 100644 --- a/tos/lib/mac/tkn154/TransferClientP.nc +++ b/tos/lib/mac/tkn154/TransferClientP.nc @@ -59,13 +59,13 @@ implementation 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() {} } diff --git a/tos/lib/mac/tkn154/UnslottedFrameDispatchP.nc b/tos/lib/mac/tkn154/UnslottedFrameDispatchP.nc new file mode 100644 index 00000000..a261dc39 --- /dev/null +++ b/tos/lib/mac/tkn154/UnslottedFrameDispatchP.nc @@ -0,0 +1,497 @@ +/* + * 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 + * ======================================================================== + */ + +#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 as WasRxEnabled; + } + uses + { + interface Timer as IndirectTxWaitTimer; + interface Resource as Token; + interface GetNow as IsTokenRequested; + interface GetNow as IsRxEnableActive; + interface Set as SetMacSuperframeOrder; + interface Set as SetMacPanCoordinator; + interface Get as GetIndirectTxFrame; + interface Notify 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) {} +} diff --git a/tos/lib/mac/tkn154/dummies/NoAssociateP.nc b/tos/lib/mac/tkn154/dummies/NoAssociateP.nc index aa4ac65e..3e469f53 100644 --- a/tos/lib/mac/tkn154/dummies/NoAssociateP.nc +++ b/tos/lib/mac/tkn154/dummies/NoAssociateP.nc @@ -33,6 +33,7 @@ * ======================================================================== */ + /** Empty placeholder component for AssociateP. */ #include "TKN154_MAC.h" @@ -60,7 +61,6 @@ module NoAssociateP interface FrameUtility; interface IEEE154Frame as Frame; interface Get as LocalExtendedAddress; - interface Ieee802154Debug as Debug; } } implementation @@ -68,7 +68,7 @@ implementation command error_t Init.init() { return SUCCESS; } -/* ------------------- MLME_ASSOCIATE Request ------------------- */ + /* ------------------- MLME_ASSOCIATE Request ------------------- */ command ieee154_status_t MLME_ASSOCIATE.request ( uint8_t LogicalChannel, @@ -91,7 +91,7 @@ implementation event void DataRequest.pollDone() { } -/* ------------------- MLME_ASSOCIATE Response ------------------- */ + /* ------------------- MLME_ASSOCIATE Response ------------------- */ event message_t* AssociationRequestRx.received(message_t* frame) { return frame; } @@ -107,7 +107,7 @@ implementation event void AssociationResponseTx.transmitDone(ieee154_txframe_t *txFrame, ieee154_status_t status) { } -/* ------------------- Defaults ------------------- */ + /* ------------------- Defaults ------------------- */ default event void MLME_ASSOCIATE.indication ( uint64_t DeviceAddress, diff --git a/tos/lib/mac/tkn154/dummies/NoBeaconSynchronizeP.nc b/tos/lib/mac/tkn154/dummies/NoBeaconSynchronizeP.nc index 5d49ff36..e1dee2c3 100644 --- a/tos/lib/mac/tkn154/dummies/NoBeaconSynchronizeP.nc +++ b/tos/lib/mac/tkn154/dummies/NoBeaconSynchronizeP.nc @@ -33,6 +33,7 @@ * ======================================================================== */ + /** Empty placeholder component for BeaconSynchronizeP. */ #include "TKN154_MAC.h" @@ -40,95 +41,87 @@ module NoBeaconSynchronizeP { provides { - interface Init; + interface Init as Reset; interface MLME_SYNC; interface MLME_BEACON_NOTIFY; interface MLME_SYNC_LOSS; + interface SuperframeStructure as IncomingSF; interface GetNow as IsTrackingBeacons; - interface Get as GetLastBeaconRxTime; - interface GetNow as CapStart; - interface GetNow as CapStartRefTime; - interface GetNow as CapLen; - interface GetNow as CapEnd; - interface GetNow as CfpEnd; - interface GetNow as CfpLen; - interface GetNow as BeaconInterval; - interface GetNow as IsBLEActive; - interface GetNow as BLELen; - interface GetNow as GtsField; - interface GetNow as SfSlotDuration; - interface GetNow as FinalCapSlot; - interface GetNow as NumGtsSlots; - interface GetNow as IsRxBroadcastPending; + interface StdControl as TrackSingleBeacon; } uses { interface MLME_GET; interface MLME_SET; interface FrameUtility; - interface Notify as FindBeacon; interface IEEE154BeaconFrame as BeaconFrame; interface Alarm as TrackAlarm; interface RadioRx as BeaconRx; interface RadioOff; - interface GetNow as IsBeaconEnabledPAN; interface DataRequest; interface FrameRx as CoordRealignmentRx; interface Resource as Token; interface GetNow as IsTokenRequested; - interface ResourceTransfer as TokenToCap; interface ResourceTransferred as TokenTransferred; - interface GetNow 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; } } diff --git a/tos/lib/mac/tkn154/dummies/NoBeaconTransmitP.nc b/tos/lib/mac/tkn154/dummies/NoBeaconTransmitP.nc index 7bed6f11..7d4a9f86 100644 --- a/tos/lib/mac/tkn154/dummies/NoBeaconTransmitP.nc +++ b/tos/lib/mac/tkn154/dummies/NoBeaconTransmitP.nc @@ -33,46 +33,33 @@ * ======================================================================== */ + /** 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 as IsSendingBeacons; - interface GetNow as CapStart; - interface GetNow as CapStartRefTime; - interface GetNow as CapLen; - interface GetNow as CapEnd; - interface GetNow as CfpEnd; - interface GetNow as CfpLen; - interface GetNow as IsBLEActive; - interface GetNow as BLELen; - interface GetNow as GtsField; - interface GetNow as SfSlotDuration; - interface GetNow as BeaconInterval; - interface GetNow as FinalCapSlot; - interface GetNow as NumGtsSlots; - interface GetNow as BeaconFramePendingBit; interface IEEE154TxBeaconPayload; + interface SuperframeStructure as OutgoingSF; + interface GetNow as IsSendingBeacons; } uses { interface Notify as GtsSpecUpdated; interface Notify as PendingAddrSpecUpdated; interface Notify as PIBUpdate[uint8_t attributeID]; - interface Alarm as BeaconTxAlarm; + interface Alarm as BeaconSendAlarm; interface Timer as BeaconPayloadUpdateTimer; interface RadioOff; - interface GetNow as IsBeaconEnabledPAN; interface RadioTx as BeaconTx; interface MLME_GET; interface MLME_SET; interface Resource as Token; - interface GetNow as IsTokenRequested; - interface ResourceTransfer as TokenToBroadcast; interface ResourceTransferred as TokenTransferred; + interface ResourceTransfer as TokenToBroadcast; + interface GetNow as IsTokenRequested; interface FrameTx as RealignmentBeaconEnabledTx; interface FrameTx as RealignmentNonBeaconEnabledTx; interface FrameRx as BeaconRequestRx; @@ -80,9 +67,7 @@ module NoBeaconTransmitP interface WriteBeaconField as PendingAddrWrite; interface FrameUtility; interface GetNow as IsTrackingBeacons; - interface GetNow as LastBeaconRxTime; - interface GetNow as LastBeaconRxRefTime; - interface Ieee802154Debug as Debug; + interface SuperframeStructure as IncomingSF; interface Set as SetMacSuperframeOrder; interface Set as SetMacBeaconTxTime; interface Set as SetMacPanCoordinator; @@ -94,10 +79,8 @@ module NoBeaconTransmitP } 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, @@ -120,17 +103,9 @@ implementation 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; } @@ -159,16 +134,6 @@ implementation { } - 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) { } @@ -182,43 +147,23 @@ implementation 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;} } diff --git a/tos/lib/mac/tkn154/dummies/NoCoordBroadcastP.nc b/tos/lib/mac/tkn154/dummies/NoCoordBroadcastP.nc index 2cf63e27..5ebf2b18 100644 --- a/tos/lib/mac/tkn154/dummies/NoCoordBroadcastP.nc +++ b/tos/lib/mac/tkn154/dummies/NoCoordBroadcastP.nc @@ -33,6 +33,8 @@ * ======================================================================== */ + /** Empty placeholder component for CoordBroadcastP. */ + #include "TKN154_MAC.h" module NoCoordBroadcastP { @@ -48,6 +50,7 @@ module NoCoordBroadcastP interface ResourceTransfer as TokenToCap; interface ResourceTransferred as TokenTransferred; interface GetNow as BeaconFramePendingBit; + interface SuperframeStructure as OutgoingSF; interface Leds; } } diff --git a/tos/lib/mac/tkn154/dummies/NoCoordCfpP.nc b/tos/lib/mac/tkn154/dummies/NoCoordCfpP.nc index 5ea62932..45497e6a 100644 --- a/tos/lib/mac/tkn154/dummies/NoCoordCfpP.nc +++ b/tos/lib/mac/tkn154/dummies/NoCoordCfpP.nc @@ -32,7 +32,7 @@ * @author Jan Hauer * ======================================================================== */ - + /** * 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 @@ -55,15 +55,9 @@ module NoCoordCfpP interface ResourceTransferred as TokenTransferred; interface ResourceTransfer as TokenToBeaconTransmit; interface ResourceRequested as TokenRequested; - interface GetNow as IsTokenRequested; - interface GetNow as IsTrackingBeacons; - interface GetNow as CfpEnd; - interface GetNow as CapStartRefTime; - interface GetNow as GtsField; - interface GetNow as SfSlotDuration; - interface GetNow as FinalCapSlot; interface Alarm as CfpSlotAlarm; interface Alarm as CfpEndAlarm; + interface SuperframeStructure as OutgoingSF; interface RadioTx; interface RadioRx; interface RadioOff; @@ -96,8 +90,6 @@ implementation // 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(); } @@ -123,11 +115,10 @@ implementation 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() { @@ -137,8 +128,4 @@ implementation } 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){} } diff --git a/tos/lib/mac/tkn154/dummies/NoCoordRealignmentP.nc b/tos/lib/mac/tkn154/dummies/NoCoordRealignmentP.nc index cbe178e9..fde191a6 100644 --- a/tos/lib/mac/tkn154/dummies/NoCoordRealignmentP.nc +++ b/tos/lib/mac/tkn154/dummies/NoCoordRealignmentP.nc @@ -33,6 +33,8 @@ * ======================================================================== */ + /** Empty placeholder component for CoordRealignmentP. */ + #include "TKN154_MAC.h" module NoCoordRealignmentP { diff --git a/tos/lib/mac/tkn154/dummies/NoDebugP.nc b/tos/lib/mac/tkn154/dummies/NoDebugP.nc deleted file mode 100644 index 229ae19f..00000000 --- a/tos/lib/mac/tkn154/dummies/NoDebugP.nc +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 - * ======================================================================== - */ -#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](){} -} diff --git a/tos/lib/mac/tkn154/dummies/NoDeviceCfpP.nc b/tos/lib/mac/tkn154/dummies/NoDeviceCfpP.nc index 0b3dfc79..9f6f87e6 100644 --- a/tos/lib/mac/tkn154/dummies/NoDeviceCfpP.nc +++ b/tos/lib/mac/tkn154/dummies/NoDeviceCfpP.nc @@ -54,14 +54,9 @@ module NoDeviceCfpP interface ResourceTransferred as TokenTransferred; interface ResourceRequested as TokenRequested; interface ResourceTransfer as TokenToBeaconSync; - interface GetNow as CapStartRefTime; - interface GetNow as IsSendingBeacons; - interface GetNow as CfpEnd; - interface GetNow as GtsField; - interface GetNow as SfSlotDuration; - interface GetNow as FinalCapSlot; interface Alarm as CfpSlotAlarm; interface Alarm as CfpEndAlarm; + interface SuperframeStructure as IncomingSF; interface RadioTx; interface RadioRx; interface RadioOff; @@ -94,8 +89,6 @@ implementation // 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(); } @@ -105,11 +98,9 @@ implementation 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() { @@ -119,9 +110,4 @@ implementation } 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){} } diff --git a/tos/lib/mac/tkn154/dummies/NoDisassociateP.nc b/tos/lib/mac/tkn154/dummies/NoDisassociateP.nc index 6b3b836f..12b8f340 100644 --- a/tos/lib/mac/tkn154/dummies/NoDisassociateP.nc +++ b/tos/lib/mac/tkn154/dummies/NoDisassociateP.nc @@ -33,6 +33,7 @@ * ======================================================================== */ + /** Empty placeholder component for DisassociateP. */ #include "TKN154_MAC.h" @@ -58,7 +59,6 @@ module NoDisassociateP interface FrameUtility; interface IEEE154Frame as Frame; interface Get as LocalExtendedAddress; - interface Ieee802154Debug as Debug; } } implementation @@ -66,7 +66,7 @@ implementation command error_t Init.init() { return SUCCESS; } -/* ------------------- MLME_DISASSOCIATE (initiating) ------------------- */ + /* ------------------- MLME_DISASSOCIATE (initiating) ------------------- */ command ieee154_status_t MLME_DISASSOCIATE.request ( uint8_t DeviceAddrMode, @@ -86,7 +86,7 @@ implementation 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; } @@ -95,7 +95,7 @@ implementation event message_t* DisassociationRxFromDevice.received(message_t* frame) { return frame; } -/* ------------------- Defaults ------------------- */ + /* ------------------- Defaults ------------------- */ default event void MLME_DISASSOCIATE.indication ( uint64_t DeviceAddress, diff --git a/tos/lib/mac/tkn154/dummies/NoFrameDispatchQueueP.nc b/tos/lib/mac/tkn154/dummies/NoFrameDispatchQueueP.nc index 54671cd0..890c816b 100644 --- a/tos/lib/mac/tkn154/dummies/NoFrameDispatchQueueP.nc +++ b/tos/lib/mac/tkn154/dummies/NoFrameDispatchQueueP.nc @@ -32,6 +32,9 @@ * @author Jan Hauer * ======================================================================== */ + + /** Empty placeholder component for FrameDispatchQueueP. */ + #include "TKN154_MAC.h" generic module NoFrameDispatchQueueP() { provides diff --git a/tos/lib/mac/tkn154/dummies/NoPromiscuousModeP.nc b/tos/lib/mac/tkn154/dummies/NoPromiscuousModeP.nc index 4ac6c850..40929940 100644 --- a/tos/lib/mac/tkn154/dummies/NoPromiscuousModeP.nc +++ b/tos/lib/mac/tkn154/dummies/NoPromiscuousModeP.nc @@ -33,6 +33,8 @@ * ======================================================================== */ + /** Empty placeholder component for PromiscuousModeP. */ + #include "TKN154_PHY.h" #include "TKN154_MAC.h" module NoPromiscuousModeP @@ -47,7 +49,6 @@ module NoPromiscuousModeP interface RadioRx as PromiscuousRx; interface RadioOff; interface Set as RadioPromiscuousMode; - interface Ieee802154Debug as Debug; } } implementation @@ -55,7 +56,7 @@ implementation command error_t Init.init() { return SUCCESS; } -/* ----------------------- Promiscuous Mode ----------------------- */ + /* ----------------------- Promiscuous Mode ----------------------- */ command bool PromiscuousModeGet.get() { return FALSE; } @@ -65,7 +66,7 @@ implementation 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; } diff --git a/tos/lib/mac/tkn154/dummies/NoRxEnableP.nc b/tos/lib/mac/tkn154/dummies/NoRxEnableP.nc index 63d76d82..69e3b3a8 100644 --- a/tos/lib/mac/tkn154/dummies/NoRxEnableP.nc +++ b/tos/lib/mac/tkn154/dummies/NoRxEnableP.nc @@ -33,6 +33,8 @@ * ======================================================================== */ + /** Empty placeholder component for RxEnableP. */ + #include "TKN154_PHY.h" #include "TKN154_MAC.h" module NoRxEnableP @@ -46,16 +48,12 @@ module NoRxEnableP } uses { - interface Ieee802154Debug as Debug; interface Timer as RxEnableTimer; - interface GetNow as IsBeaconEnabledPAN; interface Get as IsMacPanCoordinator; interface GetNow as IsTrackingBeacons; - interface GetNow as IncomingSfStart; - interface GetNow as IncomingBeaconInterval; interface GetNow as IsSendingBeacons; - interface GetNow as OutgoingSfStart; - interface GetNow as OutgoingBeaconInterval; + interface SuperframeStructure as IncomingSuperframeStructure; + interface SuperframeStructure as OutgoingSuperframeStructure; interface Notify as WasRxEnabled; interface TimeCalc; } @@ -65,7 +63,7 @@ implementation command error_t Init.init() { return SUCCESS; } -/* ----------------------- MLME-RX-ENABLE ----------------------- */ + /* ----------------------- MLME-RX-ENABLE ----------------------- */ command ieee154_status_t MLME_RX_ENABLE.request ( bool DeferPermit, diff --git a/tos/lib/mac/tkn154/dummies/NoScanP.nc b/tos/lib/mac/tkn154/dummies/NoScanP.nc index 2ff5a045..a2591add 100644 --- a/tos/lib/mac/tkn154/dummies/NoScanP.nc +++ b/tos/lib/mac/tkn154/dummies/NoScanP.nc @@ -33,6 +33,8 @@ * ======================================================================== */ + /** Empty placeholder component for ScanP. */ + #include "TKN154_MAC.h" module NoScanP @@ -88,23 +90,16 @@ implementation 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() { } diff --git a/tos/lib/mac/tkn154/dummies/NoFrameDispatchP.nc b/tos/lib/mac/tkn154/dummies/NoSlottedFrameDispatchP.nc similarity index 55% rename from tos/lib/mac/tkn154/dummies/NoFrameDispatchP.nc rename to tos/lib/mac/tkn154/dummies/NoSlottedFrameDispatchP.nc index eec51664..92b7cb0e 100644 --- a/tos/lib/mac/tkn154/dummies/NoFrameDispatchP.nc +++ b/tos/lib/mac/tkn154/dummies/NoSlottedFrameDispatchP.nc @@ -33,10 +33,12 @@ * ======================================================================== */ + /** Empty placeholder component for SlottedFrameDispatchP. */ + #include "TKN154_PHY.h" #include "TKN154_MAC.h" -generic module NoFrameDispatchP(uint8_t superframeDirection) +generic module NoSlottedFrameDispatchP(uint8_t superframeDirection) { provides { @@ -46,7 +48,6 @@ generic module NoFrameDispatchP(uint8_t superframeDirection) interface FrameExtracted as FrameExtracted[uint8_t frameType]; interface FrameTxNow as BroadcastTx; interface Notify as WasRxEnabled; - interface Notify as FindBeacon; } uses { @@ -58,109 +59,55 @@ generic module NoFrameDispatchP(uint8_t superframeDirection) interface GetNow as IsTokenRequested; interface ResourceTransfer as TokenToCfp; interface ResourceTransferred as TokenTransferred; - interface GetNow as CapStart; - interface GetNow as CapStartRefTime; - interface GetNow as CapLen; - interface GetNow as IsBLEActive; - interface GetNow as BLELen; - interface GetNow as IsRxBroadcastPending; + interface SuperframeStructure; interface GetNow as IsRxEnableActive; interface Get as GetIndirectTxFrame; interface Notify as RxEnableStateChange; interface GetNow as IsTrackingBeacons; interface FrameUtility; - interface RadioTx; + interface SlottedCsmaCa; interface RadioRx; interface RadioOff; - interface GetNow as IsBeaconEnabledPAN; interface MLME_GET; interface MLME_SET; - interface Ieee802154Debug as Debug; interface TimeCalc; interface Leds; interface SetNow as FrameBackup; interface GetNow as FrameRestore; + interface StdControl as TrackSingleBeacon; } } implementation { - command error_t Reset.init() - { - return SUCCESS; - } + command error_t Reset.init() { return SUCCESS; } - async event void TokenTransferred.transferred() - { - call TokenToCfp.transfer(); - } + async event void TokenTransferred.transferred() { } - command ieee154_status_t FrameTx.transmit(ieee154_txframe_t *frame) - { - return IEEE154_TRANSACTION_OVERFLOW; - } + 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 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 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){} + async event void SlottedCsmaCa.transmitDone(ieee154_txframe_t *frame, ieee154_csma_t *csma, + bool ackPendingFlag, uint16_t remainingBackoff, error_t result) { } - 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;} + event message_t* RadioRx.received(message_t* frame, const ieee154_timestamp_t *timestamp) { return frame; } - 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();} + async command ieee154_status_t BroadcastTx.transmitNow(ieee154_txframe_t *frame) { } - 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;} + event void Token.granted() { } 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;} } diff --git a/tos/lib/mac/tkn154/interfaces/MCPS/MCPS_DATA.nc b/tos/lib/mac/tkn154/interfaces/MCPS/MCPS_DATA.nc index 6c2cf76c..3cbe4725 100644 --- a/tos/lib/mac/tkn154/interfaces/MCPS/MCPS_DATA.nc +++ b/tos/lib/mac/tkn154/interfaces/MCPS/MCPS_DATA.nc @@ -33,6 +33,12 @@ * ======================================================================== */ +/** + * 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 @@ -40,17 +46,15 @@ interface MCPS_DATA { /** - * "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 (frame - * parameter) and can be accessed through the IEEE154Frame - * 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 frame, - * i.e. it must have been set (through the IEEE154Frame - * 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 frame and must have + * been set (through the IEEE154Frame 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 @@ -58,12 +62,12 @@ interface MCPS_DATA * * @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 confirm() event will be signalled; + * an appropriate error code otherwise * @see confirm */ @@ -75,14 +79,14 @@ interface MCPS_DATA ); /** - * 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 status + * is not IEEE154_SUCCESS) */ event void confirm ( message_t *frame, @@ -92,8 +96,9 @@ interface MCPS_DATA ); /** - * Indicates the arrival of a frame. Address information can be accessed - * through the IEEE154Frame interface. + * Indicates the arrival of a frame. Use the IEEE154Frame + * 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 */ diff --git a/tos/lib/mac/tkn154/interfaces/MCPS/MCPS_PURGE.nc b/tos/lib/mac/tkn154/interfaces/MCPS/MCPS_PURGE.nc index c598a15f..e8bc3fe7 100644 --- a/tos/lib/mac/tkn154/interfaces/MCPS/MCPS_PURGE.nc +++ b/tos/lib/mac/tkn154/interfaces/MCPS/MCPS_PURGE.nc @@ -33,17 +33,23 @@ * ======================================================================== */ +/** + * 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 */ diff --git a/tos/lib/mac/tkn154/interfaces/MLME/MLME_ASSOCIATE.nc b/tos/lib/mac/tkn154/interfaces/MLME/MLME_ASSOCIATE.nc index ce135fda..7e1c095a 100644 --- a/tos/lib/mac/tkn154/interfaces/MLME/MLME_ASSOCIATE.nc +++ b/tos/lib/mac/tkn154/interfaces/MLME/MLME_ASSOCIATE.nc @@ -33,6 +33,11 @@ * ======================================================================== */ +/** + * 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 { @@ -51,6 +56,7 @@ 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) @@ -67,7 +73,7 @@ interface MLME_ASSOCIATE { ); /** - * 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 @@ -82,7 +88,7 @@ interface MLME_ASSOCIATE { ); /** - * 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 @@ -90,9 +96,10 @@ interface MLME_ASSOCIATE { * @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 ( @@ -103,7 +110,7 @@ interface MLME_ASSOCIATE { ); /** - * Confirmation of the association attempt. + * Confirms an association attempt. * * @param AssocShortAddress The short device address allocated by the * coordinator on successful association diff --git a/tos/lib/mac/tkn154/interfaces/MLME/MLME_BEACON_NOTIFY.nc b/tos/lib/mac/tkn154/interfaces/MLME/MLME_BEACON_NOTIFY.nc index 3b9d9dd6..e014b56d 100644 --- a/tos/lib/mac/tkn154/interfaces/MLME/MLME_BEACON_NOTIFY.nc +++ b/tos/lib/mac/tkn154/interfaces/MLME/MLME_BEACON_NOTIFY.nc @@ -33,21 +33,29 @@ * ======================================================================== */ +/** + * 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 + 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 macAutoRequest is set to FALSE + * or the beacon payload is not empty. * - * The beacon parameters can be accessed through the - * IEEE154BeaconFrame<\tt> interface. The - * IEEE154Frame<\tt> interface can be used to - * inspect the addressing fields in the MAC header. + * The beacon parameters can be accessed through the + * IEEE154BeaconFrame interface. The IEEE154Frame + * 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 ); diff --git a/tos/lib/mac/tkn154/interfaces/MLME/MLME_COMM_STATUS.nc b/tos/lib/mac/tkn154/interfaces/MLME/MLME_COMM_STATUS.nc index e435e30c..ff8934ed 100644 --- a/tos/lib/mac/tkn154/interfaces/MLME/MLME_COMM_STATUS.nc +++ b/tos/lib/mac/tkn154/interfaces/MLME/MLME_COMM_STATUS.nc @@ -33,6 +33,14 @@ * ======================================================================== */ +/** + * 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 { diff --git a/tos/lib/mac/tkn154/interfaces/MLME/MLME_DISASSOCIATE.nc b/tos/lib/mac/tkn154/interfaces/MLME/MLME_DISASSOCIATE.nc index 9602ba3d..902b0f4e 100644 --- a/tos/lib/mac/tkn154/interfaces/MLME/MLME_DISASSOCIATE.nc +++ b/tos/lib/mac/tkn154/interfaces/MLME/MLME_DISASSOCIATE.nc @@ -33,11 +33,16 @@ * ======================================================================== */ +/** + * 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. @@ -50,6 +55,7 @@ interface MLME_DISASSOCIATE { * 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) @@ -65,7 +71,7 @@ interface MLME_DISASSOCIATE { ); /** - * 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 @@ -79,7 +85,7 @@ interface MLME_DISASSOCIATE { ); /** - * 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 diff --git a/tos/lib/mac/tkn154/interfaces/MLME/MLME_GET.nc b/tos/lib/mac/tkn154/interfaces/MLME/MLME_GET.nc index 29efcc3a..5cd117c5 100644 --- a/tos/lib/mac/tkn154/interfaces/MLME/MLME_GET.nc +++ b/tos/lib/mac/tkn154/interfaces/MLME/MLME_GET.nc @@ -33,16 +33,16 @@ * ======================================================================== */ -/** - * 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 IEEE154TxBeaconPayload <\tt> - * interface; for promiscuous mode there is a separate (SplitControl) - * interface. - **/ + * NOTE: for the attributes macBeaconPayload (0x45) and + * macBeaconPayloadLength (0x46) use the + * IEEE154TxBeaconPayload interface; for promiscuous mode + * there is a separate (SplitControl) interface. + */ #include "TKN154.h" interface MLME_GET { @@ -87,7 +87,7 @@ interface MLME_GET { command ieee154_macBattLifeExtPeriods_t macBattLifeExtPeriods(); /* macBeaconPayload (0x45) and macBeaconPayloadLength (0x46) are read - * through the IEEE154TxBeaconPayload<\tt> interface. */ + * through the IEEE154TxBeaconPayload interface. */ /** @return PIB attribute macBeaconOrder (0x47) */ command ieee154_macBeaconOrder_t macBeaconOrder(); @@ -163,4 +163,7 @@ interface MLME_GET { /** @return PIB attribute macMinSIFSPeriod */ command ieee154_macMinSIFSPeriod_t macMinSIFSPeriod(); + + /** @return custom attribute macPanCoordinator */ + command ieee154_macPanCoordinator_t macPanCoordinator(); } diff --git a/tos/lib/mac/tkn154/interfaces/MLME/MLME_GTS.nc b/tos/lib/mac/tkn154/interfaces/MLME/MLME_GTS.nc index d90bbe57..74b5426e 100644 --- a/tos/lib/mac/tkn154/interfaces/MLME/MLME_GTS.nc +++ b/tos/lib/mac/tkn154/interfaces/MLME/MLME_GTS.nc @@ -33,6 +33,13 @@ * ======================================================================== */ +/** + * 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 { diff --git a/tos/lib/mac/tkn154/interfaces/MLME/MLME_ORPHAN.nc b/tos/lib/mac/tkn154/interfaces/MLME/MLME_ORPHAN.nc index 5f9aca89..abc433e1 100644 --- a/tos/lib/mac/tkn154/interfaces/MLME/MLME_ORPHAN.nc +++ b/tos/lib/mac/tkn154/interfaces/MLME/MLME_ORPHAN.nc @@ -33,6 +33,12 @@ * ======================================================================== */ +/** + * 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 { diff --git a/tos/lib/mac/tkn154/interfaces/MLME/MLME_POLL.nc b/tos/lib/mac/tkn154/interfaces/MLME/MLME_POLL.nc index 77a801a7..ecd7cf4d 100644 --- a/tos/lib/mac/tkn154/interfaces/MLME/MLME_POLL.nc +++ b/tos/lib/mac/tkn154/interfaces/MLME/MLME_POLL.nc @@ -32,6 +32,12 @@ * @author Jan Hauer * ======================================================================== */ + +/** + * 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 { diff --git a/tos/lib/mac/tkn154/interfaces/MLME/MLME_RESET.nc b/tos/lib/mac/tkn154/interfaces/MLME/MLME_RESET.nc index 480a1b90..90aab473 100644 --- a/tos/lib/mac/tkn154/interfaces/MLME/MLME_RESET.nc +++ b/tos/lib/mac/tkn154/interfaces/MLME/MLME_RESET.nc @@ -33,16 +33,18 @@ * ======================================================================== */ +/** + * 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 PANType, 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 @@ -58,8 +60,6 @@ interface MLME_RESET { * 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 @@ -67,8 +67,7 @@ interface MLME_RESET { * */ command ieee154_status_t request ( - bool SetDefaultPIB, - uint8_t PANType + bool SetDefaultPIB ); /** diff --git a/tos/lib/mac/tkn154/interfaces/MLME/MLME_RX_ENABLE.nc b/tos/lib/mac/tkn154/interfaces/MLME/MLME_RX_ENABLE.nc index 7abdb3f6..ad880b2f 100644 --- a/tos/lib/mac/tkn154/interfaces/MLME/MLME_RX_ENABLE.nc +++ b/tos/lib/mac/tkn154/interfaces/MLME/MLME_RX_ENABLE.nc @@ -34,6 +34,12 @@ * ======================================================================== */ +/** + * 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 { diff --git a/tos/lib/mac/tkn154/interfaces/MLME/MLME_SCAN.nc b/tos/lib/mac/tkn154/interfaces/MLME/MLME_SCAN.nc index 551e35d6..a68b3cf3 100644 --- a/tos/lib/mac/tkn154/interfaces/MLME/MLME_SCAN.nc +++ b/tos/lib/mac/tkn154/interfaces/MLME/MLME_SCAN.nc @@ -33,6 +33,12 @@ * ======================================================================== */ +/** + * 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 { diff --git a/tos/lib/mac/tkn154/interfaces/MLME/MLME_SET.nc b/tos/lib/mac/tkn154/interfaces/MLME/MLME_SET.nc index 2935fc01..60572729 100644 --- a/tos/lib/mac/tkn154/interfaces/MLME/MLME_SET.nc +++ b/tos/lib/mac/tkn154/interfaces/MLME/MLME_SET.nc @@ -35,15 +35,15 @@ /** - * 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 IEEE154TxBeaconPayload <\tt> - * interface; for promiscuous mode there is a separate (SplitControl) - * interface. - **/ + * NOTE: for the attributes macBeaconPayload (0x45) and + * macBeaconPayloadLength (0x46) use the + * IEEE154TxBeaconPayload interface; for promiscuous mode + * there is a separate (SplitControl) interface. + */ #include "TKN154.h" interface MLME_SET { @@ -90,7 +90,7 @@ interface MLME_SET { command ieee154_status_t macBattLifeExtPeriods(ieee154_macBattLifeExtPeriods_t value); /* macBeaconPayload (0x45) and macBeaconPayloadLength (0x46) are set - * through the IEEE154TxBeaconPayload<\tt> interface. */ + * through the IEEE154TxBeaconPayload interface. */ /** @param value new PIB attribute value for macBeaconOrder (0x47) * @returns IEEE154_SUCCESS if PIB attribute was updated, INVALID_PARAMETER if @@ -138,7 +138,7 @@ interface MLME_SET { command ieee154_status_t macPANId(ieee154_macPANId_t value); /* macPromiscuousMode (0x51) is (re-)set through the - * PromiscuousMode<\tt> (SplitControl) interface. */ + * PromiscuousMode (SplitControl) interface. */ /** @param value new PIB attribute value for macRxOnWhenIdle (0x52) * @returns IEEE154_SUCCESS if PIB attribute was updated, INVALID_PARAMETER if diff --git a/tos/lib/mac/tkn154/interfaces/MLME/MLME_START.nc b/tos/lib/mac/tkn154/interfaces/MLME/MLME_START.nc index b5e44b25..b090ac3f 100644 --- a/tos/lib/mac/tkn154/interfaces/MLME/MLME_START.nc +++ b/tos/lib/mac/tkn154/interfaces/MLME/MLME_START.nc @@ -33,6 +33,14 @@ * ======================================================================== */ +/** + * 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 { diff --git a/tos/lib/mac/tkn154/interfaces/MLME/MLME_SYNC.nc b/tos/lib/mac/tkn154/interfaces/MLME/MLME_SYNC.nc index f10ab9f3..35f370bb 100644 --- a/tos/lib/mac/tkn154/interfaces/MLME/MLME_SYNC.nc +++ b/tos/lib/mac/tkn154/interfaces/MLME/MLME_SYNC.nc @@ -32,6 +32,14 @@ * @author Jan Hauer * ======================================================================== */ + +/** + * 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 { /** diff --git a/tos/lib/mac/tkn154/interfaces/MLME/MLME_SYNC_LOSS.nc b/tos/lib/mac/tkn154/interfaces/MLME/MLME_SYNC_LOSS.nc index 9266822b..4c0a1391 100644 --- a/tos/lib/mac/tkn154/interfaces/MLME/MLME_SYNC_LOSS.nc +++ b/tos/lib/mac/tkn154/interfaces/MLME/MLME_SYNC_LOSS.nc @@ -33,6 +33,13 @@ * ======================================================================== */ +/** + * 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 { diff --git a/tos/lib/mac/tkn154/interfaces/private/EnergyDetection.nc b/tos/lib/mac/tkn154/interfaces/private/EnergyDetection.nc index a3476cb2..a6a5b55c 100644 --- a/tos/lib/mac/tkn154/interfaces/private/EnergyDetection.nc +++ b/tos/lib/mac/tkn154/interfaces/private/EnergyDetection.nc @@ -49,12 +49,12 @@ interface EnergyDetection command error_t start(uint32_t duration); /** - * Signalled in response to a call to start<\tt>; + * Signalled in response to a call to start; * returns the maximum energy measured on the channel over the * specified period of time. * * @param status SUCCESS if the measurement succeeded - * and only then EnergyLevel<\tt> is valid, FAIL + * and only then EnergyLevel is valid, FAIL * otherwise * @param EnergyLevel The maximum energy on the channel **/ diff --git a/tos/lib/mac/tkn154/interfaces/private/FrameRx.nc b/tos/lib/mac/tkn154/interfaces/private/FrameRx.nc index 29fa071a..e3c0cfe7 100644 --- a/tos/lib/mac/tkn154/interfaces/private/FrameRx.nc +++ b/tos/lib/mac/tkn154/interfaces/private/FrameRx.nc @@ -34,8 +34,7 @@ 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 diff --git a/tos/lib/mac/tkn154/interfaces/private/FrameTx.nc b/tos/lib/mac/tkn154/interfaces/private/FrameTx.nc index 665d5543..458ddf93 100644 --- a/tos/lib/mac/tkn154/interfaces/private/FrameTx.nc +++ b/tos/lib/mac/tkn154/interfaces/private/FrameTx.nc @@ -34,7 +34,7 @@ interface FrameTx { /** - * Transmits a frame buffer. + * Transmits a frame. * * @param txFrame the frame to transmit * @return IEEE154_SUCCESS if the request was accepted and @@ -43,7 +43,7 @@ interface FrameTx 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 diff --git a/tos/lib/mac/tkn154/interfaces/private/FrameTxNow.nc b/tos/lib/mac/tkn154/interfaces/private/FrameTxNow.nc index beca22a1..7ac79658 100644 --- a/tos/lib/mac/tkn154/interfaces/private/FrameTxNow.nc +++ b/tos/lib/mac/tkn154/interfaces/private/FrameTxNow.nc @@ -34,7 +34,7 @@ interface FrameTxNow { /** - * Transmits a frame buffer. + * Transmits a frame. * * @param txFrame the frame to transmit * @return IEEE154_SUCCESS if the request was accepted and @@ -44,7 +44,7 @@ interface FrameTxNow /** - * 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 diff --git a/tos/lib/mac/tkn154/interfaces/private/RadioOff.nc b/tos/lib/mac/tkn154/interfaces/private/RadioOff.nc index 3405932c..1a110723 100644 --- a/tos/lib/mac/tkn154/interfaces/private/RadioOff.nc +++ b/tos/lib/mac/tkn154/interfaces/private/RadioOff.nc @@ -35,16 +35,14 @@ 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 offDone() - * 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(); @@ -56,6 +54,7 @@ interface RadioOff /** * 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(); diff --git a/tos/lib/mac/tkn154/interfaces/private/RadioRx.nc b/tos/lib/mac/tkn154/interfaces/private/RadioRx.nc index 597ab758..ec0bbb41 100644 --- a/tos/lib/mac/tkn154/interfaces/private/RadioRx.nc +++ b/tos/lib/mac/tkn154/interfaces/private/RadioRx.nc @@ -32,50 +32,42 @@ * @author Jan Hauer * ======================================================================== */ + #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 receive(). + * Switches the radio to receive mode at time t0 + dt or immediately + * if t0 + dt lies in the past. Analogous to the Timer + * interface t0 is interpreted as a time in the past. Consequently, + * if dt = 0 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 + * enableRxDone will be signalled. * - * @return SUCCESS if the command was accepted and prepareDone() - * 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 prepare(). 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 receive(). - **/ - 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 t0 + dt. If - * t0 is NULL, then the callee interprets t0 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 t0. * - * @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 + * enableRxDone() 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 enableRx(). This + * event is completing the enableRx() operation, the radio is now in + * the state RECEIVING. It will stay in receive mode until it is switched off + * through the RadioOff interface. Received frames will be signalled + * through the received() 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(); @@ -84,14 +76,19 @@ interface RadioRx * 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 + * IEEE154Frame.getTimestamp() 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); } diff --git a/tos/lib/mac/tkn154/interfaces/private/RadioTx.nc b/tos/lib/mac/tkn154/interfaces/private/RadioTx.nc index f5d45c89..37b8c0a9 100644 --- a/tos/lib/mac/tkn154/interfaces/private/RadioTx.nc +++ b/tos/lib/mac/tkn154/interfaces/private/RadioTx.nc @@ -33,184 +33,62 @@ * ======================================================================== */ #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 transmit(). Any - * frame that was previously prepared for transmission ("loaded") will be - * overwritten. The loadDone() event signals the completion of the - * load() command. - * - * The frame will be loaded (and the radio will stay in the state - * TX_LOADED) until either the transmission was successful, i.e. - * transmitDone() was signalled with a status IEEE154_SUCCESS, or - * the radio is switched off through the RadioOff - * 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 loadDone() will - * be signalled; FAIL otherwise - **/ - async command error_t load(ieee154_txframe_t *frame); - - /** - * Signalled in response to a successful call to load(). 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 transmit(). - **/ - 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 t0 + dt or immediately if t0 + + * dt lies in the past. The frame is transmitted in any case (without + * prior CCA). Analogous to the Timer interface t0 is + * interpreted as a time in the past. If t0 is NULL or if + * dt 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 load() at time t0+dt or immediately if - * t0 is NULL. In the first case the caller has to guarantee (through - * platform-specific guard times and by calling transmit in an - * atomic block) that the callee can start the transmission on time. - * The frame is transmitted without carrier sense (without CCA). - * The transmitDone() 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 t0. + * @param frame The frame to transmit * - * @return SUCCESS if the transmission was triggered successfully and only - * then transmitDone() 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 transmit() and completing the transmission. Depending on the - * error parameter the radio is now in the state RADIO_OFF - * (error == IEEE154_SUCCESS) or back in state TX_LOADED - * (error != IEEE154_SUCCESS). + * @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 load() 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 transmitUnslottedCsmaCaDone() 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 t0, ignored + * if t0 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 transmitDone() will be signalled; FAIL, if the command was + * not accepted, because the radio is currently not in the state RADIO_OFF; + * EINVAL if frame 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 transmitUnslottedCsmaCa(). - * Depending on the - * error parameter the radio is now in the state RADIO_OFF - * (error == IEEE154_SUCCESS) or still in state TX_LOADED - * (error != IEEE154_SUCCESS). 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 transmit() 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 timestamp. 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 load() 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 slot0Time+dtMax. The backoff slot boundaries - * are defined relative to slot0Time, if the resume - * then the initial backoff (in symbols) is passed as the initialBackoff parameter. * - * The transmitSlottedCsmaCaDone() 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 slot0Time+dtMax is the last time the frame may be transmitted. - * @param resume TRUE means that the initial backoff is defined by the - * initialBackoff parameter, FALSE means the initialBackoff - * 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 transmitSlottedCsmaCa(). - * Depending on the - * error parameter the radio is now in the state RADIO_OFF - * (error == IEEE154_SUCCESS) or still in state TX_LOADED - * (error != IEEE154_SUCCESS). 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 - * txTime 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 error == ERETRY, i.e. - * when the frame could not be transmitted because transmission would have - * started later than slot0Time+dtMax; then it - * specifies the remaining offset (in symbols) relative to slot0Time+dtMax, - * 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 + * IEEE154Frame.getTimestamp() 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 slot0Time+dtMax - */ - 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); } diff --git a/tos/lib/mac/tkn154/interfaces/private/SlottedCsmaCa.nc b/tos/lib/mac/tkn154/interfaces/private/SlottedCsmaCa.nc new file mode 100644 index 00000000..ed705542 --- /dev/null +++ b/tos/lib/mac/tkn154/interfaces/private/SlottedCsmaCa.nc @@ -0,0 +1,117 @@ +/* + * 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 + * ======================================================================== + */ +#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 csma until the transmitDone + * event has been signalled. + * + * slot0Time defines the beginning of the first slot in the CAP. + * Any transmission must commence on a backoff slot boundary relative to + * slot0Time. The last possible time for transmission is defined by + * slot0Time+dtMax. If the transmission cannot commence at or before + * slot0Time+dtMax then an event transmitDone() with error + * code ERETRY will be signalled and csma 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 + * remainingBackoff passed in the transmitDone() event, by + * setting resume to TRUE in the transmit() 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 slot0Time+dtMax is the last time the frame may be + * transmitted. + * + * @param resume TRUE means that the initial backoff is defined by the + * remainingBackoff parameter, FALSE means the + * remainingBackoff is to be ignored. + * + * @param remainingBackoff initial backoff (ignored if resume + * is FALSE. + * + * @return SUCCESS if the slotted CSMA-CA was triggered successfully; + * EINVAL if frame 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 transmit(). This event + * completes the transmit operation. A transmission failed if either + * the channel was never idle during any of the macMaxCsmaBackoffs+1 + * transmission attempts, if no acknowledgement was received although one was + * requested or if the frame could not be transmitted before the specified + * deadline (slot0Time+dtMax). + * + * @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 transmit 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 result = ERETRY, 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 + * slot0Time+dtMax + */ + async event void transmitDone(ieee154_txframe_t *frame, ieee154_csma_t *csma, + bool ackPendingFlag, uint16_t remainingBackoff, error_t result); +} diff --git a/tos/lib/mac/tkn154/interfaces/private/SuperframeStructure.nc b/tos/lib/mac/tkn154/interfaces/private/SuperframeStructure.nc new file mode 100644 index 00000000..08921600 --- /dev/null +++ b/tos/lib/mac/tkn154/interfaces/private/SuperframeStructure.nc @@ -0,0 +1,115 @@ +/* + * 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 + * ======================================================================== + */ + + /* 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(); +} diff --git a/tos/lib/mac/tkn154/interfaces/private/UnslottedCsmaCa.nc b/tos/lib/mac/tkn154/interfaces/private/UnslottedCsmaCa.nc new file mode 100644 index 00000000..765d9c57 --- /dev/null +++ b/tos/lib/mac/tkn154/interfaces/private/UnslottedCsmaCa.nc @@ -0,0 +1,90 @@ +/* + * 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 + * ======================================================================== + */ +#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 csma until the transmitDone 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 frame 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 transmit(). This event completes + * the transmit 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 transmit 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); +} diff --git a/tos/lib/mac/tkn154/interfaces/public/IEEE154BeaconFrame.nc b/tos/lib/mac/tkn154/interfaces/public/IEEE154BeaconFrame.nc index aae98efc..19a5a2c6 100644 --- a/tos/lib/mac/tkn154/interfaces/public/IEEE154BeaconFrame.nc +++ b/tos/lib/mac/tkn154/interfaces/public/IEEE154BeaconFrame.nc @@ -33,6 +33,10 @@ * ======================================================================== */ +/** + * The IEEE154BeaconFrame interface allows to access the content of a beacon + * frame. + */ #include diff --git a/tos/lib/mac/tkn154/interfaces/public/IEEE154Frame.nc b/tos/lib/mac/tkn154/interfaces/public/IEEE154Frame.nc index eaa1c3bf..1f3184c5 100644 --- a/tos/lib/mac/tkn154/interfaces/public/IEEE154Frame.nc +++ b/tos/lib/mac/tkn154/interfaces/public/IEEE154Frame.nc @@ -33,6 +33,10 @@ * ======================================================================== */ +/** + * The IEEE154Frame interface allows to access the content of a IEEE 802.15.4 + * frame. + */ #include #include @@ -157,7 +161,7 @@ interface IEEE154Frame /** * Returns the point in time when the frame was received. If - * isTimestampValid()<\tt> returns FALSE then the + * isTimestampValid() returns FALSE then the * timestamp is not valid and must be ignored. * * @param frame the frame @@ -192,7 +196,7 @@ interface IEEE154Frame * Returns the type of the frame * BEACON=0, DATA=1, ACK=2, COMMAND=3. * - * Note: For beacon frames one can use the IEEE154BeaconFrame<\tt> + * Note: For beacon frames one can use the IEEE154BeaconFrame * interface to inspect additional fields of the frame. * * @param frame the frame diff --git a/tos/lib/mac/tkn154/interfaces/public/IEEE154TxBeaconPayload.nc b/tos/lib/mac/tkn154/interfaces/public/IEEE154TxBeaconPayload.nc index bc42d77c..33768e3c 100644 --- a/tos/lib/mac/tkn154/interfaces/public/IEEE154TxBeaconPayload.nc +++ b/tos/lib/mac/tkn154/interfaces/public/IEEE154TxBeaconPayload.nc @@ -33,6 +33,12 @@ * ======================================================================== */ +/** + * 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 @@ -42,33 +48,33 @@ interface IEEE154TxBeaconPayload * 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 - * setBeaconPayloadDone()<\tt> event will be signalled when the - * beacon payload has been set -- until then beaconPayload<\tt> must + * setBeaconPayloadDone() event will be signalled when the + * beacon payload has been set -- until then beaconPayload 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 setBeaconPayloadDone<\tt> event + * SUCCESS otherwise (and only then the setBeaconPayloadDone event * will be signalled) */ command error_t setBeaconPayload(void *beaconPayload, uint8_t length); /** - * Signalled in response to a setBeaconPayload()<\tt> request. + * Signalled in response to a setBeaconPayload() request. * Indicates that the beacon payload has been copied and returns the * ownership of the buffer to the next higher layer. * - * @param beaconPayload the beaconPayload<\tt> passed in the - * setBeaconPayload()<\tt> command - * @param length the length<\tt> passed in the - * setBeaconPayload()<\tt> command + * @param beaconPayload the beaconPayload passed in the + * setBeaconPayload() command + * @param length the length passed in the + * setBeaconPayload() 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 */ @@ -84,31 +90,31 @@ interface IEEE154TxBeaconPayload /** * Replaces (overwrites) a portion of the current beacon payload. Whenever * possible, to minimize overhead, the next higher layer should prefer this - * command over the setBeaconPayload()<\tt> command. The - * modifyBeaconPayloadDone()<\tt> event will be signalled when the - * beacon payload has been updated -- until then buffer<\tt> must - * not be modified. + * command over the setBeaconPayload() command. The + * modifyBeaconPayloadDone() event will be signalled when the beacon + * payload has been updated -- until then buffer 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 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 + * modifyBeaconPayloadDone event will be signalled) */ command error_t modifyBeaconPayload(uint8_t offset, void *buffer, uint8_t bufferLength); /** - * Signalled in response to a modifyBeaconPayload()<\tt> request. + * Signalled in response to a modifyBeaconPayload() request. * Indicates that the beacon payload has been updated. * - * @param offset the offset<\tt> passed in the - * modifyBeaconPayload()<\tt> command - * @param buffer the buffer<\tt> passed in the - * modifyBeaconPayload()<\tt> command - * @param bufferLength the bufferLength<\tt> passed in the - * modifyBeaconPayload()<\tt> command + * @param offset the offset passed in the + * modifyBeaconPayload() command + * @param buffer the buffer passed in the + * modifyBeaconPayload() command + * @param bufferLength the bufferLength passed in the + * modifyBeaconPayload() command */ event void modifyBeaconPayloadDone(uint8_t offset, void *buffer, uint8_t bufferLength); @@ -117,8 +123,8 @@ interface IEEE154TxBeaconPayload * 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 setPayload<\tt> - * will update the beacon payload portion of this beacon. However, + * transmission, and (2) that a subsequent call to setPayload + * will still update the beacon payload portion of this beacon. However, * because of tight timing constraints in beacon-enabled mode neither can be * guaranteed! */ @@ -126,7 +132,7 @@ interface IEEE154TxBeaconPayload /** * Indicates that a beacon frame has been transmitted (the - * getBeaconPayload<\tt> command can be used to inspect the + * getBeaconPayload command can be used to inspect the * beacon payload). */ event void beaconTransmitted(); diff --git a/tos/platforms/telosb/mac/tkn154/Ieee802154BeaconEnabledC.nc b/tos/platforms/telosb/mac/tkn154/Ieee802154BeaconEnabledC.nc new file mode 100644 index 00000000..5f56c685 --- /dev/null +++ b/tos/platforms/telosb/mac/tkn154/Ieee802154BeaconEnabledC.nc @@ -0,0 +1,175 @@ +/* + * 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 + * ======================================================================== + */ +#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 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 +} diff --git a/tos/platforms/telosb/mac/tkn154/Ieee802154NonBeaconEnabledC.nc b/tos/platforms/telosb/mac/tkn154/Ieee802154NonBeaconEnabledC.nc new file mode 100644 index 00000000..892ef93d --- /dev/null +++ b/tos/platforms/telosb/mac/tkn154/Ieee802154NonBeaconEnabledC.nc @@ -0,0 +1,148 @@ +/* + * 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 + * ======================================================================== + */ +#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 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 +} diff --git a/tos/platforms/telosb/mac/tkn154/TKN154TimingP.nc b/tos/platforms/telosb/mac/tkn154/TKN154TimingP.nc index ceb71191..fe2782b7 100644 --- a/tos/platforms/telosb/mac/tkn154/TKN154TimingP.nc +++ b/tos/platforms/telosb/mac/tkn154/TKN154TimingP.nc @@ -35,8 +35,9 @@ /** * 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" @@ -46,6 +47,7 @@ module TKN154TimingP provides interface ReliableWait; provides interface ReferenceTime; uses interface TimeCalc; + uses interface GetNow as CCA; uses interface Alarm as SymbolAlarm; uses interface Leds; } @@ -59,14 +61,12 @@ implementation }; 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 { @@ -80,57 +80,51 @@ implementation 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() @@ -140,26 +134,18 @@ implementation 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; } } diff --git a/tos/platforms/telosb/mac/tkn154/TKN154_platform.h b/tos/platforms/telosb/mac/tkn154/TKN154_platform.h index cf5b1972..d9dadde5 100644 --- a/tos/platforms/telosb/mac/tkn154/TKN154_platform.h +++ b/tos/platforms/telosb/mac/tkn154/TKN154_platform.h @@ -38,36 +38,26 @@ /**************************************************** * 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 diff --git a/tos/platforms/telosb/mac/tkn154/platform_message.h b/tos/platforms/telosb/mac/tkn154/platform_message.h index bbff8982..5b76993f 100644 --- a/tos/platforms/telosb/mac/tkn154/platform_message.h +++ b/tos/platforms/telosb/mac/tkn154/platform_message.h @@ -11,7 +11,7 @@ #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 { @@ -21,9 +21,9 @@ 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 diff --git a/tos/platforms/telosb/mac/tkn154/timer/Alarm32khzTo62500hzTransformC.nc b/tos/platforms/telosb/mac/tkn154/timer/Alarm32khzTo62500hzTransformC.nc index 2af284dd..e6012855 100644 --- a/tos/platforms/telosb/mac/tkn154/timer/Alarm32khzTo62500hzTransformC.nc +++ b/tos/platforms/telosb/mac/tkn154/timer/Alarm32khzTo62500hzTransformC.nc @@ -40,15 +40,17 @@ module Alarm32khzTo62500hzTransformC } 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]();} -- 2.39.2