]> oss.titaniummirror.com Git - tinyos-2.x.git/commitdiff
+ modified radio driver (PHY) interfaces: CSMA-CA algorithm is now pushed to radio...
authorjanhauer <janhauer>
Tue, 25 Nov 2008 09:35:08 +0000 (09:35 +0000)
committerjanhauer <janhauer>
Tue, 25 Nov 2008 09:35:08 +0000 (09:35 +0000)
+ adapted CC2420 driver
+ renamed CsmaP -> FrameDispatchP
+ provided workaround for a problem with virtualized alarms (sometimes they seem to fire 2s too late)
+ updated placeholder components
+ updated debug information

54 files changed:
tos/chips/cc2420_tkn154/CC2420AsyncSplitControl.nc
tos/chips/cc2420_tkn154/CC2420ControlP.nc
tos/chips/cc2420_tkn154/CC2420ControlTransmitC.nc
tos/chips/cc2420_tkn154/CC2420Power.nc
tos/chips/cc2420_tkn154/CC2420ReceiveP.nc
tos/chips/cc2420_tkn154/CC2420SpiC.nc [new file with mode: 0644]
tos/chips/cc2420_tkn154/CC2420TKN154P.nc
tos/chips/cc2420_tkn154/CC2420TransmitP.nc
tos/chips/cc2420_tkn154/CC2420Tx.nc
tos/chips/cc2420_tkn154/ReliableWait.nc
tos/lib/mac/tkn154/AssociateP.nc
tos/lib/mac/tkn154/BeaconSynchronizeP.nc
tos/lib/mac/tkn154/BeaconTransmitP.nc
tos/lib/mac/tkn154/CsmaP.nc [deleted file]
tos/lib/mac/tkn154/CsmaQueueP.nc [deleted file]
tos/lib/mac/tkn154/DisassociateP.nc
tos/lib/mac/tkn154/FrameDispatchP.nc [new file with mode: 0644]
tos/lib/mac/tkn154/FrameDispatchQueueP.nc [new file with mode: 0644]
tos/lib/mac/tkn154/IndirectTxP.nc
tos/lib/mac/tkn154/PollP.nc
tos/lib/mac/tkn154/PromiscuousModeP.nc
tos/lib/mac/tkn154/RadioControlImplP.nc
tos/lib/mac/tkn154/ScanP.nc
tos/lib/mac/tkn154/TKN154P.nc
tos/lib/mac/tkn154/TKN154_DEBUG.h
tos/lib/mac/tkn154/TKN154_MAC.h
tos/lib/mac/tkn154/dummies/NoBeaconTransmitP.nc
tos/lib/mac/tkn154/dummies/NoCoordCfpP.nc
tos/lib/mac/tkn154/dummies/NoCsmaP.nc [deleted file]
tos/lib/mac/tkn154/dummies/NoCsmaQueueP.nc [deleted file]
tos/lib/mac/tkn154/dummies/NoDeviceCapQueueP.nc [deleted file]
tos/lib/mac/tkn154/dummies/NoDeviceCfpP.nc
tos/lib/mac/tkn154/dummies/NoFrameDispatchP.nc [new file with mode: 0644]
tos/lib/mac/tkn154/dummies/NoFrameDispatchQueueP.nc [new file with mode: 0644]
tos/lib/mac/tkn154/dummies/NoScanP.nc
tos/lib/mac/tkn154/interfaces/MCPS/MCPS_DATA.nc
tos/lib/mac/tkn154/interfaces/MLME/MLME_BEACON_NOTIFY.nc
tos/lib/mac/tkn154/interfaces/MLME/MLME_GET.nc
tos/lib/mac/tkn154/interfaces/MLME/MLME_SET.nc
tos/lib/mac/tkn154/interfaces/private/EnergyDetection.nc
tos/lib/mac/tkn154/interfaces/private/FrameTx.nc
tos/lib/mac/tkn154/interfaces/private/FrameTxNow.nc
tos/lib/mac/tkn154/interfaces/private/RadioOff.nc
tos/lib/mac/tkn154/interfaces/private/RadioRx.nc
tos/lib/mac/tkn154/interfaces/private/RadioTx.nc
tos/lib/mac/tkn154/interfaces/public/IEEE154Frame.nc
tos/lib/mac/tkn154/interfaces/public/IEEE154TxBeaconPayload.nc
tos/platforms/telosb/mac/tkn154/Ieee802154MacC.nc
tos/platforms/telosb/mac/tkn154/Makefile.include
tos/platforms/telosb/mac/tkn154/TKN154TimingP.nc
tos/platforms/telosb/mac/tkn154/TKN154_platform.h
tos/platforms/telosb/mac/tkn154/timer/Alarm32khzTo62500hzTransformC.nc
tos/platforms/telosb/mac/tkn154/timer/Alarm62500hz32C.nc [new file with mode: 0644]
tos/platforms/telosb/mac/tkn154/timer/Alarm62500hz32P.nc [new file with mode: 0644]

index 7688a55eaa13bfc927a1d84a35617b572238911e..edeebfe6bdf05dafa16e192ac5a789b2c44b3ea8 100644 (file)
  */
 
 /**
- * An async version of the SplitControl interface.
+ * This interface is a mixture of a SplitControl/AsyncStdControl interface.
  * @author Jan Hauer <hauer@tkn.tu-berlin.de>
  */
 
 interface CC2420AsyncSplitControl
 {
   /**
-   * Start this component and all of its subcomponents.  Return
-   * values of SUCCESS will always result in a <code>startDone()</code>
-   * event being signalled.
+   * Start this component and all of its subcomponents.  
    *
-   * @return SUCCESS if the device is already in the process of 
-   *         starting or the device was off and the device is now ready to turn 
-   *         on.  After receiving this return value, you should expect a 
-   *         <code>startDone</code> event in the near future.<br>
-   *         EBUSY if the component is in the middle of powering down
-   *               i.e. a <code>stop()</code> command has been called,
-   *               and a <code>stopDone()</code> event is pending<br>
-   *         EALREADY if the device is already on <br>
+   * @return SUCCESS if the component was started successfully.<br>
    *         FAIL Otherwise
    */
   async command error_t start();
 
-  /** 
-   * Notify caller that the component has been started and is ready to
-   * receive other commands.
-   *
-   * @param <b>error</b> -- SUCCESS if the component was successfully
-   *                        turned on, FAIL otherwise
-   */
-  async event void startDone(error_t error);
-
   /**
-   * Start this component and all of its subcomponents.  Return
-   * values of SUCCESS will always result in a <code>startDone()</code>
-   * event being signalled.
+   * Stop this component and all of its subcomponents - iff this command
+   * succeeds then <tt>stopDone</tt> will signal the result of the stop
+   * operation.
    *
-   * @return SUCCESS if the device is already in the process of 
-   *         stopping or the device was on and the device is now ready to turn 
-   *         off.  After receiving this return value, you should expect a 
-   *         <code>stopDone</code> event in the near future.<br>
-   *         EBUSY if the component is in the middle of powering up
-   *               i.e. a <code>start()</code> command has been called,
-   *               and a <code>startDone()</code> event is pending<br>
-   *         EALREADY if the device is already off <br>
-   *         FAIL Otherwise
+   * @return SUCCESS Stop operation was started, <tt>stopDone</tt> will be signalled
+   *         FAIL Otherwise (<tt>stopDone</tt> will not be signalled)
    */
   async command error_t stop();
 
   /**
-   * Notify caller that the component has been stopped.
+   * Notify caller that the component has been stopped. This event
+   * completes the <tt>stop()</tt> operation.
    *
   * @param <b>error</b> -- SUCCESS if the component was successfully
   *                        turned off, FAIL otherwise
index 64e4adf8f33f8b726fb867bf8266f4d32e99402b..6b8eac0df8130ce505c22c22c076e676d9725aaf 100644 (file)
@@ -33,7 +33,7 @@
  * @author Jonathan Hui <jhui@archrock.com>
  * @author David Moss
  * @author Urs Hunkeler (ReadRssi implementation)
- * @author Jan Hauer <hauer@tkn.tu-berlin.de> (support for promiscuous mode)
+ * @author Jan Hauer <hauer@tkn.tu-berlin.de>
  * @version $Revision$ $Date$
  */
 
@@ -53,6 +53,7 @@ module CC2420ControlP {
   uses interface GeneralIO as RSTN;
   uses interface GeneralIO as VREN;
   uses interface GpioInterrupt as InterruptCCA;
+  uses interface GeneralIO as FIFO;
 
   uses interface CC2420Ram as IEEEADR;
   uses interface CC2420Register as FSCTRL;
@@ -62,11 +63,14 @@ module CC2420ControlP {
   uses interface CC2420Register as MDMCTRL1;
   uses interface CC2420Register as RXCTRL1;
   uses interface CC2420Register as RSSI;
+  uses interface CC2420Register as RXFIFO_REGISTER;
+  uses interface CC2420Strobe as SNOP;
   uses interface CC2420Strobe as SRXON;
   uses interface CC2420Strobe as SRFOFF;
   uses interface CC2420Strobe as SXOSCOFF;
   uses interface CC2420Strobe as SXOSCON;
-  uses interface CC2420Strobe as SACKPEND; // JH: ACKs must have pending flag set
+  uses interface CC2420Strobe as SACKPEND;
+  uses interface CC2420Strobe as SFLUSHRX;
   uses interface CC2420Register as TXCTRL;
   uses interface AMPacket;
   
@@ -122,6 +126,12 @@ implementation {
   }
 
   /***************** Resource Commands ****************/
+  /* This module never actively requests the SPI resource,
+   * instead the caller MUST request the SPI through this module
+   * before it calls any of the provided commands and it must
+   * release it afterwards (the caller can call multiple  
+   * commands in this module before it releases the SPI, though).
+   */ 
   async command error_t Resource.immediateRequest() {
     error_t error = call SpiResource.immediateRequest();
     if ( error == SUCCESS ) {
@@ -145,6 +155,11 @@ implementation {
     }
   }
 
+  event void SpiResource.granted() {
+/*    call CSN.clr();*/
+    signal Resource.granted();
+  }
+
   void switchToUnbufferedMode()
   {
     uint16_t mdmctrol1;
@@ -179,7 +194,7 @@ implementation {
       m_state = S_VREG_STARTING;
     }
     call VREN.set();
-    call StartupAlarm.start( CC2420_TIME_VREN * 2 ); // JH: a 15.4 symbol is about two 32khz ticks
+    call StartupAlarm.start( CC2420_TIME_VREN * 2 ); // JH: changed from 32khz jiffies
     return SUCCESS;
   }
 
@@ -241,32 +256,52 @@ implementation {
 
   async command error_t CC2420Power.rxOn() {
     atomic {
-      if ( m_state != S_XOSC_STARTED ) {
+      if ( !call SpiResource.isOwner() )
         return FAIL;
-      }
       call CSN.set();
       call CSN.clr();
       call SRXON.strobe();
-      call SACKPEND.strobe();  // JH: ACKs have the pending bit set
+      call SACKPEND.strobe();  // JH: ACKs need the pending bit set
       call CSN.set();
     }
     return SUCCESS;
   }
 
   async command error_t CC2420Power.rfOff() {
-    atomic {  
-      if ( m_state != S_XOSC_STARTED ) {
+    atomic {
+      if ( !call SpiResource.isOwner() )
         return FAIL;
-      }
       call CSN.set();
       call CSN.clr();
-      call SACKPEND.strobe();  // JH: ACKs have the pending bit set
       call SRFOFF.strobe();
       call CSN.set();
     }
     return SUCCESS;
   }
 
+  async command error_t CC2420Power.flushRxFifo()
+  {
+    uint16_t dummy;
+    atomic {
+      if ( !call SpiResource.isOwner() )
+        return FAIL;
+      if ( call FIFO.get() ){ // check if there is something in the RXFIFO
+        // SFLUSHRX: "Flush the RX FIFO buffer and reset the demodulator. 
+        // 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 CSN.set();
+        call CSN.clr();
+        // "SFLUSHRX command strobe should be issued twice to ensure 
+        // that the SFD pin goes back to its idle state." (CC2420 Datasheet)
+        call SFLUSHRX.strobe();
+        call SFLUSHRX.strobe();
+        call CSN.set();
+      }
+    }
+    return SUCCESS;
+  }
   
   /***************** CC2420Config Commands ****************/
   command uint8_t CC2420Config.getChannel() {
@@ -367,13 +402,11 @@ implementation {
    * Sync must be called to commit software parameters configured on
    * the microcontroller (through the CC2420Config interface) to the
    * CC2420 radio chip.
-   * ASSUMPTION: caller owns the SPI, radio will be switched off !
    */
   async command error_t CC2420Config.sync() {
     atomic {
-      if ( m_state != S_XOSC_STARTED ) {
+      if ( !call SpiResource.isOwner() )
         return FAIL;
-      }
       if (m_needsSync){
         call CSN.set();
         call CSN.clr();
@@ -396,29 +429,30 @@ implementation {
   /***************** ReadRssi Commands ****************/
   
   async command error_t CC2420Power.rssi(int8_t *rssi) {
-    // we are owner of the Spi !
     uint16_t data;
     cc2420_status_t status;
-    call CSN.clr();
-    status = call RSSI.read(&data);
-    call CSN.set();
-    if ((status & 0x02)){
-      *rssi = (data & 0x00FF);
-      return SUCCESS;
-    } else
-      return FAIL;
-  }
-
-  event void SpiResource.granted() {
-/*    call CSN.clr();*/
-    signal Resource.granted();
+    atomic {
+      if ( !call SpiResource.isOwner() )
+        return FAIL;
+      call CSN.set();
+      call CSN.clr();
+      status = call RSSI.read(&data);
+      call CSN.set();
+      if ((status & 0x02)){
+        *rssi = (data & 0x00FF);
+        return SUCCESS;
+      } else
+        return FAIL;
+    }
   }
-
-
   
   /***************** StartupAlarm Events ****************/
   async event void StartupAlarm.fired() {
     if ( m_state == S_VREG_STARTING ) {
+      cc2420_status_t status;
+      do {
+       status = call SNOP.strobe();  
+      } while (!(status & CC2420_STATUS_XOSC16M_STABLE));
       m_state = S_VREG_STARTED;
       call RSTN.clr();
       call RSTN.set();
index 76f8568ea7a6f1cd3f71d1224a2155614be8a323..83aa7d3184d3656cddfa1ff794356f67b52104e3 100644 (file)
@@ -86,6 +86,7 @@ implementation {
   CC2420ControlP.CSN -> Pins.CSN;
   CC2420ControlP.RSTN -> Pins.RSTN;
   CC2420ControlP.VREN -> Pins.VREN;
+  CC2420ControlP.FIFO -> Pins.FIFO;
 
   components HplCC2420InterruptsC as Interrupts;
   CC2420ControlP.InterruptCCA -> Interrupts.InterruptCCA;
@@ -106,7 +107,10 @@ implementation {
   CC2420ControlP.TXCTRL      -> Spi.TXCTRL;
   CC2420ControlP.IEEEADR -> Spi.IEEEADR;
   CC2420ControlP.RXCTRL1 -> Spi.RXCTRL1;
+  CC2420ControlP.SFLUSHRX-> Spi.SFLUSHRX;
   CC2420ControlP.RSSI  -> Spi.RSSI;
+  CC2420ControlP.RXFIFO_REGISTER -> Spi.RXFIFO_REGISTER;
+  CC2420ControlP.SNOP -> Spi.SNOP;
 
   // CC2420TransmitC
   components CC2420TransmitP;
index a213f31d5d7a1c938a7122360ff7c05687d14d79..9d62b049fc6b1a9208e317b7e8b80923d9c00319 100644 (file)
@@ -102,4 +102,12 @@ interface CC2420Power {
    * @return SUCCESS if RSSI was read successfulyy, FAIL otherwise.
    */
   async command error_t rssi(int8_t *rssi);
+  /**
+   * Flush the RXFIFO if it is not empty. 
+   * Radio SHOULD be disabled (off) when calling this command.
+   *
+   * @return SUCCESS if fifo was flushed (or it was empty), FAIL otherwise.
+   */
+  async command error_t flushRxFifo(); 
 }
index 04860924a488ddde3f10208aa7eec13e79484eb1..4824d540597dffd1970ad9fdce793ebe22a3fa61 100644 (file)
@@ -42,7 +42,6 @@ module CC2420ReceiveP {
   provides interface CC2420AsyncSplitControl as AsyncSplitControl; 
   provides interface CC2420Receive;
   provides interface CC2420Rx;
-/*  provides interface ReceiveIndicator as PacketIndicator;*/
 
   uses interface GeneralIO as CSN;
   uses interface GeneralIO as FIFO;
@@ -54,13 +53,12 @@ module CC2420ReceiveP {
   uses interface CC2420Strobe as SACK;
   uses interface CC2420Strobe as SFLUSHRX;
   uses interface CC2420Strobe as SRXON;
-  uses interface CC2420Strobe as SACKPEND; // JH: ACKs must have pending flag set
+  uses interface CC2420Strobe as SACKPEND; 
   uses interface CC2420Register as MDMCTRL1;
   uses interface ReferenceTime;
   uses interface FrameUtility;
   uses interface CC2420Config;
-/*  uses interface CC2420Packet;*/
-/*  uses interface CC2420PacketBody;*/
+  uses interface CC2420Ram as RXFIFO_RAM;
   
   uses interface Leds;
 }
@@ -70,7 +68,6 @@ implementation {
   typedef enum {
     S_STOPPED,
     S_STARTING,
-    S_STARTING_FLUSHRX,
     S_STARTED,
     S_RX_LENGTH,
     S_RX_FCF,
@@ -125,7 +122,6 @@ implementation {
   void flush();
   void switchToUnbufferedMode();
   void switchToBufferedMode();
-  void startingSpiReserved();
   void continueStart();
   void continueStop();
   task void stopContinueTask();
@@ -139,79 +135,48 @@ implementation {
     return SUCCESS;
   }
 
-  /***************** AsyncSplitControl ****************
-   * IMPORTANT: when AsyncSplitControl.start is called, 
-   * the radio MUST be off !
+  /***************** AsyncSplitControl ****************/
+  /* NOTE: AsyncSplitControl does not switch the state of the radio 
+   * hardware (i.e. it does not put the radio in Rx mode, this has to
+   * be done by the caller through a separate interface/component). 
+   */
+
+  /** 
+   * AsyncSplitControl.start should be called before radio
+   * is switched to Rx mode (or at least early enough before
+   * a packet has been received, i.e. before FIFOP changes)
    */
   async command error_t AsyncSplitControl.start()
   {
     atomic {
+      if ( !call FIFO.get() && !call FIFOP.get() ){
+        // RXFIFO has some data (remember: FIFOP is inverted)
+        // the problem is that this messses up the timestamping
+        // so why don't we flush here ourselves? 
+        // because we don't own the SPI...
+        return FAIL; 
+      }
       if (m_state != S_STOPPED){
         call Leds.led0On();
         return FAIL;
-      } else {
-        m_state = S_STARTING;
-        if (call SpiResource.isOwner()){ 
-          call Leds.led0On(); // internal error (debug) !
-          startingSpiReserved();
-        }
-        if (call SpiResource.immediateRequest() == SUCCESS)
-          startingSpiReserved();
-        else
-          call SpiResource.request();        
       }
-    }
-    return SUCCESS;
-  }
-
-  void startingSpiReserved()
-  {
-    atomic {
-      if (!call FIFOP.get() || call FIFO.get()){ // FIFOP is inverted
-        // there is something in RXFIFO: flush it out 
-        // the datasheet says at least one byte should 
-        // be read before flushing
-        m_state = S_STARTING_FLUSHRX;
-        call CSN.set();
-        call CSN.clr();
-        call RXFIFO.beginRead( &m_dummy, 1 ); // will continue in continueFlushStart()
-        return;
-      }
-    }
-    continueStart();
-  }
-
-
-  void continueFlushStart()
-  {
-    atomic {
-      call CSN.set();
-      call CSN.clr();
-      call SFLUSHRX.strobe();
-      call SFLUSHRX.strobe();
-      call CSN.set();
-    }
-    continueStart();
-  }
-  
-  void continueStart()
-  {
-    // RXFIFO is empty
-    if (!call FIFOP.get() || call FIFO.get()){
-      call Leds.led0On();
-    }
-    atomic {
       reset_state();
       m_state = S_STARTED;
+      call InterruptFIFOP.enableFallingEdge(); // ready!
     }
-    call SpiResource.release();
-    call InterruptFIFOP.enableFallingEdge();
-    signal AsyncSplitControl.startDone(SUCCESS);
+    return SUCCESS;
   }
 
-  /***************** AsyncSplitControl ****************
+  /* AsyncSplitControl.stop:
+   *
    * IMPORTANT: when AsyncSplitControl.stop is called, 
-   * the radio MUST NOT be off !
+   * then either
+   * 1) the radio MUST still be in RxMode
+   * 2) it was never put in RxMode after  
+   *    AsyncSplitControl.start() was called
+   *
+   * => The radio may be switched off only *after* the
+   * stopDone() event was signalled.
    */
   async command error_t AsyncSplitControl.stop()
   {
@@ -222,9 +187,9 @@ implementation {
         m_stop = TRUE;
         call InterruptFIFOP.disable();
         if (!receivingPacket)
-          continueStop();
-        // else stopContinueTask will be posted after 
-        // current Rx operation is finished, because m_stop is set
+          continueStop(); // it is safe to stop now
+        // else continueStop will be called after 
+        // current Rx operation is finished
       }
     }
     return SUCCESS;
@@ -233,6 +198,9 @@ implementation {
   void continueStop()
   {
     atomic {
+      if (!m_stop){
+        return;
+      }
       m_stop = FALSE;
       m_state = S_STOPPED;
     }
@@ -241,9 +209,8 @@ implementation {
 
   task void stopContinueTask()
   {
-    if (receivingPacket){
+    if (receivingPacket)
       call Leds.led0On();
-    }
     call SpiResource.release(); // may fail
     atomic m_state = S_STOPPED;
     signal AsyncSplitControl.stopDone(SUCCESS);
@@ -314,10 +281,10 @@ implementation {
     atomic {
       switch (m_state)
       {
-        case S_STARTING: startingSpiReserved(); break;
-        case S_STARTING_FLUSHRX: // fall through
-        case S_STOPPED: call Leds.led0On(); 
-                        call SpiResource.release(); break;
+        case S_STOPPED: // this should never happen!
+                        call Leds.led0On(); 
+                        call SpiResource.release(); 
+                        break;
         default: receive();
       }
     }
@@ -471,8 +438,6 @@ implementation {
       waitForNextPacket();
       break;
 
-    case S_STARTING_FLUSHRX: continueFlushStart(); break;
-      
     default:
       atomic receivingPacket = FALSE;
       call CSN.set();
@@ -538,8 +503,7 @@ implementation {
    */
   void beginReceive() { 
     atomic {
-      if ( m_state == S_STOPPED){
-        call Leds.led0On();
+      if (m_state == S_STOPPED || m_stop){
         return;
       }
       m_state = S_RX_LENGTH;
@@ -591,11 +555,11 @@ implementation {
    */
   void waitForNextPacket() {
     atomic {
-      receivingPacket = FALSE;
       if ( m_state == S_STOPPED) {
         call SpiResource.release();
         return;
       }
+      receivingPacket = FALSE;
       if (m_stop){
         continueStop();
         return;
diff --git a/tos/chips/cc2420_tkn154/CC2420SpiC.nc b/tos/chips/cc2420_tkn154/CC2420SpiC.nc
new file mode 100644 (file)
index 0000000..7b7676c
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * 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 Arch Rock Corporation 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
+ * ARCHED ROCK OR ITS 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
+ */
+
+/**
+ * Implementation of basic SPI primitives for the ChipCon CC2420 radio.
+ *
+ * Jan Hauer: this component currently shadows 
+ * tinyos-2.x/tos/chips/cc2420/spi/CC2420SpiC.nc because the latter
+ * does not (yet) provide access to the RXFIFO via the CC2420Register
+ * interface. As soon as it does, this file should be removed.
+ *
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+generic configuration CC2420SpiC() {
+
+  provides interface Resource;
+  provides interface ChipSpiResource;
+
+  // commands
+  provides interface CC2420Strobe as SNOP;
+  provides interface CC2420Strobe as SXOSCON;
+  provides interface CC2420Strobe as STXCAL;
+  provides interface CC2420Strobe as SRXON;
+  provides interface CC2420Strobe as STXON;
+  provides interface CC2420Strobe as STXONCCA;
+  provides interface CC2420Strobe as SRFOFF;
+  provides interface CC2420Strobe as SXOSCOFF;
+  provides interface CC2420Strobe as SFLUSHRX;
+  provides interface CC2420Strobe as SFLUSHTX;
+  provides interface CC2420Strobe as SACK;
+  provides interface CC2420Strobe as SACKPEND;
+  provides interface CC2420Strobe as SRXDEC;
+  provides interface CC2420Strobe as STXENC;
+  provides interface CC2420Strobe as SAES;
+
+  // registers
+  provides interface CC2420Register as MAIN;
+  provides interface CC2420Register as MDMCTRL0;
+  provides interface CC2420Register as MDMCTRL1;
+  provides interface CC2420Register as RSSI;
+  provides interface CC2420Register as SYNCWORD;
+  provides interface CC2420Register as TXCTRL;
+  provides interface CC2420Register as RXCTRL0;
+  provides interface CC2420Register as RXCTRL1;
+  provides interface CC2420Register as FSCTRL;
+  provides interface CC2420Register as SECCTRL0;
+  provides interface CC2420Register as SECCTRL1;
+  provides interface CC2420Register as BATTMON;
+  provides interface CC2420Register as IOCFG0;
+  provides interface CC2420Register as IOCFG1;
+  provides interface CC2420Register as MANFIDL;
+  provides interface CC2420Register as MANFIDH;
+  provides interface CC2420Register as FSMTC;
+  provides interface CC2420Register as MANAND;
+  provides interface CC2420Register as MANOR;
+  provides interface CC2420Register as AGCCTRL;
+  provides interface CC2420Register as RXFIFO_REGISTER;
+
+  // ram
+  provides interface CC2420Ram as IEEEADR;
+  provides interface CC2420Ram as PANID;
+  provides interface CC2420Ram as SHORTADR;
+  provides interface CC2420Ram as TXFIFO_RAM;
+
+  // fifos
+  provides interface CC2420Fifo as RXFIFO;
+  provides interface CC2420Fifo as TXFIFO;
+
+}
+
+implementation {
+
+  enum {
+    CLIENT_ID = unique( "CC2420Spi.Resource" ),
+  };
+  
+  components HplCC2420PinsC as Pins;
+  components CC2420SpiWireC as Spi;
+  
+  ChipSpiResource = Spi.ChipSpiResource;
+  Resource = Spi.Resource[ CLIENT_ID ];
+  
+  // commands
+  SNOP = Spi.Strobe[ CC2420_SNOP ];
+  SXOSCON = Spi.Strobe[ CC2420_SXOSCON ];
+  STXCAL = Spi.Strobe[ CC2420_STXCAL ];
+  SRXON = Spi.Strobe[ CC2420_SRXON ];
+  STXON = Spi.Strobe[ CC2420_STXON ];
+  STXONCCA = Spi.Strobe[ CC2420_STXONCCA ];
+  SRFOFF = Spi.Strobe[ CC2420_SRFOFF ];
+  SXOSCOFF = Spi.Strobe[ CC2420_SXOSCOFF ];
+  SFLUSHRX = Spi.Strobe[ CC2420_SFLUSHRX ];
+  SFLUSHTX = Spi.Strobe[ CC2420_SFLUSHTX ];
+  SACK = Spi.Strobe[ CC2420_SACK ];
+  SACKPEND = Spi.Strobe[ CC2420_SACKPEND ];
+  SRXDEC = Spi.Strobe[ CC2420_SRXDEC ];
+  STXENC = Spi.Strobe[ CC2420_STXENC ];
+  SAES = Spi.Strobe[ CC2420_SAES ];
+  
+  // registers
+  MAIN = Spi.Reg[ CC2420_MAIN ];
+  MDMCTRL0 = Spi.Reg[ CC2420_MDMCTRL0 ];
+  MDMCTRL1 = Spi.Reg[ CC2420_MDMCTRL1 ];
+  RSSI = Spi.Reg[ CC2420_RSSI ];
+  SYNCWORD = Spi.Reg[ CC2420_SYNCWORD ];
+  TXCTRL = Spi.Reg[ CC2420_TXCTRL ];
+  RXCTRL0 = Spi.Reg[ CC2420_RXCTRL0 ];
+  RXCTRL1 = Spi.Reg[ CC2420_RXCTRL1 ];
+  FSCTRL = Spi.Reg[ CC2420_FSCTRL ];
+  SECCTRL0 = Spi.Reg[ CC2420_SECCTRL0 ];
+  SECCTRL1 = Spi.Reg[ CC2420_SECCTRL1 ];
+  BATTMON = Spi.Reg[ CC2420_BATTMON ];
+  IOCFG0 = Spi.Reg[ CC2420_IOCFG0 ];
+  IOCFG1 = Spi.Reg[ CC2420_IOCFG1 ];
+  MANFIDL = Spi.Reg[ CC2420_MANFIDL ];
+  MANFIDH = Spi.Reg[ CC2420_MANFIDH ];
+  FSMTC = Spi.Reg[ CC2420_FSMTC ];
+  MANAND = Spi.Reg[ CC2420_MANAND ];
+  MANOR = Spi.Reg[ CC2420_MANOR ];
+  AGCCTRL = Spi.Reg[ CC2420_AGCCTRL ];
+  RXFIFO_REGISTER = Spi.Reg[ CC2420_RXFIFO ];
+  
+  // ram
+  IEEEADR = Spi.Ram[ CC2420_RAM_IEEEADR ];
+  PANID = Spi.Ram[ CC2420_RAM_PANID ];
+  SHORTADR = Spi.Ram[ CC2420_RAM_SHORTADR ];
+  TXFIFO_RAM = Spi.Ram[ CC2420_RAM_TXFIFO ];
+
+  // fifos
+  RXFIFO = Spi.Fifo[ CC2420_RXFIFO ];
+  TXFIFO = Spi.Fifo[ CC2420_TXFIFO ];
+
+}
+
index 2546253eddd3f02c50205dc94ec298c5aa8fec80..73e0a7d7a1c04bc220948ccb144e4e9236b09240 100644 (file)
@@ -78,26 +78,30 @@ module CC2420TKN154P
 
     S_RESERVE_RX_SPI,
     S_RX_PREPARED,
+    S_RX_WAIT,
     S_RECEIVING,
     S_OFF_PENDING,
 
     S_LOAD_TXFIFO,
     S_TX_LOADED,
+    S_TX_WAIT,
     S_TX_ACTIVE,
     S_TX_CANCEL,
     S_TX_DONE,
   } m_state_t;
 
   norace m_state_t m_state = S_STOPPED;
-  norace ieee154_txframe_t *m_txdata;
+  norace ieee154_txframe_t *m_txframe;
   norace error_t m_txError;
   norace ieee154_reftime_t m_txReferenceTime;
   norace bool m_ackFramePending;
   uint32_t m_edDuration;
   bool m_pibUpdated;
-  uint8_t m_numCCA;
+  norace uint8_t m_numCCA;
   ieee154_reftime_t *m_t0Tx;
-  uint32_t m_dtTx;
+  uint32_t m_dtMax;
+  uint32_t m_dt;
+  norace ieee154_csma_t *m_csmaParams;
 
   norace uint8_t m_txLockOnCCAFail;
   norace bool m_rxAfterTx = FALSE;
@@ -112,34 +116,20 @@ module CC2420TKN154P
   void rxSpiReserved();
   void txSpiReserved();
   void txDoneSpiReserved();
-  void signalTxDone();
   void finishTx();
   void stopContinue();
   void offSpiReserved();
   void offStopRxDone();
-  void continueTxPrepare();
+  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);
   
 
-  /******************************/
-  /* StdControl Operations      */
-  /******************************/
-
-  /****************************************/
-  /*     TelosB Pin connection (debug)    */
-  /*                                      */
-  /* R1 = P6.6 = ADC6, R2 = P6.7 = ADC7   */
-  /* S1 = P2.3 = GIO2, S2 = P2.6 = GIO3   */
-  /* R1 is at 6pin-expansion pin 1,       */               
-  /* R2 is at 6pin-expansion pin 2,       */               
-  /****************************************/
+/* ----------------------- StdControl Operations ----------------------- */
 
   command error_t SplitControl.start()
   {
-    // debug
-    //P6SEL &= ~0xC0;     // debug PIN: 6.6, 6.7, set to I/O function
-    //P6DIR |= 0xC0;      // output
-    //P6OUT &= ~0xC0;     // low
-    
     atomic {
       if (m_state == S_RADIO_OFF)
         return EALREADY;
@@ -166,6 +156,7 @@ module CC2420TKN154P
   {
     // default configuration (addresses, etc) has been written
     call CC2420Power.rfOff();
+    call CC2420Power.flushRxFifo();
     call CC2420Tx.unlockChipSpi();
     post startDoneTask();
   }
@@ -203,10 +194,9 @@ module CC2420TKN154P
         m_state = S_STOPPING;
     }
     if (m_state != S_STOPPING)
-      post stopTask(); // this will not happen, because the caller has switched radio off
+      post stopTask(); // spin - this should not happen, because the caller has switched radio off
     else 
-      if (call RxControl.stop() == EALREADY)
-        stopContinue();
+      stopContinue();
   }
 
   void stopContinue()
@@ -219,19 +209,28 @@ module CC2420TKN154P
     // we own the SPI bus
     atomic {
       call CC2420Power.rfOff();
-      call CC2420Tx.unlockChipSpi();
-      call TxControl.stop();
+      call CC2420Power.flushRxFifo();
       call CC2420Power.stopOscillator(); 
       call CC2420Power.stopVReg();
+      call CC2420Tx.unlockChipSpi();
       call SpiResource.release();
       m_state  = S_STOPPED;
       signal SplitControl.stopDone(SUCCESS);
     }
   }
 
-  /*********************************/
-  /*  PIB Updates                  */
-  /*********************************/
+  uint16_t generateRandomBackoff(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;
+  }
+
+/* ----------------------- PIB Updates ----------------------- */
   
   // input: power in dBm, output: PA_LEVEL parameter for cc2420 TXCTRL register
   uint8_t dBmToPA_LEVEL(int dBm)
@@ -292,9 +291,7 @@ module CC2420TKN154P
     call CC2420Config.setPromiscuousMode(val);
   }
 
-  /*********************************/
-  /* Energy Detection              */
-  /*********************************/
+/* ----------------------- Energy Detection ----------------------- */
 
   command error_t EnergyDetection.start(uint32_t duration)
   {
@@ -319,7 +316,7 @@ module CC2420TKN154P
     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 BusyWait?)
+    // 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;
@@ -331,21 +328,33 @@ module CC2420TKN154P
     if (maxEnergy > -128)
       maxEnergy -= 45; 
     call CC2420Power.rfOff();
+    call CC2420Power.flushRxFifo();
     m_state = S_RADIO_OFF;
     call SpiResource.release();
     signal EnergyDetection.done(SUCCESS, maxEnergy);
   }
 
-  /****************************************/
-  /*     Transceiver Off                  */
-  /****************************************/
+/* ----------------------- Transceiver Off ----------------------- */
+
+  task void spinOffTask()
+  {
+    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();
+  }
 
   async command error_t RadioOff.off()
   {
     atomic {
       if (m_state == S_RADIO_OFF)
         return EALREADY;
-      else if (m_state != S_RECEIVING && m_state != S_TX_LOADED && m_state != S_RX_PREPARED)
+      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)
         return FAIL;
       m_state = S_OFF_PENDING;
     }
@@ -367,7 +376,7 @@ module CC2420TKN154P
   {
     call TxControl.stop();
     call CC2420Power.rfOff();
-    call CC2420Config.sync(); // put any PIB updates into operation
+    call CC2420Power.flushRxFifo();
     call CC2420Tx.unlockChipSpi();
     call SpiResource.release();
     m_state = S_RADIO_OFF;
@@ -379,9 +388,7 @@ module CC2420TKN154P
     return m_state == S_RADIO_OFF;
   }
 
-  /****************************************/
-  /*     Receive Operations               */
-  /****************************************/
+/* ----------------------- Receive Operations ----------------------- */
 
   async command error_t RadioRx.prepare()
   {
@@ -392,26 +399,24 @@ module CC2420TKN154P
         return FAIL;
       m_state = S_RESERVE_RX_SPI;
     }
-    if (call RxControl.start() != SUCCESS){  // will trigger rxStartRxDone()
+    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();
     }
     return SUCCESS; 
   }
 
-  void rxStartRxDone()
-  {
-    if (call SpiResource.immediateRequest() == SUCCESS)   // will trigger rxSpiReserved()
-      rxSpiReserved();
-    else
-      call SpiResource.request();
-  }
-
   void rxSpiReserved()
   {
     call CC2420Config.sync(); // put PIB changes into operation
-    call TxControl.start();   // for timestamping
+    call TxControl.stop();    
+    call TxControl.start();   // for timestamping (SFD interrupt)
     m_state = S_RX_PREPARED;
     signal RadioRx.prepareDone(); // keep owning the SPI
   }
@@ -428,8 +433,9 @@ module CC2420TKN154P
         call Leds.led0On();
         return FAIL;
       }
-      if (t0 != NULL && dt)
-        call ReliableWait.waitRx(t0, dt);
+      m_state = S_RX_WAIT;
+      if (t0 != NULL)
+        call ReliableWait.waitRx(t0, dt); // will signal waitRxDone() in time
       else
         signal ReliableWait.waitRxDone();
     }
@@ -447,12 +453,12 @@ module CC2420TKN154P
     call SpiResource.release();    
   }
 
-  event message_t* CC2420Rx.received(message_t *data, ieee154_reftime_t *timestamp) 
+  event message_t* CC2420Rx.received(message_t *frame, ieee154_reftime_t *timestamp) 
   {
     if (m_state == S_RECEIVING)
-      return signal RadioRx.received(data, timestamp);
+      return signal RadioRx.received(frame, timestamp);
     else
-      return data;
+      return frame;
   }
 
   async command bool RadioRx.isReceiving()
@@ -460,40 +466,28 @@ module CC2420TKN154P
     return m_state == S_RECEIVING;
   }
 
-  /******************************/
-  /*     Transmit Operations    */
-  /******************************/
+/* ----------------------- Transmit Operations ----------------------- */
 
   async command error_t RadioTx.load(ieee154_txframe_t *frame)
   {
-    bool startRxControl;
     atomic {
       if (m_state != S_RADIO_OFF && m_state != S_TX_LOADED)
         return FAIL;
-      startRxControl = (m_state == S_RADIO_OFF);
-      m_txdata = frame;
+      m_txframe = frame;
       m_state = S_LOAD_TXFIFO;
     }
-    if (!startRxControl)
-      continueTxPrepare();
-    else if (call RxControl.start() != SUCCESS) // will trigger continueTxPrepare()
-      call Leds.led0On();
-    return SUCCESS;
-  }
-
-  void continueTxPrepare()
-  {
-    if (call SpiResource.immediateRequest() == SUCCESS) 
+    if (call SpiResource.isOwner() || call SpiResource.immediateRequest() == SUCCESS) 
       txSpiReserved();
     else
       call SpiResource.request(); // will trigger txSpiReserved()
+    return SUCCESS;
   }
 
   void txSpiReserved()
   {
     call CC2420Config.sync();
     call TxControl.start();
-    if (call CC2420Tx.loadTXFIFO(m_txdata) != SUCCESS)
+    if (call CC2420Tx.loadTXFIFO(m_txframe) != SUCCESS)
       call Leds.led0On();
   }
 
@@ -508,80 +502,228 @@ module CC2420TKN154P
   async command ieee154_txframe_t* RadioTx.getLoadedFrame()
   {
     if (m_state == S_TX_LOADED)
-     return m_txdata;
+     return m_txframe;
     else 
       return NULL;
   }
 
-  async command error_t RadioTx.transmit(ieee154_reftime_t *t0, uint32_t dt, uint8_t numCCA, bool ackRequest)
+  async command error_t RadioTx.transmit(ieee154_reftime_t *t0, uint32_t dt)
+  {
+    // transmit without CCA
+    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
+        signal ReliableWait.waitTxDone();
+    }
+    return SUCCESS;
+  }
+
+  void checkEnableRxForACK()
+  {
+    // 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();
+    }
+  }
+
+  async event void ReliableWait.waitTxDone()
   {
+    atomic {
+      m_state = S_TX_ACTIVE;
+      if (call CC2420Tx.send(FALSE) == SUCCESS) // transmit without CCA, this must succeed
+        checkEnableRxForACK();
+      else
+        call Leds.led0On();
+    }
+  }
+
+  async command error_t RadioTx.transmitUnslottedCsmaCa(ieee154_csma_t *csmaParams)
+  {
+    // transmit with single CCA
     atomic {
       if (m_state != S_TX_LOADED)
         return FAIL;
-      m_numCCA = numCCA;
-      m_t0Tx = t0;
-      m_dtTx = dt;
-      if (numCCA){
-        // for CCA we need to be in Rx mode
-        call CC2420Power.rxOn();
-        call ReliableWait.busyWait(20); // turnaround + CCA valid time
-        if (numCCA == 2){
-          // first CCA is done in software (8 symbols after backoff boundary)
-          if (t0 != NULL){
-            call ReliableWait.waitCCA(t0, dt-IEEE154_aUnitBackoffPeriod-12);
-            return SUCCESS;
-          }
+      m_csmaParams = csmaParams;
+      m_numCCA = 1;
+      randomDelayUnslottedCsmaCa(); 
+    }
+    return SUCCESS;
+  }
+
+  void randomDelayUnslottedCsmaCa()
+  {
+    // 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); 
+  }
+
+  void waitBackoffUnslottedCsmaCaDone()
+  {
+    int8_t dummy;
+    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
+      call CC2420Power.rxOn();
+      m_state = S_TX_ACTIVE;
+      // 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){
+        checkEnableRxForACK();
+      } else {
+        // 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);
+        } 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();
         }
       }
-      signal ReliableWait.waitCCADone();
+    }
+  }
+
+  async command error_t RadioTx.transmitSlottedCsmaCa(ieee154_reftime_t *slot0Time, uint32_t dtMax, 
+      bool resume, uint16_t remainingBackoff, ieee154_csma_t *csmaParams)
+  {
+    // 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
+    atomic {
+      if (m_state != S_TX_LOADED)
+        return FAIL;
+      m_csmaParams = csmaParams;
+      m_numCCA = 2;
+      m_t0Tx = slot0Time;
+      m_dtMax = dtMax;
+      randomDelaySlottedCsmaCa(resume, remainingBackoff);
     }
     return SUCCESS;
   }
 
-  async event void ReliableWait.waitCCADone()
+  void randomDelaySlottedCsmaCa(bool resume, uint16_t remainingBackoff)
   {
-    bool cca = call CC2420Tx.cca();
-    if (m_numCCA == 2 && !cca){
-      // channel is busy
-      ieee154_reftime_t now;
-      call ReferenceTime.getNow(&now, IEEE154_aUnitBackoffPeriod+12);
-      memcpy(&m_txReferenceTime, &now, sizeof(ieee154_reftime_t));
-      m_ackFramePending = FALSE;
-      m_txError = EBUSY;
-      signalTxDone();
-      return;
-    } else {
-      // the second CCA (or first CCA if there's only one) is done in hardware...
-      uint16_t offset = 0;
-      if (m_numCCA)
-        offset = 12;
-      if (m_t0Tx)
-        call ReliableWait.waitTx(m_t0Tx, m_dtTx-offset);
+    uint16_t dtTx;
+    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
-        signal ReliableWait.waitTxDone();
+        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);
+      } else {
+        m_state = S_TX_WAIT;
+        call ReliableWait.waitBackoff(m_t0Tx, dtTx); 
+      }
     }
   }
 
-  async event void ReliableWait.waitTxDone()
+  void waitBackoffSlottedCsmaCaDone()
+  {
+    bool cca;
+    uint16_t dtTx=0;
+    int8_t dummy;
+    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
+      call CC2420Power.rxOn();
+      m_state = S_TX_ACTIVE;
+      // 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){
+          checkEnableRxForACK();
+          return;
+        } else
+          cca = FALSE;
+      }
+      // 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);
+        } 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);
+        }
+      }
+    }
+  }
+
+  async event void ReliableWait.waitBackoffDone()
   {
-    m_state = S_TX_ACTIVE;
-    call CC2420Tx.send(m_numCCA>0); // go (with or without CCA) !
+    if (m_numCCA == 1)
+      waitBackoffUnslottedCsmaCaDone();
+    else
+      waitBackoffSlottedCsmaCaDone();
   }
 
-  async event void CC2420Tx.transmissionStarted( ieee154_txframe_t *data )
+  async event void CC2420Tx.transmissionStarted( ieee154_txframe_t *frame )
   {
-    uint8_t frameType = data->header->mhr[0] & FC1_FRAMETYPE_MASK;
-    uint8_t token = data->headerLen;
-    signal Timestamp.transmissionStarted(frameType, data->handle, data->payload, token);
+    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 *data)
+  async event void CC2420Tx.transmittedSFD(uint32_t time, ieee154_txframe_t *frame)
   {
-    uint8_t frameType = data->header->mhr[0] & FC1_FRAMETYPE_MASK;
-    uint8_t token = data->headerLen;
-    signal Timestamp.transmittedSFD(time, frameType, data->handle, data->payload, token);
-    // ATTENTION: here we release the SPI, so we can receive a possible ACK
-    call SpiResource.release();
+    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 )
@@ -593,15 +735,18 @@ module CC2420TKN154P
   async event void CC2420Tx.sendDone(ieee154_txframe_t *frame, ieee154_reftime_t *referenceTime, 
       bool ackPendingFlag, error_t error)
   {
-    memcpy(&m_txReferenceTime, referenceTime, sizeof(ieee154_reftime_t));
-    m_ackFramePending = ackPendingFlag;
-    m_txError = error;
-    if (error == EBUSY) // CCA failure, i.e. didn't transmit
-      signalTxDone();
-    else 
-      // reset radio
+    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();
+    } else
+      sendDone(referenceTime, ackPendingFlag, error);
   }
 
   void txDoneRxControlStopped()
@@ -615,37 +760,43 @@ module CC2420TKN154P
 
   void txDoneSpiReserved() 
   { 
-    // switch radio off
-    call CC2420Power.rfOff(); 
-    call TxControl.stop();
-    call SpiResource.release(); // for RxControl.start to succeed
-    if (m_txError == SUCCESS)
-      signalTxDone();
-    else {
-      call TxControl.start();
-      call RxControl.start(); // will trigger txDoneRxControlStarted()
-    }
+    sendDone(&m_txReferenceTime, m_ackFramePending, m_txError);
   }
 
-  void txDoneRxControlStarted()
+  void sendDone(ieee154_reftime_t *referenceTime, bool ackPendingFlag, error_t error)
   {
-    m_state = S_TX_DONE;
-    call SpiResource.request(); // will trigger signalTxDone()
-  }
-
-  void signalTxDone() 
-  { 
-    // radio is off, Rx component is started, radio is loaded, we own the SPI
-    if (m_txError == SUCCESS)
+    uint8_t numCCA = m_numCCA;
+    // transmission complete, we're owning the SPI, Rx logic is disabled
+    call CC2420Power.rfOff();
+    call CC2420Power.flushRxFifo();
+    switch (error)
+    {
+       case SUCCESS:
+         m_state = S_RADIO_OFF;
+         break;
+       case ENOACK:
+         m_state = S_TX_LOADED;
+         break;
+       default: 
+         call Leds.led0On(); // internal error!
+         break;
+    }
+    if (error == SUCCESS){
+      call CC2420Tx.unlockChipSpi();
+      call TxControl.stop();
+      call SpiResource.release();
       m_state = S_RADIO_OFF;
-    else
+    else
       m_state = S_TX_LOADED;
-    signal RadioTx.transmitDone(m_txdata, &m_txReferenceTime, m_ackFramePending, m_txError);
+    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)
   {
@@ -659,7 +810,6 @@ module CC2420TKN154P
     switch (m_state)
     {
       case S_OFF_PENDING: offStopRxDone(); break;
-      case S_RX_PREPARED: rxStartRxDone(); break;
       case S_TX_ACTIVE: txDoneRxControlStopped(); break;
       case S_STOPPING: stopContinue(); break;            
       default: // huh ?
@@ -667,21 +817,7 @@ module CC2420TKN154P
     }
   }
 
-  async event void RxControl.startDone(error_t error)
-  {
-    switch (m_state)
-    {
-      case S_RESERVE_RX_SPI: rxStartRxDone(); break;
-      case S_LOAD_TXFIFO: continueTxPrepare(); break;
-      case S_TX_ACTIVE: txDoneRxControlStarted(); break;
-      default: // huh ?
-           call Leds.led0On(); break;
-    }
-  }
-
-  /***********************/
-  /* SPI Bus Arbitration */
-  /***********************/
+/* ----------------------- SPI Bus Arbitration ----------------------- */
 
   event void SpiResource.granted() 
   {
@@ -693,7 +829,6 @@ module CC2420TKN154P
       case S_LOAD_TXFIFO: txSpiReserved(); break;
       case S_TX_ACTIVE: txDoneSpiReserved(); break;
       case S_STOPPING: stopReserved(); break;
-      case S_TX_DONE: signalTxDone(); break;
       case S_OFF_PENDING: offSpiReserved(); break;
       default: // huh ?
            call Leds.led0On(); break;
index d746c854098e781a7849e1e647be7672e588ff94..87388ce9ae64c31767f6cd17795e8c3229587c83 100644 (file)
  * @author David Moss
  * @author Jung Il Choi Initial SACK implementation
  * @author Jan Hauer <hauer@tkn.tu-berlin.de>
+ *
+ * IMPORTANT: this module does not use the SPI Resource interface,
+ * instead the caller must take care of the resource arbitration
+ * (i.e. the caller must own the resource before calling commands
+ * like CC2420Tx.loadTXFIFO())
+ * Note: on TelosB there seems to be a problem if BackoffAlarm
+ * is virtualized - i.e. BackoffAlarm should be a dedicated Alarm.
+ *
  * @version $Revision$ $Date$
  */
 
@@ -45,21 +53,13 @@ module CC2420TransmitP {
 
   provides interface Init;
   provides interface AsyncStdControl;
-/*    interface CC2420Transmit;*/
   provides interface CC2420Tx;
-/*  provides interface RadioBackoff;*/
-/*  provides interface RadioTimeStamping as TimeStamp;*/
-/*  provides interface ReceiveIndicator as EnergyIndicator;*/
-/*  provides interface ReceiveIndicator as ByteIndicator;*/
-  
-/*  uses interface Alarm<T32khz,uint32_t> as BackoffAlarm;*/
   uses interface Alarm<T62500hz,uint32_t> as BackoffAlarm;
   uses interface GpioCapture as CaptureSFD;
   uses interface GeneralIO as CCA;
   uses interface GeneralIO as CSN;
   uses interface GeneralIO as SFD;
 
-/*  uses interface Resource as SpiResource;*/
   uses interface ChipSpiResource;
   uses interface CC2420Fifo as TXFIFO;
   uses interface CC2420Ram as TXFIFO_RAM;
@@ -71,7 +71,7 @@ module CC2420TransmitP {
   uses interface CC2420Strobe as SRXON;
   uses interface CC2420Strobe as SRFOFF;
   uses interface CC2420Strobe as SFLUSHRX;
-  uses interface CC2420Strobe as SACKPEND; // JH: ACKs must have pending flag set
+  uses interface CC2420Strobe as SACKPEND;
   uses interface CC2420Register as MDMCTRL1;
   uses interface CaptureTime;
   uses interface ReferenceTime;
@@ -86,25 +86,21 @@ implementation {
     S_STOPPED,
     S_STARTED,
     S_LOAD,
-    S_SAMPLE_CCA,
-    S_BEGIN_TRANSMIT,
+    S_READY_TX,
     S_SFD,
     S_EFD,
     S_ACK_WAIT,
-    S_CANCEL,
   } cc2420_transmit_state_t;
 
-  // This specifies how many jiffies the stack should wait after a
+  // This specifies how many symbols the stack should wait after a
   // TXACTIVE to receive an SFD interrupt before assuming something is
   // wrong and aborting the send. There seems to be a condition
   // on the micaZ where the SFD interrupt is never handled.
   enum {
-    CC2420_ABORT_PERIOD = 320
+    CC2420_ABORT_PERIOD = 320*3,
   };
   
-/*  norace message_t *m_msg;*/
-  norace ieee154_txframe_t *m_data;
-  norace uint8_t m_txFrameLen;
+  norace ieee154_txframe_t *m_frame;
   ieee154_reftime_t m_timestamp;
   
   cc2420_transmit_state_t m_state = S_STOPPED;
@@ -119,27 +115,16 @@ implementation {
   /** Let the CC2420 driver keep a lock on the SPI while waiting for an ack */
   norace bool abortSpiRelease;
   
-  /** Total CCA checks that showed no activity before the NoAck LPL send */
-  norace int8_t totalCcaChecks;
-  
   /** The initial backoff period */
   norace uint16_t myInitialBackoff;
   
   /** The congestion backoff period */
   norace uint16_t myCongestionBackoff;
+  norace uint32_t alarmStartTime;
   
 
   /***************** Prototypes ****************/
-  error_t load( ieee154_txframe_t *data );
-  error_t resend( bool cca );
-  void loadTXFIFO();
-  void attemptSend(bool cca);
-  void congestionBackoff();
-  error_t acquireSpiResource();
-  error_t releaseSpiResource();
-/*  void signalDone( error_t err );*/
   void signalDone( bool ackFramePending, error_t err );
-/*  void cancelTx();*/
   
   /***************** Init Commands *****************/
   command error_t Init.init() {
@@ -166,81 +151,90 @@ implementation {
       m_state = S_STOPPED;
       call BackoffAlarm.stop();
       call CaptureSFD.disable();
-/*      call SpiResource.release();  // REMOVE*/
       call CSN.set();
     }
     return SUCCESS;
   }
 
 
-  /**************** Send Commands ****************/
+  /**************** Load/Send Commands ****************/
 
-/*  async command error_t Send.send( message_t* p_msg, bool useCca ) {*/
-  async command error_t CC2420Tx.loadTXFIFO(ieee154_txframe_t *data) {
-    return load( data);
-  }
-
-  async command void CC2420Tx.send(bool cca)
+  async command error_t CC2420Tx.loadTXFIFO(ieee154_txframe_t *data) 
   {
-    attemptSend(cca);
-  }
-  
-  async command bool CC2420Tx.cca()
-  {
-    return call CCA.get();
-  }
-
-  async command error_t CC2420Tx.modify( uint8_t offset, uint8_t* buf, 
-                                     uint8_t len ) {
-    call CSN.set();
-    call CSN.clr();
-    call TXFIFO_RAM.write( offset, buf, len );
-    call CSN.set();
+    atomic {
+      if ( m_state != S_STARTED )
+        return FAIL;
+      m_state = S_LOAD;
+      m_frame = data;
+      m_frame->header->length = m_frame->headerLen + m_frame->payloadLen + 2; // 2 for CRC
+      call CSN.set();
+      call CSN.clr();
+      call SFLUSHTX.strobe(); // flush out anything that was in TXFIFO
+      call CSN.set();
+      call CSN.clr();
+      call TXFIFO.write( &(m_frame->header->length), 1 );
+    }
     return SUCCESS;
-  }
-  
-  async command void CC2420Tx.lockChipSpi()
+  }   
+
+  async event void TXFIFO.writeDone( uint8_t* tx_buf, uint8_t tx_len, error_t error) 
   {
-    abortSpiRelease = TRUE;
+    atomic {
+      call CSN.set();
+      if (tx_buf == &(m_frame->header->length)){
+        call CSN.clr();
+        call TXFIFO.write( m_frame->header->mhr, m_frame->headerLen );
+        return;
+      } else if (tx_buf == m_frame->header->mhr) {
+        call CSN.clr();
+        call TXFIFO.write( m_frame->payload, m_frame->payloadLen );
+        return;
+      }
+    }
+    m_state = S_READY_TX;
+    signal CC2420Tx.loadTXFIFODone(m_frame, error);
   }
-  async command void CC2420Tx.unlockChipSpi()
+
+  async command error_t CC2420Tx.send(bool cca)
   {
-    abortSpiRelease = FALSE;
-  }
+    cc2420_status_t status;
+    bool congestion = TRUE;
 
-  /***************** Indicator Commands ****************/
-/*  command bool EnergyIndicator.isReceiving() {*/
-/*    return !(call CCA.get());*/
-/*  }*/
-/*  */
-/*  command bool ByteIndicator.isReceiving() {*/
-/*    bool high;*/
-/*    atomic high = sfdHigh;*/
-/*    return high;*/
-/*  }*/
-  
+    atomic {
+      if (m_state != S_READY_TX)
+        return EOFF;
+      call CSN.set();
+      call CSN.clr();
 
-  /***************** RadioBackoff Commands ****************/
-  /**
-   * Must be called within a requestInitialBackoff event
-   * @param backoffTime the amount of time in some unspecified units to backoff
-   */
-/*  async command void RadioBackoff.setInitialBackoff(uint16_t backoffTime) {*/
-/*    myInitialBackoff = backoffTime + 1;*/
-/*  }*/
-  
-  /**
-   * Must be called within a requestCongestionBackoff event
-   * @param backoffTime the amount of time in some unspecified units to backoff
-   */
-/*  async command void RadioBackoff.setCongestionBackoff(uint16_t backoffTime) {*/
-/*    myCongestionBackoff = backoffTime + 1;*/
-/*  }*/
-  
-/*  async command void RadioBackoff.setCca(bool useCca) {*/
-/*  }*/
-  
-  
+      // DEBUG
+      //P2OUT |= 0x40;      // P2.6 high
+      status = cca ? call STXONCCA.strobe() : call STXON.strobe();
+      //status = call STXON.strobe();
+      //U0TXBUF = 0x04; // strobe STXON
+      //while (!(IFG1 & URXIFG0));
+      //status = U0RXBUF;
+      //call CSN.set();
+
+      if ( !( status & CC2420_STATUS_TX_ACTIVE ) ) {
+        status = call SNOP.strobe();
+        if ( status & CC2420_STATUS_TX_ACTIVE ) {
+          congestion = FALSE;
+        }
+      }
+      
+      call CSN.set();
+      // DEBUG: on telosb SFD is connected to Pin P4.1
+      //if (!congestion) {while (!(P4IN & 0x02)) ;  P6OUT &= ~0x80;}
+
+      if (congestion){
+        return FAIL; // channel busy
+      } else {
+        m_state = S_SFD;
+        call BackoffAlarm.start(CC2420_ABORT_PERIOD); 
+        return SUCCESS;
+      }
+    }
+  }
   
   /**
    * The CaptureSFD event is actually an interrupt from the capture pin
@@ -256,33 +250,18 @@ implementation {
    * would have picked up and executed had our microcontroller been fast enough.
    */
   async event void CaptureSFD.captured( uint16_t time ) {
-    // "time" is from TimerB capture, which is sourced by SMCLK (1MHz)
     //P2OUT &= ~0x40;      // debug: P2.6 low
-    uint32_t localTime;
     atomic {
       switch( m_state ) {
         
       case S_SFD:
         m_state = S_EFD;
         sfdHigh = TRUE;
-        call CaptureTime.convert(time, &m_timestamp, -8); // -8 for the preamble
         call CaptureSFD.captureFallingEdge();
-/*        signal TimeStamp.transmittedSFD( time, m_msg );*/
-        localTime = call ReferenceTime.toLocalTime(&m_timestamp);
-        signal CC2420Tx.transmittedSFD(localTime, m_data );
-        //if ( (call CC2420PacketBody.getHeader( m_msg ))->fcf & ( 1 << IEEE154_FCF_ACK_REQ ) ) {
-        //if ( (m_data->header)[0] & ( 1 << IEEE154_FCF_ACK_REQ ) ) {
-          // This is an ack packet, don't release the chip's SPI bus lock.
-        //}
-        releaseSpiResource();
+        // 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);
         call BackoffAlarm.stop();
-        m_data->metadata->timestamp = localTime;
-
-        
-/*        if ( ( ( (call CC2420PacketBody.getHeader( m_msg ))->fcf >> IEEE154_FCF_FRAME_TYPE ) & 7 ) == IEEE154_TYPE_DATA ) {*/
-/*          (call CC2420PacketBody.getMetadata( m_msg ))->time = time;*/
-/*        }*/
-        
         if ( call SFD.get() ) {
           break;
         }
@@ -291,11 +270,15 @@ implementation {
       case S_EFD:
         sfdHigh = FALSE;
         call CaptureSFD.captureRisingEdge();
-        
-/*        if ( (call CC2420PacketBody.getHeader( m_msg ))->fcf & ( 1 << IEEE154_FCF_ACK_REQ ) ) {*/
-        if ( (m_data->header->mhr)[0] & ( 1 << IEEE154_FCF_ACK_REQ ) ) {
+        signal CC2420Tx.transmissionStarted(m_frame);
+        if ( (m_frame->header->mhr)[0] & ( 1 << IEEE154_FCF_ACK_REQ ) ) {
+          // wait for the ACK
           m_state = S_ACK_WAIT;
-          call BackoffAlarm.start( 200 ); // we need to have *completely* received the ACK
+          alarmStartTime = call BackoffAlarm.getNow();
+          // we need to have *completely* received the ACK, 32+22 symbols
+          // should theroretically be enough, but there can be delays in 
+          // servicing the FIFOP interrupt, so we use 100 symbols here
+          call BackoffAlarm.start( 100 ); 
         } else {
           signalDone(FALSE, SUCCESS);
         }
@@ -309,8 +292,7 @@ implementation {
         if ( !m_receiving ) {
           sfdHigh = TRUE;
           call CaptureSFD.captureFallingEdge();
-/*          signal TimeStamp.receivedSFD( time );*/
-          call CaptureTime.convert(time, &m_timestamp, -8);
+          call CaptureTime.convert(time, &m_timestamp, -10);
           call CC2420Receive.sfd( &m_timestamp );
           m_receiving = TRUE;
           m_prev_time = time;
@@ -318,13 +300,13 @@ implementation {
             // wait for the next interrupt before moving on
             return;
           }
+          // if we move on, then the timestamp will be invalid!
         }
         
         sfdHigh = FALSE;
         call CaptureSFD.captureRisingEdge();
         m_receiving = FALSE;
-/*        if ( time - m_prev_time < 10 ) {*/
-#ifdef PIERCEBOARD_ENABLED
+#ifdef TKN154_PIERCEBOARD
         if ( time - m_prev_time < 10*30 ) {
 #else
         if ( time - m_prev_time < 10 ) {
@@ -336,8 +318,31 @@ implementation {
       }
     }
   }
+   
+  async command bool CC2420Tx.cca()
+  {
+    return call CCA.get();
+  }
+
+  async command error_t CC2420Tx.modify( uint8_t offset, uint8_t* buf, uint8_t len ) 
+  {
+    call CSN.set();
+    call CSN.clr();
+    call TXFIFO_RAM.write( offset, buf, len );
+    call CSN.set();
+    return SUCCESS;
+  }
+  
+  async command void CC2420Tx.lockChipSpi()
+  {
+    abortSpiRelease = TRUE;
+  }
+
+  async command void CC2420Tx.unlockChipSpi()
+  {
+    abortSpiRelease = FALSE;
+  }
 
-  /***************** ChipSpiResource Events ****************/
   async event void ChipSpiResource.releasing() {
     if(abortSpiRelease) {
       call ChipSpiResource.abortRelease();
@@ -351,392 +356,54 @@ implementation {
    * our send is complete.
    */
   async event void CC2420Receive.receive(  uint8_t type, message_t *ackFrame ){
-/*  async event void CC2420Receive.receive( uint8_t type, message_t* ack_msg ) {*/
-/*    cc2420_header_t* ack_header;*/
-/*    cc2420_header_t* msg_header;*/
-/*    cc2420_metadata_t* msg_metadata;*/
-/*    uint8_t* ack_buf;*/
-/*    uint8_t length;*/
-
     atomic {
       if ( type == IEEE154_TYPE_ACK ) {
-
-        /*      ack_header = call CC2420PacketBody.getHeader( ack_msg );*/
-        /*      msg_header = call CC2420PacketBody.getHeader( m_msg );*/
-
-        /*      if ( m_state == S_ACK_WAIT && msg_header->dsn == ack_header->dsn ) {*/
         if (  m_state == S_ACK_WAIT && 
-            m_data->header->mhr[2] == ((ieee154_header_t*) ackFrame->header)->mhr[2] ) { // compare seqno
+            m_frame->header->mhr[2] == ((ieee154_header_t*) ackFrame->header)->mhr[2] ) { // compare seqno
           call BackoffAlarm.stop();
-
-          /*        msg_metadata = call CC2420PacketBody.getMetadata( m_msg );*/
-          /*        ack_buf = (uint8_t *) ack_header;*/
-          /*        length = ack_header->length;*/
-          /*        */
-          /*        msg_metadata->ack = TRUE;*/
-          /*        msg_metadata->rssi = ack_buf[ length - 1 ];*/
-          /*        msg_metadata->lqi = ack_buf[ length ] & 0x7f;*/
           signalDone(( ((ieee154_header_t*) ackFrame->header)->mhr[0] & 0x10) ? TRUE: FALSE, SUCCESS);
         }
       }
     }
   }
-
-  /***************** SpiResource Events ****************/
-    /*
-  event void SpiResource.granted() {
-    uint8_t cur_state;
-
-    atomic {
-      cur_state = m_state;
-    }
-
-    switch( cur_state ) {
-    case S_LOAD:
-      loadTXFIFO();
-      break;
-      
-    case S_BEGIN_TRANSMIT:
-      attemptSend();
-      break;
-      
-    case S_CANCEL:
-      cancelTx();
-      break;
-      
-    default:
-      releaseSpiResource();
-      break;
-    }
-  }
-  */
   
-  /***************** TXFIFO Events ****************/
-  /**
-   * The TXFIFO is used to load packets into the transmit buffer on the
-   * chip
-   */
-  async event void TXFIFO.writeDone( uint8_t* tx_buf, uint8_t tx_len,
-                                     error_t error ) {
-
-    call CSN.set();
-    
-    if (tx_buf == &m_txFrameLen){
-      // until here: 1.65 ms
-      call CSN.clr();
-      call TXFIFO.write( m_data->header->mhr, m_data->headerLen );
-      return;
-    } else if (tx_buf == m_data->header->mhr) {
-      // until here: 2.2 ms
-      call CSN.clr();
-      call TXFIFO.write( m_data->payload, m_data->payloadLen );
-      return;
-    }
-    // until here: 4.6 ms (no DMA on USART0)
-    // until here: 3.3 ms (with DMA on USART0)
-    // P2OUT &= ~0x40;      // P2.1 low 
-    
-/*    if ( m_state == S_CANCEL ) {*/
-/*      atomic {*/
-/*        call CSN.clr();*/
-/*        call SFLUSHTX.strobe();*/
-/*        call CSN.set();*/
-/*      }*/
-/*      releaseSpiResource();*/
-/*      m_state = S_STARTED;*/
-            
-/*    } else if ( !m_cca ) {*/
-/*    } else  {*/
-      m_state = S_BEGIN_TRANSMIT;
-      releaseSpiResource();
-      signal CC2420Tx.loadTXFIFODone(m_data, error);
-/*      attemptSend();*/
-/*    }*/
-
-/*    } else {*/
-/*      releaseSpiResource();*/
-/*      atomic {*/
-/*        if (m_state == S_LOAD_CANCEL) {*/
-/*          m_state = S_CCA_CANCEL;*/
-/*        } else {*/
-/*          m_state = S_SAMPLE_CCA;*/
-/*        }*/
-/*      }*/
-/*      signal CC2420Tx.loadTXFIFODone(m_data, error);*/
-      
-/*      signal RadioBackoff.requestInitialBackoff(m_msg);*/
-/*      call BackoffAlarm.start(myInitialBackoff);*/
-/*    }*/
-  }
-
-  
-  async event void TXFIFO.readDone( uint8_t* tx_buf, uint8_t tx_len, 
-      error_t error ) {
-  }
-  
-  
-  /***************** Timer Events ****************/
-  /**
-   * The backoff timer is mainly used to wait for a moment before trying
-   * to send a packet again. But we also use it to timeout the wait for
-   * an acknowledgement, and timeout the wait for an SFD interrupt when
-   * we should have gotten one.
-   */
   async event void BackoffAlarm.fired() {
     atomic {
       switch( m_state ) {
-        
-      case S_SAMPLE_CCA : 
-        // sample CCA and wait a little longer if free, just in case we
-        // sampled during the ack turn-around window
-        if ( call CCA.get() ) {
-          m_state = S_BEGIN_TRANSMIT;
-          call BackoffAlarm.start( CC2420_TIME_ACK_TURNAROUND );
-          
-        } else {
-          congestionBackoff();
-        }
-        break;
-        
-      case S_BEGIN_TRANSMIT:
-      case S_CANCEL:
-        // should never happen
-        call Leds.led0On();
-/*        if ( acquireSpiResource() == SUCCESS ) {*/
-/*          attemptSend();*/
-/*        }*/
-        break;
-        
-      case S_ACK_WAIT:
-/*        signalDone( SUCCESS );*/
-        signalDone( FALSE, FAIL );
-        break;
-
-      case S_SFD:
-        // We didn't receive an SFD interrupt within CC2420_ABORT_PERIOD
-        // jiffies. Assume something is wrong.
-        atomic {
-          call CSN.set();
-          call CSN.clr();
-          call SFLUSHTX.strobe();
-          call CSN.set();
-        }
-        signalDone( FALSE, ERETRY );
-        releaseSpiResource();
-        //call CaptureSFD.captureRisingEdge();
-        break;
-
-      default:
-        break;
-      }
-    }
-  }
-
-  /***************** Functions ****************/
-  /**
-   * Set up a message to be sent. First load it into the outbound tx buffer
-   * on the chip, then attempt to send it.
-   * @param *p_msg Pointer to the message that needs to be sent
-   * @param cca TRUE if this transmit should use clear channel assessment
-   */
-  error_t load( ieee154_txframe_t *data) {
-    atomic {
-      if (m_state == S_CANCEL) {
-        return ECANCEL;
-      }
-      
-      if ( m_state != S_STARTED ) {
-        return FAIL;
-      }
-      
-      m_state = S_LOAD;
-/*      m_msg = p_msg;*/
-      m_data = data;
-      totalCcaChecks = 0;
-    }
-    
-    if ( acquireSpiResource() == SUCCESS ) {
-      loadTXFIFO();
-    }
-
-    return SUCCESS;
-  }
-  
-  /**
-   * Resend a packet that already exists in the outbound tx buffer on the
-   * chip
-   * @param cca TRUE if this transmit should use clear channel assessment
-   */
-/*  error_t resend( bool cca ) {*/
-
-/*    atomic {*/
-/*      if (m_state == S_LOAD_CANCEL*/
-/*          || m_state == S_CCA_CANCEL*/
-/*          || m_state == S_TX_CANCEL) {*/
-/*        return ECANCEL;*/
-/*      }*/
-/*      */
-/*      if ( m_state != S_STARTED ) {*/
-/*        return FAIL;*/
-/*      }*/
-/*      */
-/*      m_cca = cca;*/
-/*      m_state = cca ? S_SAMPLE_CCA : S_BEGIN_TRANSMIT;*/
-/*      totalCcaChecks = 0;*/
-/*    }*/
-/*    */
-/*    if(m_cca) {*/
-/*      signal RadioBackoff.requestInitialBackoff(m_msg);*/
-/*      call BackoffAlarm.start( myInitialBackoff );*/
-/*      */
-/*    } else if ( acquireSpiResource() == SUCCESS ) {*/
-/*      attemptSend();*/
-/*    }*/
-/*    */
-/*    return SUCCESS;*/
-/*  }*/
-  
-  /**
-   * Attempt to send the packet we have loaded into the tx buffer on 
-   * the radio chip.  The STXONCCA will send the packet immediately if
-   * the channel is clear.  If we're not concerned about whether or not
-   * the channel is clear (i.e. m_cca == FALSE), then STXON will send the
-   * packet without checking for a clear channel.
-   *
-   * If the packet didn't get sent, then congestion == TRUE.  In that case,
-   * we reset the backoff timer and try again in a moment.
-   *
-   * If the packet got sent, we should expect an SFD interrupt to take
-   * over, signifying the packet is getting sent.
-   */
-  void attemptSend(bool cca) {
-    uint8_t status;
-    bool congestion = TRUE;
 
-    atomic {
-      call CSN.set();
-      call CSN.clr();
+        case S_SFD:
+        case S_EFD: // fall through
+          // We didn't receive an SFD interrupt within CC2420_ABORT_PERIOD
+          // jiffies. Assume something is wrong.
+          atomic {
+            call CSN.set();
+            call CSN.clr();
+            call SFLUSHTX.strobe();
+            call CSN.set();
+          }
+          signalDone( FALSE, ERETRY );
+          break;
 
-      // STXONCCA costs about ? symbols, i.e. attemptSend should be called
-      // ? symbols, before the actual CCA
-      //P2OUT |= 0x40;      // P2.6 high
-      status = cca ? call STXONCCA.strobe() : call STXON.strobe();
-      //status = call STXON.strobe();
-      //U0TXBUF = 0x04; // strobe STXON
-      //while (!(IFG1 & URXIFG0));
-      //status = U0RXBUF;
-      //call CSN.set();
+        case S_ACK_WAIT:
+          /*        signalDone( SUCCESS );*/
+          signalDone( FALSE, ENOACK );
+          break;
 
-      if ( !( status & CC2420_STATUS_TX_ACTIVE ) ) {
-        status = call SNOP.strobe();
-        if ( status & CC2420_STATUS_TX_ACTIVE ) {
-          congestion = FALSE;
-        }
-      }
-      
-      call CSN.set();
-      // debug: on telosb SFD is connected to Pin P4.1
-      if (!congestion) {while (!(P4IN & 0x02)) ;  P6OUT &= ~0x80;}
 
-      if (congestion){
-        call ReferenceTime.getNow(&m_timestamp, 0);
-        m_state = S_BEGIN_TRANSMIT; // don't use a state S_SAMPLE_CCA
-        releaseSpiResource();
-        signal CC2420Tx.sendDone(m_data, &m_timestamp, FALSE, EBUSY); // waiting for the next send()
-      } else {
-        m_state = S_SFD; // wait for an ACK
-        signal CC2420Tx.transmissionStarted(m_data);
-        call BackoffAlarm.start(CC2420_ABORT_PERIOD*3);
+        default:
+          break;
       }
-      return; // we still own the SPI, either we wait for an ACK or resend is going to be called soon
     }
-    
-/*    if ( congestion ) {*/
-/*      totalCcaChecks = 0;*/
-/*      releaseSpiResource();*/
-/*      congestionBackoff();*/
-/*    } else {*/
-/*      call BackoffAlarm.start(CC2420_ABORT_PERIOD);*/
-/*    }*/
   }
-  
-  /**  
-   * Congestion Backoff
-   */
-  void congestionBackoff() {
-    atomic {
-/*      signal RadioBackoff.requestCongestionBackoff(m_msg);*/
-      call BackoffAlarm.start(myCongestionBackoff);
-    }
-  }
-  
-  error_t acquireSpiResource() {
-    return SUCCESS;
-    /*
-    error_t error = call SpiResource.immediateRequest();
-    if ( error != SUCCESS ) {
-      call SpiResource.request();
-    }
-    return error;
-    */
-  }
-
-  error_t releaseSpiResource() {
-    //call SpiResource.release();
-    return SUCCESS;
-  }
-
-
-  /** 
-   * Setup the packet transmission power and load the tx fifo buffer on
-   * the chip with our outbound packet.  
-   *
-   * Warning: the tx_power metadata might not be initialized and
-   * could be a value other than 0 on boot.  Verification is needed here
-   * to make sure the value won't overstep its bounds in the TXCTRL register
-   * and is transmitting at max power by default.
-   *
-   * It should be possible to manually calculate the packet's CRC here and
-   * tack it onto the end of the header + payload when loading into the TXFIFO,
-   * so the continuous modulation low power listening strategy will continually
-   * deliver valid packets.  This would increase receive reliability for
-   * mobile nodes and lossy connections.  The crcByte() function should use
-   * the same CRC polynomial as the CC2420's AUTOCRC functionality.
-   */
-  void loadTXFIFO() {
-/*    cc2420_header_t* header = call CC2420PacketBody.getHeader( m_msg );*/
-/*    uint8_t tx_power = (call CC2420PacketBody.getMetadata( m_msg ))->tx_power;*/
-    m_txFrameLen = m_data->headerLen + m_data->payloadLen + 2;
 
-/*    if ( !tx_power ) {*/
-/*      tx_power = CC2420_DEF_RFPOWER;*/
-/*    }*/
-    call CSN.set();
-    call CSN.clr();
-    call SFLUSHTX.strobe(); // flush out anything that was in there
-    call CSN.set();
-    call CSN.clr();
-    
-/*    call TXFIFO.write( (uint8_t*)header, header->length - 1);*/
-    call TXFIFO.write( &m_txFrameLen, 1 );
-
-  }
-  
   void signalDone( bool ackFramePending, error_t err ) {
     atomic m_state = S_STARTED;
-    signal CC2420Tx.sendDone( m_data, &m_timestamp, ackFramePending, err );
+    signal CC2420Tx.sendDone( m_frame, &m_timestamp, ackFramePending, err );
     call ChipSpiResource.attemptRelease();
-/*    signal Send.sendDone( m_msg, err );*/
   }
-  
-  /***************** Tasks ****************/
-
-  /***************** Defaults ****************/
-/*  default async event void TimeStamp.transmittedSFD( uint16_t time, message_t* p_msg ) {*/
-/*  }*/
-  
-/*  default async event void TimeStamp.receivedSFD( uint16_t time ) {*/
-/*  }*/
 
+  async event void TXFIFO.readDone( uint8_t* tx_buf, uint8_t tx_len, 
+      error_t error ) {
+  }
 }
 
index 53e1fc9fda513b145d5aece88c893717465140bf..8d7fe92363caf47d90e97d0e3a3b9094aaae3392 100644 (file)
@@ -40,7 +40,7 @@ interface CC2420Tx {
   async command error_t loadTXFIFO(ieee154_txframe_t *data);
   async event void loadTXFIFODone(ieee154_txframe_t *data, error_t error );
 
-  async command void send(bool cca);
+  async command error_t send(bool cca);
   async event void sendDone(ieee154_txframe_t *frame, ieee154_reftime_t *referenceTime, 
       bool ackPendingFlag, error_t error);
 
index 02140b1116fb1181ff4e5dff2cddd9a5b56979e8..0ac6432453905931c6a67661bb4345241b21db59 100644 (file)
  */
 interface ReliableWait
 {
-
   async command void busyWait(uint16_t dt);
-
-  /*
-   * The following command/event pairs are platform-specific
-   * busy-waits. 
-   */
-  
   async command void waitRx(ieee154_reftime_t *t0, uint16_t dt);
   async event void waitRxDone();
-  async command void waitCCA(ieee154_reftime_t *t0, uint16_t dt);
-  async event void waitCCADone();
   async command void waitTx(ieee154_reftime_t *t0, uint16_t dt);
   async event void waitTxDone();
+  async command void waitBackoff(ieee154_reftime_t *t0, uint16_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);
 }
index c420f3201700c61f53f21b63018705e22e5a9d54..5740941980813ceec55195c4aeaff92f2a13dd7d 100644 (file)
@@ -152,7 +152,7 @@ implementation
         call TxControlPool.put(txControl);
       }
     }
-    call Debug.log(LEVEL_INFO, AssociateP_REQUEST, status, 0, 0);
+    call Debug.log(DEBUG_LEVEL_INFO, AssociateP_REQUEST, status, 0, 0);
     return status;
   }
 
@@ -165,10 +165,10 @@ implementation
       signal MLME_ASSOCIATE.confirm(0xFFFF, status, 0);
     } else {
       call ResponseTimeout.startOneShot(call MLME_GET.macResponseWaitTime()*IEEE154_aBaseSuperframeDuration);
-      call Debug.log(LEVEL_INFO, AssociateP_SETTIMER, 
+      call Debug.log(DEBUG_LEVEL_INFO, AssociateP_SETTIMER, 
           call MLME_GET.macResponseWaitTime()*IEEE154_aBaseSuperframeDuration, 0, 0);
     }
-    call Debug.log(LEVEL_INFO, AssociateP_TXDONE, status, 0, 0);
+    call Debug.log(DEBUG_LEVEL_INFO, AssociateP_TXDONE, status, 0, 0);
   }
   
   event void ResponseTimeout.fired()
@@ -202,7 +202,7 @@ implementation
   event void DataRequest.pollDone()
   {
     if (m_associationOngoing){
-      call Debug.log(LEVEL_INFO, AssociateP_POLL_DONE, m_payloadAssocRequest[0], m_assocRespStatus, 0);
+      call Debug.log(DEBUG_LEVEL_INFO, AssociateP_POLL_DONE, m_payloadAssocRequest[0], m_assocRespStatus, 0);
       call ResponseTimeout.stop();
       m_associationOngoing = FALSE;
       signal MLME_ASSOCIATE.confirm(m_shortAddress, m_assocRespStatus, 0);
index c4c570c527cd2b881ff942fa268d692dc933549d..eadfc4bc3c0c3e0dd0d2db69c284bd0664ee5eed 100644 (file)
@@ -105,7 +105,6 @@ implementation
   bool m_internalRequest = FALSE;
 
   norace uint8_t m_numBeaconsLost;
-  uint8_t m_coordAddress[8];
   message_t m_beaconBuffer;
   norace message_t *m_beaconBufferPtr = &m_beaconBuffer;
   norace bool m_beaconSwapBufferReady = TRUE;
@@ -161,7 +160,7 @@ implementation
         (channelPage != IEEE154_SUPPORTED_CHANNELPAGE) || !call IsBeaconEnabledPAN.getNow())
       return IEEE154_INVALID_PARAMETER;
 
-    call Debug.log(LEVEL_INFO,SyncP_REQUEST, logicalChannel, channelPage, trackBeacon);
+    call Debug.log(DEBUG_LEVEL_INFO,0, logicalChannel, channelPage, trackBeacon);
     if (!trackBeacon && m_tracking){
       // stop tracking after next received beacon
       m_stopTracking = TRUE;
@@ -171,7 +170,7 @@ implementation
       m_updateTrackBeacon = trackBeacon;
       m_internalRequest = FALSE;
       m_updatePending = TRUE;
-      call Debug.log(LEVEL_INFO,SyncP_RESOURCE_REQUEST, 0, 0, 0);
+      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
@@ -185,7 +184,8 @@ implementation
 
   event void FindBeacon.notify( bool val )
   {
-    if (!m_tracking && !m_updatePending){
+    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;
@@ -197,7 +197,7 @@ implementation
 
   event void Token.granted()
   {
-    call Debug.log(LEVEL_INFO,SyncP_GOT_RESOURCE, m_lastBeaconRxTime+m_beaconInterval, 
+    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;
@@ -210,7 +210,7 @@ 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(LEVEL_INFO,SyncP_UPDATING, call MLME_GET.macCoordShortAddress(), 
+      call Debug.log(DEBUG_LEVEL_INFO,3, call MLME_GET.macCoordShortAddress(), 
           call MLME_GET.macPANId(), m_updateLogicalChannel);
     }
     getNextBeacon();
@@ -225,23 +225,24 @@ implementation
       m_state = S_PREPARE;
       if (!m_tracking){
         // nothing to do, just give up the token
-        call Debug.log(LEVEL_INFO,SyncP_RELEASE_RESOURCE, 0, 0, 0);
+        call Debug.log(DEBUG_LEVEL_INFO,4, 0, 0, 0);
         call Token.release();
         return;
       }
       while (call TimeCalc.hasExpired(m_lastBeaconRxTime, m_dt)){ // missed a beacon!
         missed = TRUE;
-        call Debug.log(LEVEL_INFO,SyncP_BEACON_MISSED_1, m_lastBeaconRxTime, m_dt, missed);
+        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);
         post processBeaconTask();
         return;
       }
       if (missed){
         call Token.request();
-        call Debug.log(LEVEL_INFO,SyncP_RELEASE_RESOURCE, m_lastBeaconRxTime, m_dt, missed);
+        call Debug.log(DEBUG_LEVEL_IMPORTANT,6, m_lastBeaconRxTime, m_dt, missed);
         call Token.release();
         return;
       }
@@ -272,17 +273,15 @@ implementation
 
   async event void TrackAlarm.fired()
   {
-    call Debug.log(LEVEL_IMPORTANT,SyncP_TRACK_ALARM, m_state,m_lastBeaconRxTime,m_dt);
-    atomic {
-      switch (m_state)
-      {
-        case S_PREPARE:
-          call BeaconRx.prepare();
-          break;
-        case S_RADIO_OFF: 
-          call RadioOff.off(); 
-          break;
-      }
+    call Debug.log(DEBUG_LEVEL_INFO,7, m_state,m_lastBeaconRxTime,m_dt);
+    switch (m_state)
+    {
+      case S_PREPARE:
+        call BeaconRx.prepare();
+        break;
+      case S_RADIO_OFF: 
+        call RadioOff.off(); 
+        break;
     }
   }
 
@@ -299,9 +298,10 @@ implementation
     } else {
       m_state = S_RADIO_OFF;
       result = call BeaconRx.receive(&m_lastBeaconRxRefTime, m_dt-RX_LAG);
-      call Debug.log(LEVEL_IMPORTANT,SyncP_RX_ON, m_lastBeaconRxTime, call TrackAlarm.getNow(), m_dt+RX_DURATION);
+      //__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(LEVEL_IMPORTANT,SyncP_RADIO_BUSY, result, 0, 0);
+        call Debug.log(DEBUG_LEVEL_CRITICAL,9, result, 0, 0);
       call TrackAlarm.startAt(m_lastBeaconRxTime, m_dt + RX_DURATION);
     }
   }
@@ -309,20 +309,23 @@ implementation
   event message_t* BeaconRx.received(message_t *frame, ieee154_reftime_t *timestamp)
   {
     uint8_t *mhr = MHR(frame);
-    call Debug.log(LEVEL_INFO,SyncP_RX_PACKET,*((nxle_uint32_t*) &mhr[MHR_INDEX_ADDRESS]), 
+    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))
     {
-      call Debug.log(LEVEL_IMPORTANT,SyncP_RX_GARBAGE, m_beaconSwapBufferReady, 0, 0);
+      call Debug.log(DEBUG_LEVEL_IMPORTANT,11, m_beaconSwapBufferReady, 0, 0);
       return frame;
     } else {
+      error_t resultOff;
       message_t *tmp = m_beaconBufferPtr;
       call TrackAlarm.stop();
       m_beaconSwapBufferReady = FALSE;
       m_beaconBufferPtr = frame;
-      if (timestamp != NULL)
+      resultOff = call RadioOff.off();
+      if (timestamp != NULL){
         memcpy(&m_lastBeaconRxRefTime, timestamp, sizeof(ieee154_reftime_t));
-      call RadioOff.off();
+        call Debug.log(DEBUG_LEVEL_INFO,23,0, 0, resultOff);
+      }
       return tmp;
     }
   }
@@ -331,10 +334,14 @@ implementation
   {
     if (m_state == S_FIRST_SCAN)
       call BeaconRx.prepare();
-    else if (m_state == S_PREPARE)
-      call TrackAlarm.startAt(m_lastBeaconRxTime, m_dt - IEEE154_RADIO_RX_PREPARE_DELAY);
-    else
+    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()
@@ -342,17 +349,22 @@ implementation
     // 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);
+      else
+        call Debug.log(DEBUG_LEVEL_IMPORTANT, 12,m_numBeaconsLost,m_beaconSwapBufferReady,m_lastBeaconRxTime);
       m_sfSlotDuration = 0; // CAP len will be 0
       m_numBeaconsLost++;
       m_dt += m_beaconInterval;
-      call Debug.log(LEVEL_IMPORTANT, SyncP_BEACON_MISSED_3,m_numBeaconsLost,0,m_lastBeaconRxTime);
+      m_beaconSwapBufferReady = TRUE;
       if (m_numBeaconsLost >= IEEE154_aMaxLostBeacons){
         m_tracking = FALSE;
-        call Debug.log(LEVEL_IMPORTANT, SyncP_LOST_SYNC,0,0,0);
+        call Debug.log(DEBUG_LEVEL_IMPORTANT, 13,m_internalRequest,0,0);
         call Leds.led2Off();
-        if (m_internalRequest)
+        if (m_internalRequest){
           call TokenToCap.transfer();
-        else
+          return;
+        } else
           signal MLME_SYNC_LOSS.indication(
               IEEE154_BEACON_LOSS, 
               call MLME_GET.macPANId(),
@@ -362,7 +374,7 @@ implementation
               );
       } else
         call Token.request(); // make another request again (before giving the token up)
-      call Debug.log(LEVEL_INFO,SyncP_RELEASE_RESOURCE, 0, 0, 0);
+      call Debug.log(DEBUG_LEVEL_INFO,14, 0, 0, 0);
       call Token.release();
     } else { 
       // got the beacon!
@@ -379,7 +391,7 @@ implementation
       uint8_t gtsFieldLength;
       uint32_t timestamp = call Frame.getTimestamp(m_beaconBufferPtr);
 
-      call Debug.log(LEVEL_INFO, SyncP_BEACON_RX, m_lastBeaconRxTime, timestamp, mhr[2]);
+      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;
@@ -395,7 +407,7 @@ implementation
           m_BLELen += call MLME_GET.macMinLIFSPeriod();
         else
           m_BLELen += call MLME_GET.macMinSIFSPeriod();
-        m_BLELen += call MLME_GET.macBattLifeExtPeriods();
+        m_BLELen = m_BLELen + call MLME_GET.macBattLifeExtPeriods() * 20;
       } else
         m_BLELen = 0;
       m_broadcastPending = mhr[MHR_INDEX_FC1] & FC1_FRAME_PENDING ? TRUE : FALSE;
@@ -403,12 +415,12 @@ implementation
       m_dt = m_beaconInterval = ((uint32_t) 1 << coordBeaconOrder) * (uint32_t) IEEE154_aBaseSuperframeDuration; 
       if (m_stopTracking){
         m_tracking = FALSE;
-        call Debug.log(LEVEL_INFO,SyncP_RELEASE_RESOURCE, 0, 0, 0);
+        call Debug.log(DEBUG_LEVEL_INFO,16, 0, 0, 0);
         if (m_updatePending) // there is already a new request pending...
           call Token.request();
         call Token.release();
       } else {
-        call Debug.log(LEVEL_INFO,SyncP_TRANSFER_RESOURCE, 0, 0, 0);
+        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
       }
       
@@ -435,7 +447,7 @@ implementation
         call DataRequest.poll(CoordAddrMode, CoordPANId, CoordAddress, SrcAddrMode);
       }
       // Beacon Tracking: update state
-      call Debug.log(LEVEL_INFO, SyncP_NEXT_RX_TIME, 0, timestamp, m_beaconInterval);
+      call Debug.log(DEBUG_LEVEL_INFO, 18, m_lastBeaconRxTime, m_beaconInterval, 0);
       m_numBeaconsLost = 0;
       // TODO: check PAN ID conflict here?
       if (!autoRequest || beaconPayloadSize)
index b3b04dbd3560d0d409f30aef71bfc407c83db775..04ef76412cb64c24256b5e0bc51783d2f89ad6aa 100644 (file)
@@ -238,7 +238,7 @@ implementation
       status = IEEE154_SUCCESS;
       if (panCoordinator)
         startTime = 0; // start immediately
-      call Debug.log(LEVEL_INFO, StartP_REQUEST, logicalChannel, beaconOrder, superframeOrder);
+      call Debug.log(DEBUG_LEVEL_INFO, 0, logicalChannel, beaconOrder, superframeOrder);
       if (beaconOrder == 15){
         // beaconless PAN
         superframeOrder = 15;
@@ -394,7 +394,7 @@ implementation
   event void Token.granted()
   {
     call Debug.flush();
-    call Debug.log(LEVEL_INFO, StartP_GOT_RESOURCE, m_lastBeaconTxTime, m_beaconInterval, m_requests);
+    call Debug.log(DEBUG_LEVEL_INFO, 1, m_lastBeaconTxTime, m_beaconInterval, m_requests);
     if (m_requests & REQUEST_REALIGNMENT_DONE_PENDING){
       // unlikely to occur: we have not yet received a done()
       // event after sending out a realignment frame 
@@ -404,7 +404,7 @@ implementation
     if (m_requests & REQUEST_UPDATE_SF){
       m_requests &= ~REQUEST_UPDATE_SF;
       continueStartRequest();
-      call Debug.log(LEVEL_INFO, StartP_UPDATE_STATE, 0, 0, 0);
+      call Debug.log(DEBUG_LEVEL_INFO, 2, 0, 0, 0);
     }
     if (call RadioOff.isOff())
       prepareNextBeaconTransmission();
@@ -433,7 +433,7 @@ implementation
     if (m_txState == S_TX_LOCKED){
       // have not had time to finish processing the last sent beacon
       post grantedTask();
-      call Debug.log(LEVEL_CRITICAL, StartP_OWNER_TOO_FAST, 0, 0, 0);
+      call Debug.log(DEBUG_LEVEL_IMPORTANT, 3, 0, 0, 0);
       return;
     } else if (m_beaconOrder == 15){
       call Token.release();
@@ -463,8 +463,8 @@ implementation
           // the usual case: next beacon tx time = last time + BI
           m_dt = m_beaconInterval;
         }
-        while (call TimeCalc.hasExpired(m_lastBeaconTxTime, m_dt)){ // missed sending a beacon
-          call Debug.log(LEVEL_INFO, StartP_SKIPPED_BEACON, m_lastBeaconTxTime, m_dt, 0);
+        while (call TimeCalc.hasExpired(m_lastBeaconTxTime, m_dt)){ // skipped a beacon
+          call Debug.log(DEBUG_LEVEL_IMPORTANT, 4, m_lastBeaconTxTime, m_dt, 0);
           m_dt += m_beaconInterval;
         }
         if (m_dt < IEEE154_RADIO_TX_PREPARE_DELAY)
@@ -489,12 +489,12 @@ implementation
           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(LEVEL_INFO, StartP_PREPARE_TX, 0, m_lastBeaconTxTime, 0);
+          call Debug.log(DEBUG_LEVEL_INFO, 5, 0, m_lastBeaconTxTime, 0);
           call BeaconTx.load(&m_beaconFrame); 
           break;
         case S_TX_LOCKED: 
-          call Debug.log(LEVEL_INFO, StartP_TRANSMIT, m_lastBeaconTxTime, m_dt, ((uint32_t)m_lastBeaconTxRefTime));
-          call BeaconTx.transmit(&m_lastBeaconTxRefTime, m_dt, 0, FALSE);
+          call Debug.log(DEBUG_LEVEL_INFO, 6, m_lastBeaconTxTime, m_dt, 0);
+          call BeaconTx.transmit(&m_lastBeaconTxRefTime, m_dt);
           break;
       }
     }
@@ -503,25 +503,23 @@ implementation
   async event void BeaconTx.loadDone()
   {
     atomic {
-      call Debug.log(LEVEL_INFO, StartP_PREPARE_TXDONE, 0, m_lastBeaconTxTime, 0);
+      call Debug.log(DEBUG_LEVEL_INFO, 7, 0, m_lastBeaconTxTime, 0);
       if (m_txOneBeaconImmediately){
         m_txOneBeaconImmediately = FALSE;
-        call BeaconTx.transmit(0, 0, 0, FALSE); // now!
+        call BeaconTx.transmit(NULL, 0); // now!
       } else 
         call BeaconTxAlarm.startAt(m_lastBeaconTxTime, m_dt - IEEE154_RADIO_TX_SEND_DELAY);
     }
   }
-    
-  async event void BeaconTx.transmitDone(ieee154_txframe_t *frame, 
-      ieee154_reftime_t *referenceTime, bool pendingFlag, error_t error)
+  async event void BeaconTx.transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime)
   {
     // Coord CAP has just started...
     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(LEVEL_INFO, StartP_BEACON_TRANSMITTED, frame->metadata->timestamp, m_lastBeaconTxTime, m_dt);
+    call Debug.log(DEBUG_LEVEL_INFO, 8, frame->metadata->timestamp, m_lastBeaconTxTime, m_dt);
     m_lastBeaconTxTime = frame->metadata->timestamp;
-    memcpy(&m_lastBeaconTxRefTime, referenceTime, sizeof(ieee154_reftime_t));
+    memcpy(&m_lastBeaconTxRefTime, txTime, sizeof(ieee154_reftime_t));
     m_numGtsSlots = (frame->payload[2] & 0x07);
     gtsFieldLength = 1 + ((m_numGtsSlots > 0) ? 1 + m_numGtsSlots * 3: 0);
     m_finalCAPSlot = (frame->payload[1] & 0x0F);
@@ -534,12 +532,12 @@ implementation
     if (frame->payload[1] & 0x10){
       // BLE is active; calculate the time offset from slot0
       m_BLELen = IEEE154_SHR_DURATION + 
-        (frame->headerLen + frame->payloadLen) * IEEE154_SYMBOLS_PER_OCTET; 
-      if (frame->headerLen + frame->payloadLen > IEEE154_aMaxSIFSFrameSize)
+        (frame->headerLen + frame->payloadLen + 2) * IEEE154_SYMBOLS_PER_OCTET; 
+      if (frame->headerLen + frame->payloadLen + 2 > IEEE154_aMaxSIFSFrameSize)
         m_BLELen += IEEE154_MIN_LIFS_PERIOD;
       else
         m_BLELen += IEEE154_MIN_SIFS_PERIOD;
-      m_BLELen += m_battLifeExtPeriods;
+      m_BLELen = m_BLELen + m_battLifeExtPeriods * 20;
     } else
       m_BLELen = 0;
     call TokenToBroadcast.transfer(); // borrow Token to Broadcast/CAP/CFP module, we'll get it back afterwards
@@ -658,7 +656,7 @@ implementation
     atomic {
       if (m_txState == S_TX_LOCKED) 
       {
-        call Debug.log(LEVEL_INFO, StartP_BEACON_UPDATE, 0, 0, m_txState);
+        call Debug.log(DEBUG_LEVEL_IMPORTANT, 10, 0, 0, m_txState);
         return; // too late !
       }
       if (m_payloadState & MODIFIED_PENDING_ADDR_FIELD){
@@ -696,7 +694,7 @@ implementation
     atomic {
       if (m_txState == S_TX_LOCKED) 
       {
-        call Debug.log(LEVEL_INFO, StartP_BEACON_UPDATE_2, 0, 0, m_txState);
+        call Debug.log(DEBUG_LEVEL_INFO, 11, 0, 0, m_txState);
         return; // too late !
       }
       if (m_payloadState & MODIFIED_BEACON_PAYLOAD){
@@ -815,6 +813,11 @@ implementation
   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){} 
+
 
   default event void MLME_START.confirm    (
                           ieee154_status_t status
diff --git a/tos/lib/mac/tkn154/CsmaP.nc b/tos/lib/mac/tkn154/CsmaP.nc
deleted file mode 100644 (file)
index 4567acc..0000000
+++ /dev/null
@@ -1,735 +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 <hauer@tkn.tu-berlin.de>
- * ========================================================================
- */
-
-#include "TKN154_PHY.h"
-#include "TKN154_MAC.h"
-
-/** 
- * This module implements the slotted and unslotted CSMA-CA algorithm.
- * Unslotted CSMA-CA is used in nonbeacon-enabled PANs, slotted CSMA-CA is used
- * in beacon-enabled PANs. In a beacon-enabled PAN this module is responsible
- * for channel access during the contention access period (CAP). It does
- * slightly different things depending on whether it is the CAP for an outgoing
- * superframe (superframeDirection = OUTGOING_SUPERFRAME), i.e. the CAP from
- * the perspective of a coordinator after it has transmitted its own beacon; or
- * for an incoming superframe (superframeDirection = INCOMING_SUPERFRAME), i.e.
- * the CAP from the perspective of a device after it has received a beacon from
- * its coordinator; for example, in the CAP a coordinator will usually listen for
- * incoming frames from the devices, and a device will usually switch the radio
- * off unless it has a frame to transmit. In nonbeacon-enabled PANs the
- * superframeDirection parameter is ignored.
- */
-
-generic module CsmaP(uint8_t superframeDirection)
-{
-  provides
-  {
-    interface Init as Reset;
-    interface FrameTx as FrameTx;
-    interface FrameRx as FrameRx[uint8_t frameType];
-    interface FrameExtracted as FrameExtracted[uint8_t frameType];
-    interface FrameTxNow as BroadcastTx;
-    interface Notify<bool> as WasRxEnabled;
-    interface Notify<bool> as FindBeacon;
-  }
-  uses
-  {
-    interface Random;
-    interface Alarm<TSymbolIEEE802154,uint32_t> as CapEndAlarm;
-    interface Alarm<TSymbolIEEE802154,uint32_t> as BLEAlarm;
-    interface Alarm<TSymbolIEEE802154,uint32_t> as IndirectTxWaitAlarm;
-    interface Alarm<TSymbolIEEE802154,uint32_t> as BroadcastAlarm;
-    interface Resource as Token;
-    interface GetNow<bool> as IsTokenRequested;
-    interface ResourceTransfer as TokenToCfp;
-    interface ResourceTransferred as TokenTransferred;
-    interface GetNow<uint32_t> as CapStart; 
-    interface GetNow<ieee154_reftime_t*> as CapStartRefTime; 
-    interface GetNow<uint32_t> as CapLen; 
-    interface GetNow<bool> as IsBLEActive; 
-    interface GetNow<uint16_t> as BLELen; 
-    interface GetNow<bool> as IsRxBroadcastPending; 
-    interface GetNow<bool> as IsRxEnableActive; 
-    interface Notify<bool> as RxEnableStateChange;
-    interface GetNow<bool> as IsTrackingBeacons;
-    interface FrameUtility;
-    interface RadioTx;
-    interface RadioRx;
-    interface RadioOff;
-    interface GetNow<bool> as IsBeaconEnabledPAN;
-    interface MLME_GET;
-    interface MLME_SET;
-    interface Ieee802154Debug as Debug;
-    interface TimeCalc;
-    interface Leds;
-    interface SetNow<ieee154_cap_frame_backup_t*> as FrameBackup;
-    interface GetNow<ieee154_cap_frame_backup_t*> as FrameRestore;
-  }
-}
-implementation
-{
-  typedef enum {
-    SWITCH_OFF,
-    LOAD_TX,
-    PREPARE_RX,
-    DO_NOTHING,
-    WAIT_FOR_TXDONE,
-  } next_state_t;
-
-  typedef enum {
-    INDIRECT_TX_ALARM,
-    BROADCAST_ALARM,
-    NO_ALARM,
-  } rx_alarm_t;
-
-  enum {
-    COORD_ROLE = (superframeDirection == OUTGOING_SUPERFRAME),
-    DEVICE_ROLE = !COORD_ROLE,
-  };
-
-  norace bool m_lock;
-  norace ieee154_txframe_t *m_currentFrame;
-  norace ieee154_txframe_t *m_bcastFrame;
-  norace ieee154_txframe_t *m_lastFrame;
-  norace ieee154_macMaxBE_t m_BE;
-  norace ieee154_macMaxBE_t m_NB;
-  norace ieee154_macMaxBE_t m_numCCA;
-  norace ieee154_macMaxCSMABackoffs_t m_macMaxCSMABackoffs;
-  norace ieee154_macMaxFrameRetries_t m_macMaxFrameRetries;
-  norace ieee154_macMaxBE_t m_macMaxBE;
-  norace ieee154_macMinBE_t m_macMinBE;
-  norace uint16_t m_backoff;
-  norace uint16_t m_backoffElapsed;
-  norace ieee154_status_t m_result;
-  norace uint32_t m_transactionTime;
-  norace bool m_indirectTxPending = FALSE;
-  norace bool m_broadcastRxPending;
-  norace ieee154_macMaxFrameTotalWaitTime_t m_macMaxFrameTotalWaitTime;
-
-  uint16_t generateRandomBackoff(uint8_t BE);
-  void stopAllAlarms();
-  next_state_t tryReceive(rx_alarm_t alarmType);
-  next_state_t tryTransmit();
-  next_state_t trySwitchOff();
-  void backupCurrentFrame();
-  void restoreFrameFromBackup();  
-  void updateState();
-  void setCurrentFrame(ieee154_txframe_t *frame);
-  void signalTxBroadcastDone(ieee154_txframe_t *frame, ieee154_status_t error);
-  task void signalTxDoneTask();
-  task void setupTxBroadcastTask();
-  task void wasRxEnabledTask();
-
-  command error_t Reset.init()
-  {
-    if (m_currentFrame)
-      signal FrameTx.transmitDone(m_currentFrame, IEEE154_TRANSACTION_OVERFLOW);
-    if (m_lastFrame)
-      signal FrameTx.transmitDone(m_lastFrame, IEEE154_TRANSACTION_OVERFLOW);
-    if (m_bcastFrame)
-      signalTxBroadcastDone(m_bcastFrame, IEEE154_TRANSACTION_OVERFLOW);
-    m_currentFrame = m_lastFrame = m_bcastFrame = NULL;
-    stopAllAlarms();
-    return SUCCESS;
-  }
-
-  async event void TokenTransferred.transferred()
-  {
-    // we got the token, i.e. CAP has just started    
-    uint32_t actualCapLen = call CapLen.getNow();
-    if (!call IsBeaconEnabledPAN.getNow()){
-      call Leds.led0On(); // internal error! 
-      call TokenToCfp.transfer();
-      call Debug.log(LEVEL_IMPORTANT, CapP_INTERNAL_ERROR, 0,0,0);
-    } else if (DEVICE_ROLE && actualCapLen == 0){
-      // very rare case: 
-      // this can only happen, if we're on a beacon-enabled PAN, not tracking beacons, 
-      // and searched but didn't find a beacon for aBaseSuperframeDuration*(2n+1) symbols
-      // -> transmit current frame using unslotted CSMA-CA
-      m_numCCA = 1;
-      updateState();
-      return;
-    } else if (actualCapLen < IEEE154_RADIO_GUARD_TIME){
-      call Debug.log(LEVEL_IMPORTANT, CapP_TOO_SHORT, superframeDirection, actualCapLen, IEEE154_RADIO_GUARD_TIME);
-      call TokenToCfp.transfer();
-      return;
-    } else {
-      actualCapLen -= IEEE154_RADIO_GUARD_TIME;
-      if (DEVICE_ROLE)
-        m_broadcastRxPending = call IsRxBroadcastPending.getNow();
-      else { 
-        // COORD_ROLE
-        if (m_bcastFrame != NULL) {
-          // we have to transmit a broadcast frame immediately; this  
-          // (possibly) requires a backup of the previously active frame
-          // and a reinitializing the CSMA parameters -> will do it
-          // in task context and then continue
-          m_lock = TRUE;
-          post setupTxBroadcastTask(); 
-        }
-      }
-      call CapEndAlarm.startAt(call CapStart.getNow(), actualCapLen);
-      if (call IsBLEActive.getNow())
-        call BLEAlarm.startAt(call CapStart.getNow(), call BLELen.getNow());
-      call Debug.log(LEVEL_IMPORTANT, CapP_SET_CAP_END, call CapStart.getNow(), 
-          actualCapLen, call CapStart.getNow()+ actualCapLen);
-    }
-    updateState();
-  }
-
-  command ieee154_status_t FrameTx.transmit(ieee154_txframe_t *frame)
-  {
-    if (m_currentFrame != NULL)
-      return IEEE154_TRANSACTION_OVERFLOW;
-    else {
-      setCurrentFrame(frame);
-      if (!call IsBeaconEnabledPAN.getNow()){
-        call Token.request(); // prepare for unslotted CSMA-CA
-      } else {
-        // a beacon must be found before transmitting in a beacon-enabled PAN
-        if (DEVICE_ROLE && !call IsTrackingBeacons.getNow()){
-          signal FindBeacon.notify(TRUE);
-          // we'll receive the Token at latest after aBaseSuperframeDuration*(2n+1) symbols; 
-          // if the beacon was not found, then we'll send the frame using unslotted CSMA-CA
-        }
-        updateState();
-      }
-      return IEEE154_SUCCESS;
-    }
-  }
-
-  task void setupTxBroadcastTask()
-  {
-    ieee154_macDSN_t tmp;
-    ieee154_txframe_t *oldFrame = m_currentFrame;
-    if (COORD_ROLE){
-      if (m_bcastFrame != NULL){
-        // broadcasts should be transmitted *immediately* after the beacon,
-        // which may interrupt a pending transmit operation from the previous
-        // CAP; back up the last active frame configuration (may be none)
-        // and restore it after the broadcast frame has been transmitted; 
-        // do this through interfaces and don't wire them for DEVICE_ROLE, 
-        // so we don't waste the RAM of devices
-        backupCurrentFrame();
-        setCurrentFrame(m_bcastFrame);
-        if (oldFrame){
-          // now the sequence number are out of order... swap them back
-          tmp = m_bcastFrame->header->mhr[MHR_INDEX_SEQNO];
-          m_bcastFrame->header->mhr[MHR_INDEX_SEQNO] = 
-            oldFrame->header->mhr[MHR_INDEX_SEQNO];
-          oldFrame->header->mhr[MHR_INDEX_SEQNO] = tmp;
-        }
-      }
-    }
-    m_lock = FALSE;
-    updateState(); 
-  }
-
-  void setCurrentFrame(ieee154_txframe_t *frame)
-  {
-    ieee154_macDSN_t dsn = call MLME_GET.macDSN();
-    frame->header->mhr[MHR_INDEX_SEQNO] = dsn++;
-    call MLME_SET.macDSN(dsn);
-    m_macMaxCSMABackoffs =  call MLME_GET.macMaxCSMABackoffs();
-    m_macMaxFrameRetries =  call MLME_GET.macMaxFrameRetries();
-    m_macMaxBE = call MLME_GET.macMaxBE();
-    m_macMinBE = call MLME_GET.macMinBE();
-    if (call MLME_GET.macBattLifeExt() && m_macMinBE > 2)
-      m_macMinBE = 2;
-    m_BE = m_macMinBE;
-    if (call IsBeaconEnabledPAN.getNow())
-      m_numCCA = 2;
-    else
-      m_numCCA = 1;
-    m_NB = 0;
-    m_transactionTime = IEEE154_SHR_DURATION + 
-      (frame->headerLen + frame->payloadLen) * IEEE154_SYMBOLS_PER_OCTET;
-    if (frame->header->mhr[MHR_INDEX_FC1] & FC1_ACK_REQUEST)
-      m_transactionTime += (IEEE154_aTurnaroundTime + IEEE154_aUnitBackoffPeriod + 
-          11 * IEEE154_SYMBOLS_PER_OCTET);
-    if (frame->headerLen + frame->payloadLen > IEEE154_aMaxSIFSFrameSize)
-      m_transactionTime += call MLME_GET.macMinLIFSPeriod();
-    else
-      m_transactionTime += call MLME_GET.macMinSIFSPeriod();
-    m_backoff = generateRandomBackoff(m_BE) * IEEE154_aUnitBackoffPeriod; // initial backoff
-    m_macMaxFrameTotalWaitTime = call MLME_GET.macMaxFrameTotalWaitTime();
-    m_backoffElapsed = 0;
-    m_currentFrame = frame;
-  }
-
-  uint16_t generateRandomBackoff(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;
-  }
-  void stopAllAlarms()
-  {
-    call CapEndAlarm.stop();
-    if (DEVICE_ROLE){
-      call IndirectTxWaitAlarm.stop();
-      call BroadcastAlarm.stop();
-    }
-    call BLEAlarm.stop();
-  }
-
-  /** 
-   * The updateState() function is called whenever some event happened that
-   * might require a state change; it implements a lock mechanism (m_lock) to
-   * prevent race conditions. Whenever the lock is set a "done"-event (from a
-   * RadioTx/RadioRx/RadioOff interface) is pending and will "soon" unset the
-   * lock (and then updateState() will called again).  The updateState()
-   * function decides about the next state by checking a list of possible
-   * current states ordered by priority, e.g. it first always checks whether
-   * the CAP is still active. Calling this function more than necessary can do
-   * no harm, but it SHOULD be called whenever an event happened that might
-   * lead to a state change.
-   */ 
-
-  void updateState()
-  {
-    error_t result = SUCCESS;
-    next_state_t next;
-    atomic {
-      // long atomics are bad... but in this block, once the
-      // current state has been determined only one branch will
-      // be taken (no loops, etc.)
-      if (m_lock || !call Token.isOwner())
-        return;
-      m_lock = TRUE; // lock
-
-      // Check 1: for beacon-enabled PANs, has the CAP finished?
-      if (call IsBeaconEnabledPAN.getNow() 
-          && (COORD_ROLE || call IsTrackingBeacons.getNow()) // FALSE only if device could't find a beacon
-          && (call TimeCalc.hasExpired(call CapStart.getNow(), call CapLen.getNow()-IEEE154_RADIO_GUARD_TIME) ||
-          !call CapEndAlarm.isRunning())){
-        if (call RadioOff.isOff()) {
-          stopAllAlarms();  // may still fire, locked through isOwner()
-          if (DEVICE_ROLE && m_indirectTxPending)
-            signal IndirectTxWaitAlarm.fired();
-          m_broadcastRxPending = FALSE;
-          if (COORD_ROLE && m_bcastFrame){
-            // didn't manage to transmit a broadcast
-            restoreFrameFromBackup();
-            signalTxBroadcastDone(m_bcastFrame, IEEE154_CHANNEL_ACCESS_FAILURE);
-            m_bcastFrame = NULL;
-          }
-          m_lock = FALSE; // unlock
-          call TokenToCfp.transfer();
-          return;
-        } else 
-          next = SWITCH_OFF;
-      }
-
-      // Check 2: should a broadcast frame be received/transmitted immediately
-      // at the start of CAP?
-      else if (DEVICE_ROLE && m_broadcastRxPending){
-        // receive a broadcast from coordinator
-        next = tryReceive(BROADCAST_ALARM);
-      } else if (COORD_ROLE && m_bcastFrame){
-        next = tryTransmit();
-      }
-
-      // Check 3: was an indirect transmission successfully started 
-      // and are we now waiting for a frame from the coordinator?
-      else if (DEVICE_ROLE && m_indirectTxPending) {
-        next = tryReceive(INDIRECT_TX_ALARM);
-      }
-
-      // Check 4: is some other operation (like MLME-SCAN or MLME-RESET) pending? 
-      else if (call IsTokenRequested.getNow() && call IsBeaconEnabledPAN.getNow()) {
-        if (call RadioOff.isOff()) {
-          stopAllAlarms();  // may still fire, but is locked through isOwner()
-          // nothing more to do... just release the Token
-          m_lock = FALSE; // unlock
-          call TokenToCfp.transfer();
-          return;
-        } else 
-          next = SWITCH_OFF;
-      }
-
-      // Check 5: is battery life extension (BLE) active and 
-      // has the BLE period expired?
-      else if (call IsBLEActive.getNow() &&
-          call TimeCalc.hasExpired(call CapStart.getNow(), call BLELen.getNow()) &&
-          !call IsRxEnableActive.getNow()) {
-        next = trySwitchOff();
-      }
-
-      // Check 6: is there a frame ready to transmit?
-      else if (m_currentFrame != NULL) {
-        next = tryTransmit();
-      }
-
-      // Check 7: should we be in receive mode?
-      else if (COORD_ROLE || call IsRxEnableActive.getNow()) {
-        next = tryReceive(NO_ALARM);
-        if (next == DO_NOTHING && call IsRxEnableActive.getNow()){
-          // this means there is an active MLME_RX_ENABLE.request
-          // and the radio was just switched to Rx mode - signal
-          // a notify event to inform the next higher layer
-          post wasRxEnabledTask();
-        }
-      }
-
-      // Check 8: just make sure the radio is switched off  
-      else {
-        next = trySwitchOff();
-        if (next == DO_NOTHING && 
-            (!call IsBeaconEnabledPAN.getNow() || (DEVICE_ROLE && call CapLen.getNow() == 0))){
-          // nothing more to do... just release the Token
-          stopAllAlarms();  // may still fire, but is locked through isOwner()
-          m_lock = FALSE; // unlock
-          call 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: result = call RadioOff.off(); break;
-      case LOAD_TX: result = call RadioTx.load(m_currentFrame); break;
-      case PREPARE_RX: result = call RadioRx.prepare(); break;
-      case WAIT_FOR_TXDONE: break;
-      case DO_NOTHING: break;
-    }
-    if (result != SUCCESS)
-      call Leds.led0On(); // internal error: could not update state !!!
-  }
-  
-  next_state_t tryTransmit()
-  {
-    // tries to transmit m_currentFrame using the configuration stored
-    // in other module variables (m_backoff, etc.)
-    next_state_t next;
-    if (call RadioTx.getLoadedFrame() == m_currentFrame){
-      // the frame is already loaded -> transmit it now
-      if (m_numCCA == 1){
-        // unslotted CSMA-CA
-        call RadioTx.transmit(NULL, m_backoff, m_numCCA, m_currentFrame->header->mhr[MHR_INDEX_FC1] & FC1_ACK_REQUEST ? TRUE : FALSE);
-        next = WAIT_FOR_TXDONE; // this will NOT clear the lock
-      } else {
-        // slotted CSMA-CA
-        uint32_t capLen = call CapLen.getNow(), capStart = call CapStart.getNow();
-        uint32_t elapsed, totalTime;
-        totalTime = IEEE154_RADIO_TX_SEND_DELAY + 
-          m_backoff - m_backoffElapsed + m_transactionTime + IEEE154_RADIO_GUARD_TIME;
-        if (totalTime > capLen)
-          totalTime = capLen; // CAP is too short
-        elapsed = call TimeCalc.timeElapsed(capStart, call CapEndAlarm.getNow());
-        elapsed += (20 - (elapsed % 20)); // round to backoff boundary
-        if (!call TimeCalc.hasExpired(capStart, capLen - totalTime)){
-          call RadioTx.transmit(call CapStartRefTime.getNow(), 
-              elapsed + IEEE154_RADIO_TX_SEND_DELAY + m_backoff - m_backoffElapsed, 
-              m_numCCA, 
-              m_currentFrame->header->mhr[MHR_INDEX_FC1] & FC1_ACK_REQUEST ? TRUE : FALSE);
-          next = WAIT_FOR_TXDONE; // this will NOT clear the lock
-        } else {
-          // frame does not fit in remaing portion of the CAP
-          if (elapsed < call CapLen.getNow()){
-            m_backoffElapsed += call CapLen.getNow() - elapsed;
-            if (m_backoffElapsed > m_backoff)
-              m_backoffElapsed = m_backoff;
-          }
-          next = SWITCH_OFF;
-        }
-      }
-    } else {
-      // the frame to transmit has not yet been loaded -> load it now
-      if (!call RadioOff.isOff())
-        next = SWITCH_OFF;
-      else {
-        if (m_lastFrame){
-          // the done event for the previous frame has not yet been
-          // signalled to the upper layer -> wait
-          next = DO_NOTHING; 
-        } else
-          next = LOAD_TX;
-      }
-    }
-    return next;
-  }
-
-  next_state_t tryReceive(rx_alarm_t alarmType)
-  {
-    next_state_t next;
-    if (call RadioRx.isReceiving()){
-      next = DO_NOTHING;
-    } else if (call RadioRx.isPrepared()){
-      call RadioRx.receive(NULL, 0);
-      switch (alarmType)
-      {
-        case INDIRECT_TX_ALARM: call IndirectTxWaitAlarm.start(m_macMaxFrameTotalWaitTime); break;
-        case BROADCAST_ALARM: call BroadcastAlarm.start(m_macMaxFrameTotalWaitTime); break;
-        case NO_ALARM: break;
-      }
-      next = DO_NOTHING;
-    } else if (call RadioOff.isOff())
-      next = PREPARE_RX;
-    else
-      next = SWITCH_OFF;
-    return next;
-  }
-
-  next_state_t trySwitchOff()
-  {
-    next_state_t next;
-    if (call RadioOff.isOff())
-      next = DO_NOTHING;
-    else
-      next = SWITCH_OFF;
-    return next;
-  }
-
-  async event void RadioTx.loadDone(){ m_lock = FALSE; updateState();}
-  async event void RadioOff.offDone(){ m_lock = FALSE; updateState();}
-  async event void RadioRx.prepareDone(){ m_lock = FALSE; updateState();}
-
-  async event void CapEndAlarm.fired(){ 
-    call Debug.log(LEVEL_IMPORTANT, CapP_CAP_END_FIRED, superframeDirection, 0, 0);
-    updateState();
-  }
-  async event void BLEAlarm.fired(){ updateState();}
-  event void RxEnableStateChange.notify(bool whatever){ updateState();}
-  async event void BroadcastAlarm.fired(){ m_broadcastRxPending = FALSE; updateState();}
-
-  async event void IndirectTxWaitAlarm.fired() 
-  { 
-    atomic {
-      if (m_indirectTxPending){
-        m_indirectTxPending = FALSE; 
-        post signalTxDoneTask(); 
-      }
-    }
-  }
-
-  async event void RadioTx.transmitDone(ieee154_txframe_t *frame, 
-      ieee154_reftime_t *referenceTime, bool ackPendingFlag, error_t error)
-  {
-    bool retry = FALSE;
-    switch (error)
-    {
-      case SUCCESS:
-        m_result = IEEE154_SUCCESS;
-        if (DEVICE_ROLE && frame->payload[0] == CMD_FRAME_DATA_REQUEST &&
-            ((frame->header->mhr[MHR_INDEX_FC1]) & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_CMD){
-          // just transmitted a data request frame
-          m_result = IEEE154_NO_DATA; // pessimistic 
-          if (ackPendingFlag){
-            // the coordinator has data for us; switch to Rx 
-            // to complete the indirect transmission
-            m_indirectTxPending = TRUE;
-            m_lastFrame = m_currentFrame;
-            m_currentFrame = NULL;
-            if (call RadioRx.prepare() != SUCCESS) // SHOULD succeed
-              call RadioOff.off();
-            return;
-          }
-        }
-        break;
-      case EBUSY:
-        // we're following the SDL Spec in IEEE 802.15.4-2003 Annex D
-        m_result = IEEE154_CHANNEL_ACCESS_FAILURE;
-        m_NB += 1;
-        if (m_NB < m_macMaxCSMABackoffs){
-          m_BE += 1;
-          if (m_BE > m_macMaxBE)
-            m_BE = m_macMaxBE;
-          retry = TRUE;
-        }
-        break;
-      case ENOACK:
-        // we're following the SDL Spec in IEEE 802.15.4-2003 Annex D
-        m_result = IEEE154_NO_ACK;
-        m_NB += 1;
-        // shouldn't the next check be (m_NB-1 < m_macMaxFrameRetries)? but
-        // on the other hand, NB is used for CHANNEL_ACCESS_FAILURE and NO_ACK,
-        // i.e. m_NB does not tell us much about past retransmissions anyway...
-        if (m_NB < m_macMaxFrameRetries){
-          m_BE = m_macMinBE;
-          retry = TRUE;
-        }
-        break;
-      default: break;
-    }
-    if (retry){
-      m_backoff = generateRandomBackoff(m_BE) * IEEE154_aUnitBackoffPeriod; // next backoff
-      m_backoffElapsed = 0;
-    } else if (COORD_ROLE && frame == m_bcastFrame){
-      // signal result of broadcast transmissions immediately 
-      restoreFrameFromBackup();
-      signalTxBroadcastDone(m_bcastFrame, m_result);
-      m_bcastFrame = NULL;
-    } else {
-      m_lastFrame = m_currentFrame;
-      m_currentFrame = NULL;
-      post signalTxDoneTask();
-    }    
-    m_lock = FALSE;
-    updateState();
-  }
-
-  task void signalTxDoneTask()
-  {
-    ieee154_txframe_t *lastFrame = m_lastFrame;
-    m_lastFrame = NULL; // only now can a next transmission begin 
-    m_indirectTxPending = FALSE;
-    if (lastFrame)
-      signal FrameTx.transmitDone(lastFrame, m_result);
-    updateState();
-  }
-
-  event message_t* RadioRx.received(message_t* frame, ieee154_reftime_t *timestamp)
-  {
-    // received a frame during CAP - find out frame type and
-    // signal it to corresponding client component
-    uint8_t *payload = (uint8_t *) frame->data;
-    uint8_t *mhr = MHR(frame);
-    uint8_t frameType = mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK;
-    if (frameType == FC1_FRAMETYPE_CMD)
-      frameType += payload[0];
-    atomic {
-      if (DEVICE_ROLE && m_indirectTxPending){
-        message_t* frameBuf;
-        call IndirectTxWaitAlarm.stop();
-        // TODO: check!
-        //if (frame->payloadLen)
-          // is this frame from our coordinator? hmm... we cannot say
-          // with certainty, because we might only know either the 
-          // coordinator extended or short address (and the frame could
-          // have been sent with the other addressing mode) ??
-          m_result = IEEE154_SUCCESS;
-        frameBuf = signal FrameExtracted.received[frameType](frame, m_lastFrame);
-        signal IndirectTxWaitAlarm.fired();
-        return frameBuf;
-      } else
-        return signal FrameRx.received[frameType](frame);
-    }
-  }
-
-  void backupCurrentFrame()
-  {
-    ieee154_cap_frame_backup_t backup = {m_currentFrame, m_BE, m_macMaxCSMABackoffs, 
-      m_macMaxBE, m_macMinBE, m_NB, m_backoff, m_backoffElapsed, m_transactionTime};
-    call FrameBackup.setNow(&backup);
-  }
-
-  void restoreFrameFromBackup()
-  {
-    ieee154_cap_frame_backup_t *backup = call FrameRestore.getNow();
-    if (backup != NULL){
-      m_currentFrame = backup->frame;
-      m_BE = backup->BE;
-      m_macMaxCSMABackoffs = backup->allowedBackoffs;
-      m_macMaxBE = backup->macMaxBE; 
-      m_macMinBE = backup->macMinBE; 
-      m_NB = backup->NB; 
-      m_backoff = backup->backoff;
-      m_backoffElapsed = backup->backoffElapsed;
-      m_transactionTime = backup->transactionTime;
-    }
-  }
-
-  async command ieee154_status_t BroadcastTx.transmitNow(ieee154_txframe_t *frame) 
-  {
-    // if this command is called then it is (MUST be) called 
-    // only just before the token is transferred to this component
-    // and it is then be called only once per CAP (max. one broadcast 
-    // is allowed after a beacon transmission)
-    atomic {
-      if (!call Token.isOwner() && m_bcastFrame == NULL){
-        m_bcastFrame = frame;
-        return IEEE154_SUCCESS;
-      } else {
-        call Leds.led0On();
-        return IEEE154_TRANSACTION_OVERFLOW;
-      }
-    }
-  }
-
-  void signalTxBroadcastDone(ieee154_txframe_t *frame, ieee154_status_t error)
-  {
-    signal BroadcastTx.transmitNowDone(frame, error);
-  }
-
-  task void wasRxEnabledTask()
-  {
-    signal WasRxEnabled.notify(TRUE);
-  }
-
-  bool isUnslottedCSMA_CA()
-  {
-    return (m_numCCA == 1);
-  }
-
-  event void Token.granted()
-  {
-    // the current frame should be transmitted using unslotted CSMA-CA
-    updateState();
-  }
-
-  default event void FrameTx.transmitDone(ieee154_txframe_t *data, ieee154_status_t status){}
-  default event message_t* FrameRx.received[uint8_t client](message_t* data){return data;}
-  default async command bool IsRxEnableActive.getNow(){return FALSE;}
-
-  default async command void IndirectTxWaitAlarm.start(uint32_t dt){call Leds.led0On();}
-  default async command void IndirectTxWaitAlarm.stop(){call Leds.led0On();}
-  default async command void IndirectTxWaitAlarm.startAt(uint32_t t0, uint32_t dt){call Leds.led0On();}
-  
-  default async command void BroadcastAlarm.start(uint32_t dt){call Leds.led0On();}
-  default async command void BroadcastAlarm.stop(){call Leds.led0On();}
-  default async command void BroadcastAlarm.startAt(uint32_t t0, uint32_t dt){call Leds.led0On();}
-
-  default async command bool IsRxBroadcastPending.getNow(){ return FALSE;}
-  default async event void BroadcastTx.transmitNowDone(ieee154_txframe_t *frame, ieee154_status_t status){}
-  default event message_t* FrameExtracted.received[uint8_t client](message_t* msg, ieee154_txframe_t *txFrame){return msg;}
-  default async command error_t FrameBackup.setNow(ieee154_cap_frame_backup_t* val ){return FAIL;}
-  default async command ieee154_cap_frame_backup_t* FrameRestore.getNow(){return NULL;}
-
-  command error_t WasRxEnabled.enable(){return FAIL;}
-  command error_t WasRxEnabled.disable(){return FAIL;}
-  command error_t FindBeacon.enable(){return FAIL;}
-  command error_t FindBeacon.disable(){return FAIL;}
-}
diff --git a/tos/lib/mac/tkn154/CsmaQueueP.nc b/tos/lib/mac/tkn154/CsmaQueueP.nc
deleted file mode 100644 (file)
index f89c762..0000000
+++ /dev/null
@@ -1,128 +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 <hauer@tkn.tu-berlin.de>
- * ========================================================================
- */
-#include "TKN154_MAC.h"
-generic module CsmaQueueP() {
-  provides
-  {
-    interface Init as Reset;
-    interface FrameTx[uint8_t client];
-    interface FrameRx as FrameExtracted[uint8_t client];
-    interface Purge;
-  } uses {
-    interface Queue<ieee154_txframe_t*>;
-    interface FrameTx as FrameTxCsma;
-    interface FrameRx as SubFrameExtracted;
-  }
-}
-implementation
-{
-  task void txTask();
-  bool m_busy;
-  uint8_t m_client;
-
-  command error_t Reset.init()
-  {
-    while (call Queue.size()){
-      ieee154_txframe_t *txFrame = call Queue.dequeue();
-      signal FrameTx.transmitDone[txFrame->client](txFrame, IEEE154_TRANSACTION_OVERFLOW);
-    }
-    m_busy = FALSE;
-    return SUCCESS;
-  }
-
-  command ieee154_status_t FrameTx.transmit[uint8_t client](ieee154_txframe_t *txFrame)
-  {
-    txFrame->client = client;
-    if (call Queue.enqueue(txFrame) != SUCCESS)
-      return IEEE154_TRANSACTION_OVERFLOW;
-    else {
-      post txTask();
-      return IEEE154_SUCCESS;
-    }
-  }
-
-  task void txTask()
-  {
-    if (!m_busy && call Queue.size()){
-      ieee154_txframe_t *txFrame = call Queue.head();
-      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){
-        m_busy = TRUE;
-      }
-    }
-  }
-
-  event void FrameTxCsma.transmitDone(ieee154_txframe_t *txFrame, ieee154_status_t status)
-  {
-    call Queue.dequeue();
-    m_busy = FALSE;
-    signal FrameTx.transmitDone[txFrame->client](txFrame, status);
-    post txTask();
-  }
-
-  event message_t* SubFrameExtracted.received(message_t* frame)
-  {
-    // this event is signalled when a frame has been received
-    // in response to a data request command frame. The transmitDone 
-    // event will be signalled later
-    return signal FrameExtracted.received[m_client](frame);
-  }
-
-  default event void FrameTx.transmitDone[uint8_t client](ieee154_txframe_t *txFrame, ieee154_status_t status){}
-
-  command ieee154_status_t Purge.purge(uint8_t msduHandle)
-  {
-    uint8_t qSize = call Queue.size(), i;
-    if (qSize > 1){
-      for (i=0; i<qSize-1; i++){
-        ieee154_txframe_t *txFrame = call Queue.element(i);
-        if (((txFrame->header->mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_DATA) &&
-          txFrame->handle == msduHandle){
-          txFrame->headerLen = 0; // mark as invalid
-          return IEEE154_SUCCESS;
-        }
-      }
-    }
-    return IEEE154_INVALID_HANDLE;
-  }
-  
-  default event void Purge.purgeDone(ieee154_txframe_t *txFrame, ieee154_status_t status){}
-}
index 5eddab18dd1d01ad2eddef4f22ce9adc97926ce6..a229f50a092d949863c3947536a4b9ddaa697528 100644 (file)
@@ -142,7 +142,7 @@ implementation
         call TxControlPool.put(txControl);
       }
     }
-    call Debug.log(LEVEL_INFO, DISSASSOCIATE_REQUEST, status, 0, 0);
+    call Debug.log(DEBUG_LEVEL_INFO, DISSASSOCIATE_REQUEST, status, 0, 0);
     return status;
   }
 
@@ -158,7 +158,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(LEVEL_INFO, DISSASSOCIATE_TXDONE, status, 2, 0);
+    call Debug.log(DEBUG_LEVEL_INFO, DISSASSOCIATE_TXDONE, status, 2, 0);
     m_disAssociationOngoing = FALSE;
     signal MLME_DISASSOCIATE.confirm(status, DeviceAddrMode, DevicePANID, DeviceAddress);
   }
@@ -176,10 +176,10 @@ 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(LEVEL_INFO, DISSASSOCIATE_TXDONE, status, 1, 0);
+    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(LEVEL_INFO, DISSASSOCIATE_TXDONE, status, 2, 0);
+    call Debug.log(DEBUG_LEVEL_INFO, DISSASSOCIATE_TXDONE, status, 2, 0);
     m_disAssociationOngoing = FALSE;
     signal MLME_DISASSOCIATE.confirm(status, DeviceAddrMode, DevicePANID, DeviceAddress);
   }
@@ -205,7 +205,7 @@ implementation
   {
     // received a disassociation notification from the device
     ieee154_address_t address;
-    call Debug.log(LEVEL_INFO, DISSASSOCIATE_RX, 0, 0, 0);
+    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);
diff --git a/tos/lib/mac/tkn154/FrameDispatchP.nc b/tos/lib/mac/tkn154/FrameDispatchP.nc
new file mode 100644 (file)
index 0000000..ad8b693
--- /dev/null
@@ -0,0 +1,770 @@
+/*
+ * Copyright (c) 2008, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright 
+ *   notice, this list of conditions and the following disclaimer in the 
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names 
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+#include "TKN154_PHY.h"
+#include "TKN154_MAC.h"
+
+
+/** 
+ * This module is responsible for preparing the transmission/reception of DATA
+ * and COMMAND frames in the contention access period (CAP, slotted CSMA-CA) or
+ * in a nonbeacon-enabled PAN (unslotted CSMA-CA). It prepares the relevant
+ * parameters of the CSMA-CA algorithm (NB, BE, etc.), but it does not implement
+ * the CSMA-CA algorithm (the CSMA-CA algorithm is implemented in the radio
+ * driver).
+ *
+ * In a beacon-enabled this module does slightly different things depending on
+ * whether it is the CAP for an outgoing superframe (superframeDirection =
+ * OUTGOING_SUPERFRAME), i.e. the CAP from the perspective of a coordinator
+ * after it has transmitted its own beacon; or for an incoming superframe
+ * (superframeDirection = INCOMING_SUPERFRAME), i.e.  the CAP from the
+ * perspective of a device after it has received a beacon from its coordinator.
+ * For example, in the CAP a coordinator will usually listen for incoming
+ * frames from the devices, and a device will usually switch the radio off
+ * unless it has a frame to transmit. In nonbeacon-enabled PANs the
+ * superframeDirection parameter is ignored.
+ */
+
+generic module FrameDispatchP(uint8_t superframeDirection)
+{
+  provides
+  {
+    interface Init as Reset;
+    interface FrameTx as FrameTx;
+    interface FrameRx as FrameRx[uint8_t frameType];
+    interface FrameExtracted as FrameExtracted[uint8_t frameType];
+    interface FrameTxNow as BroadcastTx;
+    interface Notify<bool> as WasRxEnabled;
+    interface Notify<bool> as FindBeacon;
+  }
+  uses
+  {
+    interface Alarm<TSymbolIEEE802154,uint32_t> as CapEndAlarm;
+    interface Alarm<TSymbolIEEE802154,uint32_t> as BLEAlarm;
+    interface Alarm<TSymbolIEEE802154,uint32_t> as IndirectTxWaitAlarm;
+    interface Alarm<TSymbolIEEE802154,uint32_t> as BroadcastAlarm;
+    interface Resource as Token;
+    interface GetNow<bool> as IsTokenRequested;
+    interface ResourceTransfer as TokenToCfp;
+    interface ResourceTransferred as TokenTransferred;
+    interface GetNow<uint32_t> as CapStart; 
+    interface GetNow<ieee154_reftime_t*> as CapStartRefTime; 
+    interface GetNow<uint32_t> as CapLen; 
+    interface GetNow<bool> as IsBLEActive; 
+    interface GetNow<uint16_t> as BLELen; 
+    interface GetNow<bool> as IsRxBroadcastPending; 
+    interface GetNow<bool> as IsRxEnableActive; 
+    interface Get<ieee154_txframe_t*> as GetIndirectTxFrame; 
+    interface Notify<bool> as RxEnableStateChange;
+    interface GetNow<bool> as IsTrackingBeacons;
+    interface FrameUtility;
+    interface RadioTx;
+    interface RadioRx;
+    interface RadioOff;
+    interface GetNow<bool> as IsBeaconEnabledPAN;
+    interface MLME_GET;
+    interface MLME_SET;
+    interface Ieee802154Debug as Debug;
+    interface TimeCalc;
+    interface Leds;
+    interface SetNow<ieee154_cap_frame_backup_t*> as FrameBackup;
+    interface GetNow<ieee154_cap_frame_backup_t*> as FrameRestore;
+  }
+}
+implementation
+{
+  typedef enum {
+    SWITCH_OFF,
+    LOAD_TX,
+    PREPARE_RX,
+    DO_NOTHING,
+    WAIT_FOR_TXDONE,
+  } next_state_t;
+
+  typedef enum {
+    INDIRECT_TX_ALARM,
+    BROADCAST_ALARM,
+    NO_ALARM,
+  } rx_alarm_t;
+
+  enum {
+    COORD_ROLE = (superframeDirection == OUTGOING_SUPERFRAME),
+    DEVICE_ROLE = !COORD_ROLE,
+  };
+
+  norace bool m_lock;
+  norace ieee154_txframe_t *m_currentFrame;
+  norace ieee154_txframe_t *m_bcastFrame;
+  norace ieee154_txframe_t *m_lastFrame;
+
+  norace ieee154_csma_t m_csmaParams;
+  norace bool m_resume;
+  norace uint16_t m_remainingBackoff;
+  norace ieee154_macMaxBE_t m_BE;
+  norace ieee154_macMaxCSMABackoffs_t m_macMaxCSMABackoffs;
+  norace ieee154_macMaxBE_t m_macMaxBE;
+  norace bool m_slottedCsma;
+  norace ieee154_macMaxFrameRetries_t m_macMaxFrameRetries;
+  norace ieee154_status_t m_result;
+  norace uint32_t m_transactionTime;
+  norace bool m_indirectTxPending = FALSE;
+  norace bool m_broadcastRxPending;
+  norace ieee154_macMaxFrameTotalWaitTime_t m_macMaxFrameTotalWaitTime;
+
+
+#ifdef TKN154_SERIAL_DEBUG 
+#define DEBUG_NEXT_BUFFER_SIZE 12
+  norace uint8_t dbgHistory[DEBUG_NEXT_BUFFER_SIZE];
+  norace uint8_t dbgHistoryIndex;
+  void dbgHistoryReset(){dbgHistoryIndex=0; memset(dbgHistory, 0xFF, DEBUG_NEXT_BUFFER_SIZE);} 
+  void dbgHistoryAdd(uint8_t nextState)
+  {
+    dbgHistory[dbgHistoryIndex] = nextState;
+    dbgHistoryIndex = (dbgHistoryIndex+1) % DEBUG_NEXT_BUFFER_SIZE; 
+  }
+  void dbgHistoryFlush()
+  {
+    uint8_t i,k=dbgHistoryIndex;
+    uint32_t s1=0xFFFFFFFF,s2=0xFFFFFFFF,s3=0xFFFFFFFF;
+    for (i=0; i<4; i++){ s1 = s1 << 8; s1 |= dbgHistory[k]; k = (k+1) % DEBUG_NEXT_BUFFER_SIZE;}
+    for (i=0; i<4; i++){ s2 = s2 << 8; s2 |= dbgHistory[k]; k = (k+1) % DEBUG_NEXT_BUFFER_SIZE;}
+    for (i=0; i<4; i++){ s3 = s3 << 8; s3 |= dbgHistory[k]; k = (k+1) % DEBUG_NEXT_BUFFER_SIZE;}
+    call Debug.log(DEBUG_LEVEL_INFO, 12, s1,s2,s3);
+  }
+#else
+  void dbgHistoryReset(){} 
+  void dbgHistoryAdd(uint8_t nextState){}
+  void dbgHistoryFlush(){}
+#endif
+
+  void stopAllAlarms();
+  next_state_t tryReceive(rx_alarm_t alarmType);
+  next_state_t tryTransmit();
+  next_state_t trySwitchOff();
+  void backupCurrentFrame();
+  void restoreFrameFromBackup();  
+  void updateState();
+  void setCurrentFrame(ieee154_txframe_t *frame);
+  void signalTxBroadcastDone(ieee154_txframe_t *frame, ieee154_status_t error);
+  void transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime, 
+      bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result);
+  task void signalTxDoneTask();
+  task void setupTxBroadcastTask();
+  task void wasRxEnabledTask();
+
+  command error_t Reset.init()
+  {
+    if (m_currentFrame)
+      signal FrameTx.transmitDone(m_currentFrame, IEEE154_TRANSACTION_OVERFLOW);
+    if (m_lastFrame)
+      signal FrameTx.transmitDone(m_lastFrame, IEEE154_TRANSACTION_OVERFLOW);
+    if (m_bcastFrame)
+      signalTxBroadcastDone(m_bcastFrame, IEEE154_TRANSACTION_OVERFLOW);
+    m_currentFrame = m_lastFrame = m_bcastFrame = NULL;
+    stopAllAlarms();
+    return SUCCESS;
+  }
+
+  async event void TokenTransferred.transferred()
+  {
+    // we got the token, i.e. CAP has just started    
+    uint32_t actualCapLen = call CapLen.getNow();
+    dbgHistoryReset();
+    if (!call IsBeaconEnabledPAN.getNow()){
+      call Leds.led0On(); // internal error! 
+      call TokenToCfp.transfer();
+      call Debug.log(DEBUG_LEVEL_IMPORTANT, 0, 0,0,0);
+    } else if (DEVICE_ROLE && actualCapLen == 0){
+      // very rare case: 
+      // this can only happen, if we're on a beacon-enabled PAN, not tracking beacons, 
+      // and searched but didn't find a beacon for aBaseSuperframeDuration*(2n+1) symbols
+      // -> transmit current frame using unslotted CSMA-CA
+      m_slottedCsma = FALSE;
+      updateState();
+      return;
+    } else if (actualCapLen < IEEE154_ACTIVE_PERIOD_GUARD_TIME){
+      call Debug.log(DEBUG_LEVEL_IMPORTANT, 1, superframeDirection, actualCapLen, IEEE154_ACTIVE_PERIOD_GUARD_TIME);
+      call TokenToCfp.transfer();
+      return;
+    } else {
+      actualCapLen -= IEEE154_ACTIVE_PERIOD_GUARD_TIME;
+      if (DEVICE_ROLE)
+        m_broadcastRxPending = call IsRxBroadcastPending.getNow();
+      else { 
+        // COORD_ROLE
+        if (m_bcastFrame != NULL) {
+          // we have to transmit a broadcast frame immediately; this  
+          // (possibly) requires a backup of the previously active frame
+          // and a reinitializing the CSMA parameters -> will do it
+          // in task context and then continue
+          m_lock = TRUE;
+          post setupTxBroadcastTask(); 
+          call Debug.log(DEBUG_LEVEL_INFO, 7, 0,0,0);
+        }
+      }
+      call CapEndAlarm.startAt(call CapStart.getNow(), actualCapLen);
+      if (call IsBLEActive.getNow())
+        call BLEAlarm.startAt(call CapStart.getNow(), call BLELen.getNow());
+      call Debug.log(DEBUG_LEVEL_INFO, 2, call CapStart.getNow(), 
+          actualCapLen, call CapStart.getNow()+ actualCapLen);
+    }
+    updateState();
+  }
+
+  command ieee154_status_t FrameTx.transmit(ieee154_txframe_t *frame)
+  {
+    //call Debug.log(DEBUG_LEVEL_INFO, 4, m_lock, call Token.isOwner(), m_currentFrame == NULL);
+    if (m_currentFrame != NULL){
+      call Debug.log(DEBUG_LEVEL_IMPORTANT, 5, 0,0,0);
+      return IEEE154_TRANSACTION_OVERFLOW;
+    } else {
+      setCurrentFrame(frame);
+      if (!call IsBeaconEnabledPAN.getNow()){
+        call Token.request(); // prepare for unslotted CSMA-CA
+      } else {
+        // a beacon must be found before transmitting in a beacon-enabled PAN
+        if (DEVICE_ROLE && !call IsTrackingBeacons.getNow()){
+          signal FindBeacon.notify(TRUE);
+          // we'll receive the Token at latest after aBaseSuperframeDuration*(2n+1) symbols; 
+          // if the beacon was not found, then we'll send the frame using unslotted CSMA-CA
+        }
+        updateState();
+      }
+      return IEEE154_SUCCESS;
+    }
+  }
+
+  task void setupTxBroadcastTask()
+  {
+    ieee154_macDSN_t tmp;
+    ieee154_txframe_t *oldFrame = m_currentFrame;
+    if (COORD_ROLE){
+      if (m_bcastFrame != NULL){
+        // broadcasts should be transmitted *immediately* after the beacon,
+        // which may interrupt a pending transmit operation from the previous
+        // CAP; back up the last active frame configuration (may be none)
+        // and restore it after the broadcast frame has been transmitted; 
+        // do this through interfaces and don't wire them for DEVICE_ROLE, 
+        // so we don't waste the RAM of devices
+        backupCurrentFrame();
+        setCurrentFrame(m_bcastFrame);
+        if (oldFrame){
+          // now the sequence number are out of order... swap them back
+          tmp = m_bcastFrame->header->mhr[MHR_INDEX_SEQNO];
+          m_bcastFrame->header->mhr[MHR_INDEX_SEQNO] = 
+            oldFrame->header->mhr[MHR_INDEX_SEQNO];
+          oldFrame->header->mhr[MHR_INDEX_SEQNO] = tmp;
+        }
+      }
+    }
+    m_lock = FALSE;
+    updateState(); 
+  }
+
+  void setCurrentFrame(ieee154_txframe_t *frame)
+  {
+    ieee154_macDSN_t dsn = call MLME_GET.macDSN();
+    frame->header->mhr[MHR_INDEX_SEQNO] = dsn++;
+    call MLME_SET.macDSN(dsn);
+    m_csmaParams.NB = 0;
+    m_csmaParams.macMaxCsmaBackoffs = m_macMaxCSMABackoffs = call MLME_GET.macMaxCSMABackoffs();
+    m_csmaParams.macMaxBE = m_macMaxBE = call MLME_GET.macMaxBE();
+    m_csmaParams.BE = call MLME_GET.macMinBE();
+    if (call MLME_GET.macBattLifeExt() && m_csmaParams.BE > 2)
+      m_csmaParams.BE = 2;
+    m_BE = m_csmaParams.BE;
+    if (COORD_ROLE && call GetIndirectTxFrame.get() == frame)
+      m_macMaxFrameRetries =  0; // this is an indirect transmissions (never retransmit)
+    else
+      m_macMaxFrameRetries =  call MLME_GET.macMaxFrameRetries();
+    m_slottedCsma = call IsBeaconEnabledPAN.getNow();
+    m_transactionTime = IEEE154_SHR_DURATION + 
+      (frame->headerLen + frame->payloadLen + 2) * IEEE154_SYMBOLS_PER_OCTET; // extra 2 for CRC
+    if (frame->header->mhr[MHR_INDEX_FC1] & FC1_ACK_REQUEST)
+      m_transactionTime += (IEEE154_aTurnaroundTime + IEEE154_aUnitBackoffPeriod + 
+          11 * IEEE154_SYMBOLS_PER_OCTET); // 11 byte for the ACK PPDU
+    //if (frame->headerLen + frame->payloadLen > IEEE154_aMaxSIFSFrameSize)
+    //  m_transactionTime += call MLME_GET.macMinLIFSPeriod();
+    //else
+    //  m_transactionTime += call MLME_GET.macMinSIFSPeriod();
+    m_macMaxFrameTotalWaitTime = call MLME_GET.macMaxFrameTotalWaitTime();
+    m_currentFrame = frame;
+  }
+  void stopAllAlarms()
+  {
+    call CapEndAlarm.stop();
+    if (DEVICE_ROLE){
+      call IndirectTxWaitAlarm.stop();
+      call BroadcastAlarm.stop();
+    }
+    call BLEAlarm.stop();
+  }
+
+  /** 
+   * The updateState() function is called whenever some event happened that
+   * might require a state change; it implements a lock mechanism (m_lock) to
+   * prevent race conditions. Whenever the lock is set a "done"-event (from a
+   * RadioTx/RadioRx/RadioOff interface) is pending and will "soon" unset the
+   * lock (and then updateState() will called again).  The updateState()
+   * function decides about the next state by checking a list of possible
+   * current states ordered by priority, e.g. it first always checks whether
+   * the CAP is still active. Calling this function more than necessary can do
+   * no harm, but it SHOULD be called whenever an event happened that might
+   * lead to a state change.
+   */ 
+
+  void updateState()
+  {
+    error_t result = SUCCESS;
+    next_state_t next;
+    atomic {
+      // long atomics are bad... but in this block, once the
+      // current state has been determined only one branch will
+      // be taken (no loops, etc.)
+      if (m_lock || !call Token.isOwner())
+        return;
+      m_lock = TRUE; // lock
+
+      // Check 1: for beacon-enabled PANs, has the CAP finished?
+      if (call IsBeaconEnabledPAN.getNow() 
+          && (COORD_ROLE || call IsTrackingBeacons.getNow()) // FALSE only if device could't find a beacon
+          && (call TimeCalc.hasExpired(call CapStart.getNow(), call CapLen.getNow()-IEEE154_ACTIVE_PERIOD_GUARD_TIME) ||
+          !call CapEndAlarm.isRunning())){
+        if (call RadioOff.isOff()) {
+          stopAllAlarms();  // may still fire, locked through isOwner()
+          if (DEVICE_ROLE && m_indirectTxPending)
+            signal IndirectTxWaitAlarm.fired();
+          m_broadcastRxPending = FALSE;
+          if (COORD_ROLE && m_bcastFrame){
+            // didn't manage to transmit a broadcast
+            restoreFrameFromBackup();
+            signalTxBroadcastDone(m_bcastFrame, IEEE154_CHANNEL_ACCESS_FAILURE);
+            m_bcastFrame = NULL;
+          }
+          m_lock = FALSE; // unlock
+          call TokenToCfp.transfer();
+          call Debug.log(DEBUG_LEVEL_INFO, 8, 0,0,0);
+          dbgHistoryFlush();
+          return;
+        } else 
+          next = SWITCH_OFF;
+      }
+
+      // Check 2: should a broadcast frame be received/transmitted immediately
+      // at the start of CAP?
+      else if (DEVICE_ROLE && m_broadcastRxPending){
+        // receive a broadcast from coordinator
+        next = tryReceive(BROADCAST_ALARM);
+      } else if (COORD_ROLE && m_bcastFrame){
+        next = tryTransmit();
+      }
+
+      // Check 3: was an indirect transmission successfully started 
+      // and are we now waiting for a frame from the coordinator?
+      else if (DEVICE_ROLE && m_indirectTxPending) {
+        next = tryReceive(INDIRECT_TX_ALARM);
+      }
+
+      // Check 4: is some other operation (like MLME-SCAN or MLME-RESET) pending? 
+      else if (call IsTokenRequested.getNow() && call IsBeaconEnabledPAN.getNow()) {
+        if (call RadioOff.isOff()) {
+          stopAllAlarms();  // may still fire, but is locked through isOwner()
+          // nothing more to do... just release the Token
+          m_lock = FALSE; // unlock
+          call TokenToCfp.transfer();
+          call Debug.log(DEBUG_LEVEL_INFO, 9, call IsTokenRequested.getNow(),0,0);
+          dbgHistoryFlush();
+          return;
+        } else 
+          next = SWITCH_OFF;
+      }
+
+      // Check 5: is battery life extension (BLE) active and 
+      // has the BLE period expired?
+      else if (call IsBLEActive.getNow() &&
+          call TimeCalc.hasExpired(call CapStart.getNow(), call BLELen.getNow()) &&
+          !call IsRxEnableActive.getNow()) {
+        next = trySwitchOff();
+      }
+
+      // Check 6: is there a frame ready to transmit?
+      else if (m_currentFrame != NULL) {
+        next = tryTransmit();
+      }
+
+      // Check 7: should we be in receive mode?
+      else if (COORD_ROLE || call IsRxEnableActive.getNow()) {
+        next = tryReceive(NO_ALARM);
+        if (next == DO_NOTHING && call IsRxEnableActive.getNow()){
+          // this means there is an active MLME_RX_ENABLE.request
+          // and the radio was just switched to Rx mode - signal
+          // a notify event to inform the next higher layer
+          post wasRxEnabledTask();
+        }
+      }
+
+      // Check 8: just make sure the radio is switched off  
+      else {
+        next = trySwitchOff();
+        if (next == DO_NOTHING && 
+            (!call IsBeaconEnabledPAN.getNow() || (DEVICE_ROLE && call CapLen.getNow() == 0))){
+          // nothing more to do... just release the Token
+          stopAllAlarms();  // may still fire, but is locked through isOwner()
+          m_lock = FALSE; // unlock
+          call Debug.log(DEBUG_LEVEL_INFO, 10, 0,0,0);
+          dbgHistoryFlush();
+          call Token.release();
+          return;
+        }
+      }
+
+      // if there is nothing to do, then we must clear the lock
+      if (next == DO_NOTHING)
+        m_lock = FALSE;
+    } // atomic
+    dbgHistoryAdd(next);
+    // put next state in operation (possibly keeping the lock)
+    switch (next)
+    {
+      case SWITCH_OFF: result = call RadioOff.off(); break;
+      case LOAD_TX: result = call RadioTx.load(m_currentFrame); break;
+      case PREPARE_RX: result = call RadioRx.prepare(); break;
+      case WAIT_FOR_TXDONE: break;
+      case DO_NOTHING: break;
+    }
+    if (result != SUCCESS)
+      call Leds.led0On(); // internal error: could not update state !!!
+  }
+  
+  next_state_t tryTransmit()
+  {
+    // tries to transmit m_currentFrame using the either slotted or unslotted csma-ca
+    next_state_t next;
+    if (call RadioTx.getLoadedFrame() == m_currentFrame){
+      // the frame is already loaded -> transmit it now
+      if (!m_slottedCsma){
+        // unslotted CSMA-CA
+        call RadioTx.transmitUnslottedCsmaCa(&m_csmaParams);
+        next = WAIT_FOR_TXDONE; // this will NOT clear the lock
+      } else {
+        // slotted CSMA-CA
+        uint32_t dtMax = call CapLen.getNow() - m_transactionTime - IEEE154_ACTIVE_PERIOD_GUARD_TIME;
+        if (dtMax > call CapLen.getNow())
+          dtMax = 0;
+        if (call IsBLEActive.getNow()){
+          // battery life extension
+          uint16_t bleLen = call BLELen.getNow();
+          if (bleLen < dtMax)
+            dtMax = bleLen;
+        }
+        if (call TimeCalc.hasExpired(call CapStart.getNow() - 60, dtMax)) // 60 is for enabling Rx + 2 CCA
+          next = SWITCH_OFF; // frame doesn't possibly fit in the remaining CAP
+        else {
+          call RadioTx.transmitSlottedCsmaCa(call CapStartRefTime.getNow(),
+              dtMax, m_resume, m_remainingBackoff, &m_csmaParams);
+          //call Debug.log(DEBUG_LEVEL_INFO, 13, call CapStart.getNow(), dtMax, m_resume);
+          next = WAIT_FOR_TXDONE; // this will NOT clear the lock
+        }
+      }
+    } else {
+      // the frame to transmit has not yet been loaded -> load it now
+      if (!call RadioOff.isOff())
+        next = SWITCH_OFF;
+      else {
+        if (m_lastFrame){
+          // the done event for the previous frame has not yet been
+          // signalled to the upper layer -> wait
+          next = DO_NOTHING; 
+        } else
+          next = LOAD_TX;
+      }
+    }
+    return next;
+  }
+
+  next_state_t tryReceive(rx_alarm_t alarmType)
+  {
+    next_state_t next;
+    if (call RadioRx.isReceiving()){
+      next = DO_NOTHING;
+    } else if (call RadioRx.isPrepared()){
+      call RadioRx.receive(NULL, 0);
+      switch (alarmType)
+      {
+        case INDIRECT_TX_ALARM: call IndirectTxWaitAlarm.start(m_macMaxFrameTotalWaitTime); break;
+        case BROADCAST_ALARM: call BroadcastAlarm.start(m_macMaxFrameTotalWaitTime); break;
+        case NO_ALARM: break;
+      }
+      next = DO_NOTHING;
+    } else if (call RadioOff.isOff())
+      next = PREPARE_RX;
+    else
+      next = SWITCH_OFF;
+    return next;
+  }
+
+  next_state_t trySwitchOff()
+  {
+    next_state_t next;
+    if (call RadioOff.isOff())
+      next = DO_NOTHING;
+    else
+      next = SWITCH_OFF;
+    return next;
+  }
+
+  async event void RadioTx.loadDone(){ m_lock = FALSE; updateState();}
+  async event void RadioOff.offDone(){ m_lock = FALSE; updateState();}
+  async event void RadioRx.prepareDone(){ m_lock = FALSE; updateState();}
+
+  async event void CapEndAlarm.fired(){ 
+    call Debug.log(DEBUG_LEVEL_IMPORTANT, 3, superframeDirection, 0, 0);
+    updateState();
+  }
+  async event void BLEAlarm.fired(){ updateState();}
+  event void RxEnableStateChange.notify(bool whatever){ updateState();}
+  async event void BroadcastAlarm.fired(){ m_broadcastRxPending = FALSE; updateState();}
+
+  async event void IndirectTxWaitAlarm.fired() 
+  { 
+    atomic {
+      if (m_indirectTxPending){
+        m_indirectTxPending = FALSE; 
+        post signalTxDoneTask(); 
+      }
+    }
+  }
+  
+  async event void RadioTx.transmitUnslottedCsmaCaDone(ieee154_txframe_t *frame,
+      bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result)
+  {
+    transmitDone(frame, NULL, ackPendingFlag, csmaParams, result);
+  }
+
+  async event void RadioTx.transmitSlottedCsmaCaDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime, 
+      bool ackPendingFlag, uint16_t remainingBackoff, ieee154_csma_t *csmaParams, error_t result)
+  {
+    if (result == ERETRY){
+      m_resume = TRUE;
+      m_remainingBackoff = remainingBackoff;
+    } else
+      m_resume = FALSE;
+    transmitDone(frame, txTime, ackPendingFlag, csmaParams, result);
+  }
+
+  void transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime, 
+      bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result)
+  {
+    bool done = TRUE;
+    //call Debug.log(DEBUG_LEVEL_INFO, 11, result,0,0);
+    switch (result)
+    {
+      case SUCCESS:
+        // frame was successfully transmitted, if ACK was requested
+        // then a matching ACK was successfully received also
+        m_result = IEEE154_SUCCESS;
+        if (DEVICE_ROLE && frame->payload[0] == CMD_FRAME_DATA_REQUEST &&
+            ((frame->header->mhr[MHR_INDEX_FC1]) & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_CMD){
+          // this was a data request frame
+          m_result = IEEE154_NO_DATA; // pessimistic 
+          if (ackPendingFlag){
+            // the coordinator has data for us; switch to Rx 
+            // to complete the indirect transmission
+            m_indirectTxPending = TRUE;
+            m_lastFrame = m_currentFrame;
+            m_currentFrame = NULL;
+            if (call RadioRx.prepare() != SUCCESS) // SHOULD succeed
+              call RadioOff.off();
+            return;
+          }
+        }
+        break;
+      case FAIL:
+        // CSMA-CA algorithm failed: frame was not transmitted,
+        // because channel was never idle (including backoff attempts)
+        m_result = IEEE154_CHANNEL_ACCESS_FAILURE;
+        break;
+      case ENOACK:
+        // frame was transmitted, but we didn't receive an ACK (and
+        // the AckRequest flag was set in the frame header)
+        // note: coordinator never retransmits an indirect transmission (see above) 
+        if (m_macMaxFrameRetries > 0) {
+          // retransmit: reinitialize CSMA-CA parameters
+          done = FALSE;
+          m_csmaParams.NB = 0;
+          m_csmaParams.macMaxCsmaBackoffs = m_macMaxCSMABackoffs;
+          m_csmaParams.macMaxBE = m_macMaxBE;
+          m_csmaParams.BE = m_BE;
+          m_macMaxFrameRetries -= 1;
+        } else
+          m_result = IEEE154_NO_ACK;
+        break;
+      case ERETRY:
+        // frame was not transmitted, because the transaction does not
+        // fit in the remaining CAP (in beacon-enabled PANs only)
+        done = FALSE;
+        break;
+      default: 
+        break;
+    }
+    if (COORD_ROLE && frame == m_bcastFrame){
+      // always signal result of broadcast transmissions immediately 
+      restoreFrameFromBackup();
+      signalTxBroadcastDone(m_bcastFrame, (!done) ? IEEE154_CHANNEL_ACCESS_FAILURE : m_result);
+      m_bcastFrame = NULL;
+    } else if (done) {
+      m_lastFrame = m_currentFrame;
+      m_currentFrame = NULL;
+      post signalTxDoneTask();
+    }    
+    m_lock = FALSE;
+    updateState();
+  }
+
+  task void signalTxDoneTask()
+  {
+    ieee154_txframe_t *lastFrame = m_lastFrame;
+    m_lastFrame = NULL; // only now can a next transmission begin 
+    m_indirectTxPending = FALSE;
+    if (lastFrame)
+      signal FrameTx.transmitDone(lastFrame, m_result);
+    updateState();
+  }
+
+  event message_t* RadioRx.received(message_t* frame, ieee154_reftime_t *timestamp)
+  {
+    // received a frame during CAP - find out frame type and
+    // signal it to corresponding client component
+    uint8_t *payload = (uint8_t *) frame->data;
+    uint8_t *mhr = MHR(frame);
+    uint8_t frameType = mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK;
+    if (frameType == FC1_FRAMETYPE_CMD)
+      frameType += payload[0];
+    atomic {
+      if (DEVICE_ROLE && m_indirectTxPending){
+        message_t* frameBuf;
+        call IndirectTxWaitAlarm.stop();
+        // TODO: check!
+        //if (frame->payloadLen)
+          // is this frame from our coordinator? hmm... we cannot say
+          // with certainty, because we might only know either the 
+          // coordinator extended or short address (and the frame could
+          // have been sent with the other addressing mode) ??
+          m_result = IEEE154_SUCCESS;
+        frameBuf = signal FrameExtracted.received[frameType](frame, m_lastFrame);
+        signal IndirectTxWaitAlarm.fired();
+        return frameBuf;
+      } else
+        return signal FrameRx.received[frameType](frame);
+    }
+  }
+
+  void backupCurrentFrame()
+  {
+    ieee154_cap_frame_backup_t backup = {m_currentFrame, m_csmaParams, m_transactionTime};
+    call FrameBackup.setNow(&backup);
+  }
+
+  void restoreFrameFromBackup()
+  {
+    ieee154_cap_frame_backup_t *backup = call FrameRestore.getNow();
+    if (backup != NULL){
+      m_currentFrame = backup->frame;
+      memcpy(&m_csmaParams, &backup->csmaParams, sizeof(ieee154_csma_t));
+      m_transactionTime = backup->transactionTime;
+    }
+  }
+
+  async command ieee154_status_t BroadcastTx.transmitNow(ieee154_txframe_t *frame) 
+  {
+    // if this command is called then it is (MUST be) called 
+    // only just before the token is transferred to this component
+    // and it is then be called only once per CAP (max. one broadcast 
+    // is allowed after a beacon transmission)
+    atomic {
+      if (!call Token.isOwner() && m_bcastFrame == NULL){
+        m_bcastFrame = frame;
+        return IEEE154_SUCCESS;
+      } else {
+        call Leds.led0On();
+        return IEEE154_TRANSACTION_OVERFLOW;
+      }
+    }
+  }
+
+  void signalTxBroadcastDone(ieee154_txframe_t *frame, ieee154_status_t error)
+  {
+    signal BroadcastTx.transmitNowDone(frame, error);
+  }
+
+  task void wasRxEnabledTask()
+  {
+    signal WasRxEnabled.notify(TRUE);
+  }
+
+  event void Token.granted()
+  {
+    // the current frame should be transmitted using unslotted CSMA-CA
+    dbgHistoryReset();
+    call Debug.log(DEBUG_LEVEL_INFO, 6, 0,0,0);
+    updateState();
+  }
+
+  async event void RadioTx.transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime){}
+
+  default event void FrameTx.transmitDone(ieee154_txframe_t *data, ieee154_status_t status){}
+  default event message_t* FrameRx.received[uint8_t client](message_t* data){return data;}
+  default async command bool IsRxEnableActive.getNow(){return FALSE;}
+
+  default async command void IndirectTxWaitAlarm.start(uint32_t dt){call Leds.led0On();}
+  default async command void IndirectTxWaitAlarm.stop(){call Leds.led0On();}
+  default async command void IndirectTxWaitAlarm.startAt(uint32_t t0, uint32_t dt){call Leds.led0On();}
+  
+  default async command void BroadcastAlarm.start(uint32_t dt){call Leds.led0On();}
+  default async command void BroadcastAlarm.stop(){call Leds.led0On();}
+  default async command void BroadcastAlarm.startAt(uint32_t t0, uint32_t dt){call Leds.led0On();}
+
+  default async command bool IsRxBroadcastPending.getNow(){ return FALSE;}
+  default async event void BroadcastTx.transmitNowDone(ieee154_txframe_t *frame, ieee154_status_t status){}
+  default event message_t* FrameExtracted.received[uint8_t client](message_t* msg, ieee154_txframe_t *txFrame){return msg;}
+  default async command error_t FrameBackup.setNow(ieee154_cap_frame_backup_t* val ){return FAIL;}
+  default async command ieee154_cap_frame_backup_t* FrameRestore.getNow(){return NULL;}
+
+  command error_t WasRxEnabled.enable(){return FAIL;}
+  command error_t WasRxEnabled.disable(){return FAIL;}
+  command error_t FindBeacon.enable(){return FAIL;}
+  command error_t FindBeacon.disable(){return FAIL;}
+}
diff --git a/tos/lib/mac/tkn154/FrameDispatchQueueP.nc b/tos/lib/mac/tkn154/FrameDispatchQueueP.nc
new file mode 100644 (file)
index 0000000..4e34605
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2008, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright 
+ *   notice, this list of conditions and the following disclaimer in the 
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names 
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+#include "TKN154_MAC.h"
+generic module FrameDispatchQueueP() {
+  provides
+  {
+    interface Init as Reset;
+    interface FrameTx[uint8_t client];
+    interface FrameRx as FrameExtracted[uint8_t client];
+    interface Purge;
+  } uses {
+    interface Queue<ieee154_txframe_t*>;
+    interface FrameTx as FrameTxCsma;
+    interface FrameRx as SubFrameExtracted;
+  }
+}
+implementation
+{
+  task void txTask();
+  bool m_busy;
+  uint8_t m_client;
+
+  command error_t Reset.init()
+  {
+    while (call Queue.size()){
+      ieee154_txframe_t *txFrame = call Queue.dequeue();
+      signal FrameTx.transmitDone[txFrame->client](txFrame, IEEE154_TRANSACTION_OVERFLOW);
+    }
+    m_busy = FALSE;
+    return SUCCESS;
+  }
+
+  command ieee154_status_t FrameTx.transmit[uint8_t client](ieee154_txframe_t *txFrame)
+  {
+    txFrame->client = client;
+    if (call Queue.enqueue(txFrame) != SUCCESS)
+      return IEEE154_TRANSACTION_OVERFLOW;
+    else {
+      post txTask();
+      return IEEE154_SUCCESS;
+    }
+  }
+
+  task void txTask()
+  {
+    if (!m_busy && call Queue.size()){
+      ieee154_txframe_t *txFrame = call Queue.head();
+      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){
+        m_busy = TRUE;
+      }
+    }
+  }
+
+  event void FrameTxCsma.transmitDone(ieee154_txframe_t *txFrame, ieee154_status_t status)
+  {
+    call Queue.dequeue();
+    m_busy = FALSE;
+    signal FrameTx.transmitDone[txFrame->client](txFrame, status);
+    post txTask();
+  }
+
+  event message_t* SubFrameExtracted.received(message_t* frame)
+  {
+    // this event is signalled when a frame has been received
+    // in response to a data request command frame. The transmitDone 
+    // event will be signalled later
+    return signal FrameExtracted.received[m_client](frame);
+  }
+
+  default event void FrameTx.transmitDone[uint8_t client](ieee154_txframe_t *txFrame, ieee154_status_t status){}
+
+  command ieee154_status_t Purge.purge(uint8_t msduHandle)
+  {
+    uint8_t qSize = call Queue.size(), i;
+    if (qSize > 1){
+      for (i=0; i<qSize-1; i++){
+        ieee154_txframe_t *txFrame = call Queue.element(i);
+        if (((txFrame->header->mhr[MHR_INDEX_FC1] & FC1_FRAMETYPE_MASK) == FC1_FRAMETYPE_DATA) &&
+          txFrame->handle == msduHandle){
+          txFrame->headerLen = 0; // mark as invalid
+          return IEEE154_SUCCESS;
+        }
+      }
+    }
+    return IEEE154_INVALID_HANDLE;
+  }
+  
+  default event void Purge.purgeDone(ieee154_txframe_t *txFrame, ieee154_status_t status){}
+}
index cf654ce6763a6f6ce4f0df2933550a720e0fee92..d17ac67f1818639ab28e244334d1ec0847a5de2e 100644 (file)
@@ -41,6 +41,7 @@ module IndirectTxP
     interface FrameTx[uint8_t client];
     interface WriteBeaconField as PendingAddrWrite;
     interface Notify<bool> as PendingAddrSpecUpdated;
+    interface Get<ieee154_txframe_t*> as GetIndirectTxFrame; 
     interface Purge;
   }
   uses
@@ -129,7 +130,7 @@ 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(LEVEL_INFO, IndirectTxP_BEACON_ASSEMBLY, len,0,0);
+    call Debug.log(DEBUG_LEVEL_INFO, IndirectTxP_BEACON_ASSEMBLY, len,0,0);
     return len;
   }
 
@@ -143,7 +144,7 @@ implementation
     // send a frame through indirect transmission
     uint8_t i;
     if (m_numTableEntries >= NUM_MAX_PENDING){
-      call Debug.log(LEVEL_IMPORTANT, IndirectTxP_OVERFLOW, 0,0,0);
+      call Debug.log(DEBUG_LEVEL_IMPORTANT, IndirectTxP_OVERFLOW, 0,0,0);
       return IEEE154_TRANSACTION_OVERFLOW;
     }
     txFrame->client = client;
@@ -159,7 +160,7 @@ implementation
       m_numExtPending++;
     if (!call IndirectTxTimeout.isRunning())
       call IndirectTxTimeout.startOneShot(getPersistenceTime());
-    call Debug.log(LEVEL_INFO, IndirectTxP_NOTIFIED, 0,0,0);
+    call Debug.log(DEBUG_LEVEL_INFO, IndirectTxP_NOTIFIED, 0,0,0);
     signal PendingAddrSpecUpdated.notify(TRUE);
     return IEEE154_SUCCESS;
   }
@@ -203,7 +204,7 @@ implementation
         }
       }
     }
-    call Debug.log(LEVEL_INFO, IndirectTxP_REQUESTED, NUM_MAX_PENDING-i,i,*src);
+    call Debug.log(DEBUG_LEVEL_INFO, IndirectTxP_REQUESTED, NUM_MAX_PENDING-i,i,*src);
     if (i != NUM_MAX_PENDING){
       // found a matching frame, mark it for transmission
       m_txFrameTable[i]->client |= SEND_THIS_FRAME;
@@ -219,16 +220,16 @@ implementation
     // iterate over the queued frames and transmit them in the CAP 
     // (if they are marked for transmission)
     uint8_t i;
-    if (!m_pendingTxFrame && m_numTableEntries){
+    if (m_pendingTxFrame == NULL && m_numTableEntries){
       for (i=0; i<NUM_MAX_PENDING; i++)
         if (m_txFrameTable[i] && (m_txFrameTable[i]->client & SEND_THIS_FRAME)){
           // 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(LEVEL_INFO, IndirectTxP_SEND_NOW, 0,0,0);
+            call Debug.log(DEBUG_LEVEL_INFO, IndirectTxP_SEND_NOW, 0,0,0);
           } else {
-            m_pendingTxFrame = 0;
+            m_pendingTxFrame = NULL;
             post tryCoordCapTxTask();
           }
           return; // done - wait for txDone
@@ -275,7 +276,7 @@ implementation
   event void CoordCapTx.transmitDone(ieee154_txframe_t *txFrame, ieee154_status_t status)
   {
     uint8_t i;
-    // TODO: if CSMA-CA algorithm failed, then frame shall remain in transaction queue
+    // TODO: if CSMA-CA algorithm failed, then frame shall still remain in transaction queue
     for (i=0; i<NUM_MAX_PENDING; i++)
       if (m_txFrameTable[i] == txFrame){
         m_txFrameTable[i] = NULL; // slot is now empty
@@ -292,9 +293,10 @@ implementation
       m_numExtPending--;    
     signal FrameTx.transmitDone[txFrame->client](txFrame, status);
     post tryCoordCapTxTask();
-    call Debug.log(LEVEL_INFO, IndirectTxP_SEND_DONE, status,m_numTableEntries,0);
+    call Debug.log(DEBUG_LEVEL_INFO, IndirectTxP_SEND_DONE, status,m_numTableEntries,0);
   }
 
+  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){}
index df20b2a8e12768c2efc2824d118eaaa9e0a6077c..269727880c19b9a50abf7287a4f91769f454283e 100644 (file)
@@ -111,7 +111,7 @@ implementation
       if ((txStatus = call PollTx.transmit(txFrame)) != IEEE154_SUCCESS){
         call TxFramePool.put(txFrame);
         call TxControlPool.put(txControl);
-        call Debug.log(LEVEL_IMPORTANT, PollP_ALLOC_FAIL1, 0, 0, 0);
+        call Debug.log(DEBUG_LEVEL_IMPORTANT, PollP_ALLOC_FAIL1, 0, 0, 0);
       } else 
         m_numPending++;
     }
@@ -124,8 +124,8 @@ implementation
     ieee154_txframe_t *txFrame;
     ieee154_txcontrol_t *txControl;
     ieee154_status_t status = IEEE154_TRANSACTION_OVERFLOW;
-    call Debug.log(LEVEL_INFO, PollP_INTERNAL_POLL, CoordAddrMode, client, m_numPending);
-    if (client == SYNC_CLIENT && m_numPending != 0){
+    call Debug.log(DEBUG_LEVEL_INFO, PollP_INTERNAL_POLL, CoordAddrMode, client, m_numPending);
+    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;
@@ -141,7 +141,7 @@ implementation
         if ((status = call PollTx.transmit(txFrame)) != IEEE154_SUCCESS){
           call TxControlPool.put(txControl);
           call TxFramePool.put(txFrame);
-          call Debug.log(LEVEL_IMPORTANT, PollP_ALLOC_FAIL2, 0, 0, 0);
+          call Debug.log(DEBUG_LEVEL_IMPORTANT, PollP_ALLOC_FAIL2, 0, 0, 0);
         } else 
           m_numPending++;
       }
@@ -188,23 +188,23 @@ implementation
   event message_t* DataExtracted.received(message_t* frame, ieee154_txframe_t *txFrame)
   {
     if (!txFrame){
-      call Debug.log(LEVEL_CRITICAL, PollP_INTERNAL_ERROR, 0, 0, 0);
+      call Debug.log(DEBUG_LEVEL_CRITICAL, PollP_INTERNAL_ERROR, 0, 0, 0);
       return frame;
     } else
-      call Debug.log(LEVEL_INFO, PollP_SUCCESS, 0, 0, 0);
+      call Debug.log(DEBUG_LEVEL_INFO, PollP_SUCCESS, 0, 0, 0);
     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(LEVEL_IMPORTANT, PollP_RX, txFrame->handle, 0, 0);
+    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(LEVEL_IMPORTANT, PollP_TXDONE, status, txFrame->handle, 0);
+    call Debug.log(DEBUG_LEVEL_IMPORTANT, PollP_TXDONE, status, txFrame->handle, 0);
     m_numPending--;
     if (txFrame->handle != HANDLE_MLME_POLL_SUCCESS){
       // didn't receive a DATA frame from the coordinator
index 4cba26cd1f6c714eb7e410e0d17a3816411103cc..8261c7d8b422778ea535cb82d050d3641e683f60 100644 (file)
@@ -81,7 +81,7 @@ implementation
       return FAIL;
     m_promiscuousState = S_STARTING;
     call Token.request();
-    call Debug.log(LEVEL_INFO, EnableRxP_PROMISCUOUS_REQUEST, m_promiscuousState, 0, 0);
+    call Debug.log(DEBUG_LEVEL_INFO, EnableRxP_PROMISCUOUS_REQUEST, m_promiscuousState, 0, 0);
     call Debug.flush();
     return SUCCESS;
   }
@@ -96,7 +96,7 @@ implementation
     if (call PromiscuousRx.prepare() != IEEE154_SUCCESS){
       m_promiscuousState = S_IDLE;
       call Token.release();
-      call Debug.log(LEVEL_IMPORTANT, EnableRxP_RADIORX_ERROR, 0, 0, 0);
+      call Debug.log(DEBUG_LEVEL_IMPORTANT, EnableRxP_RADIORX_ERROR, 0, 0, 0);
       signal PromiscuousMode.startDone(FAIL);
     }
   }
@@ -115,7 +115,7 @@ implementation
     m_promiscuousState = S_STARTED;
     call PromiscuousRx.receive(NULL, 0);
     signal PromiscuousMode.startDone(SUCCESS);
-    call Debug.log(LEVEL_INFO, EnableRxP_PROMISCUOUS_ON, m_promiscuousState, 0, 0);
+    call Debug.log(DEBUG_LEVEL_INFO, EnableRxP_PROMISCUOUS_ON, m_promiscuousState, 0, 0);
   }
 
   event message_t* PromiscuousRx.received(message_t *frame, ieee154_reftime_t *timestamp)
@@ -151,7 +151,7 @@ implementation
     call RadioPromiscuousMode.set(FALSE);
     call Token.release();
     signal PromiscuousMode.stopDone(SUCCESS);
-    call Debug.log(LEVEL_INFO, EnableRxP_PROMISCUOUS_OFF, m_promiscuousState, 0, 0);
+    call Debug.log(DEBUG_LEVEL_INFO, EnableRxP_PROMISCUOUS_OFF, m_promiscuousState, 0, 0);
   }
 
   default event void PromiscuousMode.startDone(error_t error){}
index 189d87614f7db0def978f0aec2ae7dd5ea3f9204..ae0b7041f488954dcd866d3c9ce86cb1243f8107 100644 (file)
@@ -142,22 +142,54 @@ implementation
     }
   }
 
+  async command error_t MacTx.transmit[uint8_t client](ieee154_reftime_t *t0, uint32_t dt)
+  {
+    if (client == call ArbiterInfo.userId()) 
+      return call PhyTx.transmit(t0, dt);
+    else {
+      call Leds.led0On();
+      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.transmit[uint8_t client](ieee154_reftime_t *referenceTime, 
-      uint32_t timeOffset, uint8_t numCCA, bool ackRequest)
+  async command error_t MacTx.transmitUnslottedCsmaCa[uint8_t client](ieee154_csma_t *csmaParams)
   {
     if (client == call ArbiterInfo.userId()) 
-      return call PhyTx.transmit(referenceTime, timeOffset, numCCA, ackRequest);
+      return call PhyTx.transmitUnslottedCsmaCa(csmaParams);
     else {
       call Leds.led0On();
       return IEEE154_TRANSACTION_OVERFLOW;
     }
   }
 
-  async event void PhyTx.transmitDone(ieee154_txframe_t *frame, 
-      ieee154_reftime_t *referenceTime, bool ackPendingFlag, error_t error)   
+  async event void PhyTx.transmitUnslottedCsmaCaDone(ieee154_txframe_t *frame,
+      bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result)
   {
-    signal MacTx.transmitDone[call ArbiterInfo.userId()](frame, referenceTime, ackPendingFlag, error);
+    signal MacTx.transmitUnslottedCsmaCaDone[call ArbiterInfo.userId()](
+        frame, ackPendingFlag, csmaParams, result);
+  }
+
+  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)
+  {
+    if (client == call ArbiterInfo.userId()) 
+      return call PhyTx.transmitSlottedCsmaCa(slot0Time, dtMax, resume, remainingBackoff, csmaParams);
+    else {
+      call Leds.led0On();
+      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)
+  {
+    signal MacTx.transmitSlottedCsmaCaDone[call ArbiterInfo.userId()](
+        frame, txTime, ackPendingFlag, remainingBackoff, csmaParams, result);
   }
 
 /* ----------------------- RadioOff ----------------------- */
@@ -190,24 +222,34 @@ implementation
 
   default async event void MacTx.loadDone[uint8_t client]()
   {
-    call Debug.log(LEVEL_CRITICAL, RadioRxTxP_DEFAULT_PREPARE_TX_DONE, 0, 0, 0);
+    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 *referenceTime, bool ackPendingFlag, error_t error) 
+  default async event void MacTx.transmitDone[uint8_t client](ieee154_txframe_t *frame, ieee154_reftime_t *txTime) 
   {
-    call Debug.log(LEVEL_CRITICAL, RadioRxTxP_DEFAULT_TX_DONE, 0, 0, 0);
+    call Debug.log(DEBUG_LEVEL_CRITICAL, 1, 0, 0, 0);
   }
   default async event void MacRx.prepareDone[uint8_t client]()
   {
-    call Debug.log(LEVEL_CRITICAL, RadioRxTxP_DEFAULT_PREPARE_RX_DONE, 0, 0, 0);
+    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(LEVEL_INFO, RadioRxTxP_DEFAULT_RECEIVED, client, call ArbiterInfo.userId(), 0xff);
+    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(LEVEL_CRITICAL, RadioRxTxP_DEFAULT_OFFDONE, 0, 0, 0);
+    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);
   }
 }
index d5cd2355d1c801a3aa111c6c8bc07bfb72567ec5..cf49f22267a099020983ea55d50f187e157e2b21 100644 (file)
@@ -297,11 +297,10 @@ implementation
 
   async event void RadioTx.loadDone()
   {
-    call RadioTx.transmit(0, 0, 0, FALSE);
+    call RadioTx.transmit(NULL, 0); // transmit immediately
   }
   
-  async event void RadioTx.transmitDone(ieee154_txframe_t *frame, 
-      ieee154_reftime_t *referenceTime, bool ackPendingFlag, error_t error)
+  async event void RadioTx.transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime)
   {
     if (call RadioRx.prepare() != SUCCESS) // must succeed
       call Leds.led0On();
@@ -388,6 +387,12 @@ implementation
     nextIteration();
   }
 
+  async event void RadioTx.transmitUnslottedCsmaCaDone(ieee154_txframe_t *frame,
+      bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result){}
+
+  async event void RadioTx.transmitSlottedCsmaCaDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime, 
+      bool ackPendingFlag, uint16_t remainingBackoff, ieee154_csma_t *csmaParams, error_t result){}  
+
   default event message_t* MLME_BEACON_NOTIFY.indication ( message_t *beaconFrame ){return beaconFrame;}
   default event void MLME_SCAN.confirm    (
                           ieee154_status_t status,
index 99d3c848d6f05e4bf3e853667215fe6b01393284..bcfdecc6ed6bf574a0c793852bca4916bd9b4288 100644 (file)
@@ -135,23 +135,23 @@ implementation
 
 #ifndef IEEE154_BEACON_SYNC_DISABLED
              BeaconSynchronizeP,
-             new CsmaQueueP() as DeviceCapQueue,
-             new CsmaP(INCOMING_SUPERFRAME) as DeviceCap,
+             new FrameDispatchQueueP() as DeviceCapQueue,
+             new FrameDispatchP(INCOMING_SUPERFRAME) as DeviceCap,
 #else
              NoBeaconSynchronizeP as BeaconSynchronizeP,
-             new NoCsmaQueueP() as DeviceCapQueue,
-             new NoCsmaP() as DeviceCap,
+             new NoFrameDispatchQueueP() as DeviceCapQueue,
+             new NoFrameDispatchP(INCOMING_SUPERFRAME) as DeviceCap,
 #endif
              NoDeviceCfpP as DeviceCfp,
 
 #ifndef IEEE154_BEACON_TX_DISABLED
              BeaconTransmitP,
-             new CsmaQueueP() as CoordCapQueue,
-             new CsmaP(OUTGOING_SUPERFRAME) as CoordCap,
+             new FrameDispatchQueueP() as CoordCapQueue,
+             new FrameDispatchP(OUTGOING_SUPERFRAME) as CoordCap,
 #else
              NoBeaconTransmitP as BeaconTransmitP,
-             new NoCsmaQueueP() as CoordCapQueue,
-             new NoCsmaP() as CoordCap,
+             new NoFrameDispatchQueueP() as CoordCapQueue,
+             new NoFrameDispatchP(OUTGOING_SUPERFRAME) as CoordCap,
 #endif
              NoCoordCfpP as CoordCfp,
 
@@ -272,7 +272,7 @@ implementation
   BeaconTransmitP.IsBroadcastReady -> CoordBroadcastP.IsBroadcastReady;
   BeaconTransmitP.TimeCalc -> PibP;
   BeaconTransmitP.Leds = Leds;
-  BeaconTransmitP.Debug = Ieee802154Debug[START_CLIENT];
+  BeaconTransmitP.Debug = Ieee802154Debug[DEBUG_BEACON_TRANSMIT_ID];
   BeaconTxRadioClient.TransferTo -> CoordBroadcastRadioClient.TransferFrom;
 
 /* ------------------ Beacon Tracking (MLME-SYNC) ------------------ */
@@ -290,7 +290,7 @@ implementation
   BeaconSynchronizeP.BeaconRx -> SyncRadioClient;
   BeaconSynchronizeP.RadioOff -> SyncRadioClient;
   BeaconSynchronizeP.IsBeaconEnabledPAN -> PibP.IsBeaconEnabledPAN;
-  BeaconSynchronizeP.DataRequest -> PollP.DataRequest[SYNC_CLIENT];
+  BeaconSynchronizeP.DataRequest -> PollP.DataRequest[SYNC_POLL_CLIENT];
   BeaconSynchronizeP.Token -> SyncRadioClient;
   BeaconSynchronizeP.IsTokenRequested -> SyncRadioClient;
   BeaconSynchronizeP.TokenTransferred -> SyncRadioClient;
@@ -298,7 +298,7 @@ implementation
   BeaconSynchronizeP.TimeCalc -> PibP;
   BeaconSynchronizeP.CoordRealignmentRx -> DeviceCap.FrameRx[FC1_FRAMETYPE_CMD + CMD_FRAME_COORDINATOR_REALIGNMENT];
   BeaconSynchronizeP.Leds = Leds;
-  BeaconSynchronizeP.Debug = Ieee802154Debug[SYNC_CLIENT];
+  BeaconSynchronizeP.Debug = Ieee802154Debug[DEBUG_BEACON_SYNCHRONIZE_ID];
   SyncRadioClient.TransferTo -> DeviceCapRadioClient.TransferFrom;
 
 /* -------------------- Association (MLME-ASSOCIATE) -------------------- */
@@ -308,7 +308,7 @@ implementation
   AssociateP.AssociationRequestTx -> DeviceCapQueue.FrameTx[unique(CAP_TX_CLIENT)];
   AssociateP.AssociationResponseExtracted -> DeviceCap.FrameExtracted[FC1_FRAMETYPE_CMD + CMD_FRAME_ASSOCIATION_RESPONSE];
   AssociateP.AssociationResponseTx -> IndirectTxP.FrameTx[unique(INDIRECT_TX_CLIENT)];
-  AssociateP.DataRequest -> PollP.DataRequest[ASSOCIATE_CLIENT];
+  AssociateP.DataRequest -> PollP.DataRequest[ASSOCIATE_POLL_CLIENT];
   AssociateP.ResponseTimeout = Timer3;
   AssociateP.TxFramePool -> TxFramePoolP;
   AssociateP.TxControlPool -> TxControlPoolP;
@@ -317,7 +317,7 @@ implementation
   AssociateP.FrameUtility -> PibP;
   AssociateP.Frame -> PibP;
   AssociateP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress;
-  AssociateP.Debug = Ieee802154Debug[ASSOCIATE_CLIENT];
+  AssociateP.Debug = Ieee802154Debug[DEBUG_ASSOCIATE_ID];
 
 /* --------------- Disassociation (MLME-DISASSOCIATE) --------------- */
 
@@ -337,7 +337,7 @@ implementation
   DisassociateP.FrameUtility -> PibP;
   DisassociateP.Frame -> PibP;
   DisassociateP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress;
-  DisassociateP.Debug = Ieee802154Debug[DISASSOCIATE_CLIENT];
+  DisassociateP.Debug = Ieee802154Debug[DEBUG_DISASSOCIATE_ID];
 
 /* ------------------ Data Transmission (MCPS-DATA) ------------------- */
 
@@ -372,7 +372,7 @@ implementation
   PollP.FrameUtility -> PibP;
   PollP.TxFramePool -> TxFramePoolP;
   PollP.TxControlPool -> TxControlPoolP;
-  PollP.Debug = Ieee802154Debug[POLL_CLIENT];
+  PollP.Debug = Ieee802154Debug[DEBUG_POLL_ID];
   PollP.MLME_GET -> PibP;
   PollP.LocalExtendedAddress -> PibP.GetLocalExtendedAddress;
 
@@ -386,7 +386,7 @@ implementation
   IndirectTxP.IndirectTxTimeout = Timer4;
   IndirectTxP.TimeCalc -> PibP;
   IndirectTxP.Leds = Leds;
-  IndirectTxP.Debug = Ieee802154Debug[INDIRECTTX_DEBUG_CLIENT];
+  IndirectTxP.Debug = Ieee802154Debug[DEBUG_INDIRECTTX_ID];
 
 /* ---------------------------- Realignment --------------------------- */
 
@@ -424,7 +424,6 @@ implementation
   
   components new RadioClientC() as DeviceCapRadioClient;
   PibP.CapReset -> DeviceCap;
-  DeviceCap.Random = Random;
   DeviceCap.CapEndAlarm = Alarm3;
   DeviceCap.BLEAlarm = Alarm4;
   DeviceCap.IndirectTxWaitAlarm = Alarm5;
@@ -440,6 +439,7 @@ implementation
   DeviceCap.BLELen -> BeaconSynchronizeP.BLELen;
   DeviceCap.IsRxBroadcastPending -> BeaconSynchronizeP.IsRxBroadcastPending;
   DeviceCap.IsRxEnableActive -> RxEnableP.IsRxEnableActive;
+  DeviceCap.GetIndirectTxFrame -> IndirectTxP;
   DeviceCap.RxEnableStateChange -> RxEnableP.RxEnableStateChange;  
   DeviceCap.IsTrackingBeacons -> BeaconSynchronizeP.IsTrackingBeacons;  
   DeviceCap.FrameUtility -> PibP;
@@ -449,7 +449,7 @@ implementation
   DeviceCap.IsBeaconEnabledPAN -> PibP.IsBeaconEnabledPAN;
   DeviceCap.MLME_GET -> PibP;
   DeviceCap.MLME_SET -> PibP.MLME_SET;
-  DeviceCap.Debug = Ieee802154Debug[DEVICE_CAP_CLIENT];
+  DeviceCap.Debug = Ieee802154Debug[DEBUG_FRAME_DISPATCH_DEVICE_ID];
   DeviceCap.TimeCalc -> PibP;
   DeviceCap.Leds = Leds;
   DeviceCapRadioClient.TransferTo -> DeviceCfpRadioClient.TransferFrom;
@@ -459,7 +459,6 @@ implementation
   components new RadioClientC() as CoordCapRadioClient, 
              new BackupP(ieee154_cap_frame_backup_t);
   PibP.CapReset -> CoordCap;
-  CoordCap.Random = Random;
   CoordCap.CapEndAlarm = Alarm7;
   CoordCap.BLEAlarm = Alarm8;
   CoordCap.Token -> CoordCapRadioClient;
@@ -472,6 +471,7 @@ implementation
   CoordCap.IsBLEActive -> BeaconTransmitP.IsBLEActive;
   CoordCap.BLELen -> BeaconTransmitP.BLELen;
   CoordCap.IsRxEnableActive -> RxEnableP.IsRxEnableActive;
+  CoordCap.GetIndirectTxFrame -> IndirectTxP;
   CoordCap.RxEnableStateChange -> RxEnableP.RxEnableStateChange;  
   CoordCap.IsTrackingBeacons -> BeaconSynchronizeP.IsTrackingBeacons;  
   CoordCap.FrameUtility -> PibP;
@@ -481,7 +481,7 @@ implementation
   CoordCap.IsBeaconEnabledPAN -> PibP.IsBeaconEnabledPAN;
   CoordCap.MLME_GET -> PibP;
   CoordCap.MLME_SET -> PibP.MLME_SET;
-  CoordCap.Debug = Ieee802154Debug[COORD_CAP_CLIENT];
+  CoordCap.Debug = Ieee802154Debug[DEBUG_FRAME_DISPATCH_COORD_ID];
   CoordCap.TimeCalc -> PibP;
   CoordCap.Leds = Leds;
   CoordCapRadioClient.TransferTo -> CoordCfpRadioClient.TransferFrom;
@@ -540,7 +540,7 @@ implementation
   PromiscuousModeP.PromiscuousRx -> PromiscuousModeRadioClient;
   PromiscuousModeP.RadioOff -> PromiscuousModeRadioClient;
   PromiscuousModeP.RadioPromiscuousMode = RadioPromiscuousMode;
-  PromiscuousModeP.Debug = Ieee802154Debug[PROMISCUOUS_MODE_CLIENT];
+  PromiscuousModeP.Debug = Ieee802154Debug[DEBUG_PROMISCUOUSMODE_ID];
 
 /* --------------------------- MLME-RX-ENABLE  ------------------------ */
 
@@ -557,7 +557,7 @@ implementation
   RxEnableP.WasRxEnabled -> DeviceCap.WasRxEnabled;
   RxEnableP.WasRxEnabled -> CoordCap.WasRxEnabled;
   RxEnableP.RxEnableTimer = Timer5;
-  RxEnableP.Debug = Ieee802154Debug[RXENABLE_CLIENT];
+  RxEnableP.Debug = Ieee802154Debug[DEBUG_RXENABLE_ID];
 
 /* ------------------------------- PIB -------------------------------- */
 
@@ -578,5 +578,5 @@ implementation
   RadioControlP.PhyRadioOff = RadioOff;
   RadioControlP.RadioPromiscuousMode -> PromiscuousModeP;
   RadioControlP.Leds = Leds;
-  RadioControlP.Debug = Ieee802154Debug[RADIORXTX_CLIENT];
+  RadioControlP.Debug = Ieee802154Debug[DEBUG_RADIOCONTROL_ID];
 }
index 8169f913029abb5509b2f982a05c99fcf378907e..41bf8fdf0cbffe32a9de5d1ccef16261b436b8b3 100644 (file)
 #ifndef __TKN154_DEBUG_H
 #define __TKN154_DEBUG_H
 
-#define LEVEL_INFO 0
-#define LEVEL_IMPORTANT 50
-#define LEVEL_CRITICAL 100
-
-#define RadioRxTxP_ACQUIRED         0
-#define RadioRxTxP_NOT_ACQUIRED     1
-#define RadioRxTxP_TRANSFERRED      2
-#define RadioRxTxP_NOT_TRANSFERRED  3
-#define RadioRxTxP_RELEASED         4
-#define RadioRxTxP_NOT_RELEASED     5
-#define RadioRxTxP_TRANSFER_REQUEST 6
-#define RadioRxTxP_DEFAULT_PREPARE_TX_DONE 7
-#define RadioRxTxP_DEFAULT_TX_DONE         8
-#define RadioRxTxP_DEFAULT_PREPARE_RX_DONE 9
-#define RadioRxTxP_DEFAULT_RECEIVED        10
-#define RadioRxTxP_DEFAULT_OFFDONE         11
-#define RadioRxTxP_DEFAULT_TRANSFERRED     12 
-#define RadioRxTxP_DEFAULT_TRANSFERREQUEST 13
-#define RadioRxTxP_ASK_ISOWNER             14
-#define RadioRxTxP_RX_NOOWNER              15
-#define RadioRxTxP_DEFAULT_CANCEL_TX_DONE  16
-#define RadioRxTxP_DEFAULT_CANCEL_RX_DONE  17
-
-#define SyncP_BEACON_MISSED_1 0
-#define SyncP_BEACON_MISSED_2 1
-#define SyncP_BEACON_MISSED_3 2
-#define SyncP_TRACK_ALARM     3
-#define SyncP_INVALID_PARAM   4
-#define SyncP_RX_ON           5
-#define SyncP_INTERNAL_ERROR  6
-#define SyncP_BEACON_RX       7
-#define SyncP_RADIO_BUSY      8
-#define SyncP_LOST_SYNC       9
-#define SyncP_RX_PACKET       10
-#define SyncP_NEXT_RX_TIME    11
-#define SyncP_SWITCHOFF       12
-#define SyncP_RX_GARBAGE      13
-#define SyncP_GOT_RESOURCE    14
-#define SyncP_RELEASE_RESOURCE 15
-#define SyncP_RESOURCE_REQUEST  16
-#define SyncP_TRANSFER_RESOURCE 17
-#define SyncP_PREPARE_RX      18
-#define SyncP_REQUEST  19
-#define SyncP_UPDATING  20
-#define SyncP_PREPARE_RX_DONE     21
-#define SyncP_INVALID_TIMESTAMP     22
-#define SyncP_RX_BEACON       SyncP_RX_PACKET
-
-#define StartP_BEACON_TRANSMITTED 0
-#define StartP_UPDATE_STATE   1
-#define StartP_REQUEST        2
-#define StartP_OWNER_TOO_FAST 3
-#define StartP_BEACON_UPDATE  4
-#define StartP_BEACON_UPDATE_2 5
-#define StartP_PREPARE_TX     6
-#define StartP_PREPARE_TXDONE 7
-#define StartP_SKIPPED_BEACON    8
-#define StartP_GOT_RESOURCE    9
-#define StartP_TRANSMIT    10
-
 #define PollP_ALLOC_FAIL1     0
 #define PollP_ALLOC_FAIL2     1
 #define PollP_INTERNAL_POLL   2
 #define CoordCapTransmitP_FINISH_TX          5
 #define CoordCapTransmitP_RADIO_RX           6
 
-#define Phy_RX_CANCEL      0
-#define Phy_RX_NOW         1
-#define Phy_LOAD_TX_FIFO   2
-#define Phy_LOAD_TX_FIFO_DONE 3
-#define Phy_LOAD_TX_CANCEL 4
-#define Phy_LOAD_TX_NOW 5
-#define Phy_LOAD_TX_RX_NOW 6
-#define Phy_SEND_DONE 7
-#define Phy_SPI_GRANTED 8
-#define Phy_RADIO_OFF 9
-#define Phy_RADIO_OFF_DONE 10
-#define Phy_RADIO_PREPARE_RX 11
-#define Phy_RADIO_PREPARE_TX 12
-#define Phy_RADIO_TX_DONE 13
-#define Phy_RADIO_RECEIVED 14
 
 #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
-  START_CLIENT = 0,
-  COORD_CAP_CLIENT = 1,
-  COORD_CFP_CLIENT = 2,
-
-  SYNC_CLIENT = 3,
-  DEVICE_CAP_CLIENT = 4,
-  DEVICE_CFP_CLIENT = 5,
-
-  SCAN_CLIENT = 6,
-
-  RADIORXTX_CLIENT = 7,
-  PIBDATABASE_CLIENT = 8,
-  ASSOCIATE_CLIENT = 9,
-  DISASSOCIATE_CLIENT = 10,
-  DEVICECAPQUEUE_CLIENT = 11,
-  INDIRECTTX_DEBUG_CLIENT = 12,
-  DATA_CLIENT = 13,
-  POLL_CLIENT = 14,
-  RXENABLE_CLIENT = 15,
-  PROMISCUOUS_MODE_CLIENT = 16,
-
-  PHY_CLIENT = 17,
-  PHY_TXCLIENT = 18,
-  PHY_RXCLIENT = 19,
+  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 {
@@ -223,7 +151,7 @@ typedef nx_struct serial_debug_msg {
 } serial_debug_msg_t;
 
 #ifndef SERIAL_DBG_MSGBUF_SIZE
-#define SERIAL_DBG_MSGBUF_SIZE 25
+#define SERIAL_DBG_MSGBUF_SIZE  150
 #endif
 
 enum {
index 8edccc00a2a163541aadc1eafaa3e26d020eb88e..6f1d3a90de9e0cba78bdc773c1b5d856851cf350 100644 (file)
@@ -128,6 +128,8 @@ enum {
   FC2_FRAME_VERSION_MASK      = 0x30,
 };
 
+#define SYNC_POLL_CLIENT unique("PollP.client")
+#define ASSOCIATE_POLL_CLIENT unique("PollP.client")
 #define CAP_TX_CLIENT "CapQueueP.FrameTx.client"
 #define INDIRECT_TX_CLIENT "IndirectTx.client"
 #define IEEE802154_RADIO_RESOURCE "RadioRxTxP.resource"
@@ -164,16 +166,17 @@ 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
+  uint8_t macMaxCsmaBackoffs; // maximum number of allowed backoffs
+  uint8_t NB;                 // number of backoff during current transmission
+} ieee154_csma_t;
 
 typedef struct {
   ieee154_txframe_t *frame;
-  ieee154_macMaxBE_t BE;
-  ieee154_macMaxCSMABackoffs_t allowedBackoffs;
-  ieee154_macMaxBE_t macMaxBE;
-  ieee154_macMinBE_t macMinBE;
-  uint8_t NB;
-  uint16_t backoff;
-  uint16_t backoffElapsed;
+  ieee154_csma_t csmaParams;
   uint32_t transactionTime;
 } ieee154_cap_frame_backup_t;
 
index 9d6a059f694f1e8ca77472e1faafd6c3d4627e54..7bed6f11b30d4b7d8bb0ee59c2de70bc2eeb0a97 100644 (file)
@@ -124,8 +124,13 @@ implementation
 
   async event void BeaconTx.loadDone() {}
 
-  async event void BeaconTx.transmitDone(ieee154_txframe_t *frame, 
-      ieee154_reftime_t *referenceTime, bool pendingFlag, error_t error) { }
+  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 BeaconTx.transmitSlottedCsmaCaDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime, 
+      bool ackPendingFlag, uint16_t remainingBackoff, ieee154_csma_t *csmaParameters, error_t result){}
 
   command error_t IEEE154TxBeaconPayload.setBeaconPayload(void *beaconPayload, uint8_t length) { return ESIZE; }
 
index 76974d2d9e2bf492a1072471b48ef8b7423d9a59..5ea629328d749c123c722e43d0aa99b5c8de30bb 100644 (file)
@@ -124,8 +124,7 @@ implementation
   }  
 
   async event void RadioTx.loadDone(){}
-  async event void RadioTx.transmitDone(ieee154_txframe_t *frame, 
-      ieee154_reftime_t *referenceTime, bool ackPendingFlag, error_t error){}
+  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;}
@@ -138,4 +137,8 @@ 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/NoCsmaP.nc b/tos/lib/mac/tkn154/dummies/NoCsmaP.nc
deleted file mode 100644 (file)
index 7137064..0000000
+++ /dev/null
@@ -1,127 +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 <hauer@tkn.tu-berlin.de>
- * ========================================================================
- */
-
-#include "TKN154_PHY.h"
-#include "TKN154_MAC.h"
-
-generic module NoCsmaP()
-{
-  provides
-  {
-    interface Init as Reset;
-    interface FrameTx as FrameTx;
-    interface FrameRx as FrameRx[uint8_t frameType];
-    interface FrameExtracted as FrameExtracted[uint8_t frameType];
-    interface FrameTxNow as BroadcastTx;
-    interface Notify<bool> as WasRxEnabled;
-    interface Notify<bool> as FindBeacon;
-  }
-  uses
-  {
-    interface Random;
-    interface Alarm<TSymbolIEEE802154,uint32_t> as CapEndAlarm;
-    interface Alarm<TSymbolIEEE802154,uint32_t> as BLEAlarm;
-    interface Alarm<TSymbolIEEE802154,uint32_t> as IndirectTxWaitAlarm;
-    interface Alarm<TSymbolIEEE802154,uint32_t> as BroadcastAlarm;
-    interface Resource as Token;
-    interface ResourceTransfer as TokenToCfp;
-    interface ResourceTransferred as TokenTransferred;
-    interface ResourceRequested as TokenRequested;
-    interface GetNow<bool> as IsTokenRequested;
-    interface GetNow<uint32_t> as CapStart; 
-    interface GetNow<ieee154_reftime_t*> as CapStartRefTime; 
-    interface GetNow<uint32_t> as CapLen; 
-    interface GetNow<bool> as IsBLEActive; 
-    interface GetNow<uint16_t> as BLELen; 
-    interface GetNow<bool> as IsRxEnableActive; 
-    interface GetNow<bool> as IsRxBroadcastPending; 
-    interface Notify<bool> as RxEnableStateChange;
-    interface GetNow<bool> as IsTrackingBeacons;
-    interface FrameUtility;
-    interface RadioTx;
-    interface RadioRx;
-    interface RadioOff;
-    interface GetNow<bool> as IsBeaconEnabledPAN;
-    interface MLME_GET;
-    interface MLME_SET;
-    interface Ieee802154Debug as Debug;
-    interface TimeCalc;
-    interface Leds;
-    interface SetNow<ieee154_cap_frame_backup_t*> as FrameBackup;
-    interface GetNow<ieee154_cap_frame_backup_t*> as FrameRestore;
-  }
-}
-implementation
-{
-  command error_t Reset.init()
-  {
-    return SUCCESS;
-  }
-
-  async event void TokenTransferred.transferred()
-  {
-    call TokenToCfp.transfer();
-  }
-
-  command ieee154_status_t FrameTx.transmit(ieee154_txframe_t *frame)
-  {
-    return IEEE154_TRANSACTION_OVERFLOW;
-  }
-
-  async event void RadioTx.loadDone(){ }
-  async event void RadioOff.offDone(){ }
-  async event void RadioRx.prepareDone(){ }
-
-  async event void CapEndAlarm.fired(){ }
-  async event void BLEAlarm.fired(){ }
-  event void RxEnableStateChange.notify(bool x){ }
-  async event void BroadcastAlarm.fired(){ }
-
-  async event void IndirectTxWaitAlarm.fired() { }
-
-  async event void RadioTx.transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t
-       *referenceTime, bool ackPendingFlag, error_t error) { }
-
-  event message_t* RadioRx.received(message_t* frame, ieee154_reftime_t* referenceTime) { return frame; }
-  async command ieee154_status_t  BroadcastTx.transmitNow(ieee154_txframe_t *frame){ return IEEE154_TRANSACTION_OVERFLOW; }
-
-  async event void TokenRequested.requested() {}
-  async event void TokenRequested.immediateRequested() {}
-  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/dummies/NoCsmaQueueP.nc b/tos/lib/mac/tkn154/dummies/NoCsmaQueueP.nc
deleted file mode 100644 (file)
index b8e7554..0000000
+++ /dev/null
@@ -1,69 +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 <hauer@tkn.tu-berlin.de>
- * ========================================================================
- */
-#include "TKN154_MAC.h"
-generic module NoCsmaQueueP()
-{
-  provides
-  {
-    interface Init;
-    interface FrameTx[uint8_t client];
-    interface FrameRx as FrameExtracted[uint8_t client];
-    interface Purge;
-  }
-  uses
-  {
-    interface Queue<ieee154_txframe_t*>; 
-    interface FrameTx as FrameTxCsma;
-    interface FrameRx as SubFrameExtracted;
-  }
-}
-implementation
-{
-  command error_t Init.init()
-  {
-    return SUCCESS;
-  }
-
-  command ieee154_status_t FrameTx.transmit[uint8_t client](ieee154_txframe_t *data)
-  {
-    return IEEE154_TRANSACTION_OVERFLOW;
-  }
-
-  event void FrameTxCsma.transmitDone(ieee154_txframe_t *data, ieee154_status_t status) { }
-
-  event message_t* SubFrameExtracted.received(message_t* frame) { return frame; }
-
-  command ieee154_status_t Purge.purge(uint8_t msduHandle) { return IEEE154_INVALID_HANDLE; }
-}
diff --git a/tos/lib/mac/tkn154/dummies/NoDeviceCapQueueP.nc b/tos/lib/mac/tkn154/dummies/NoDeviceCapQueueP.nc
deleted file mode 100644 (file)
index 31c9a28..0000000
+++ /dev/null
@@ -1,63 +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 <hauer@tkn.tu-berlin.de>
- * ========================================================================
- */
-#include "TKN154_MAC.h"
-module NoDeviceCapQueueP
-{
-  provides
-  {
-    interface Init;
-    interface FrameTx[uint8_t client];
-    interface FrameRx as FrameExtracted[uint8_t client];
-    interface Purge;
-  }
-  uses
-  {
-    interface Queue<ieee154_txframe_t*>; 
-    interface FrameTx as DeviceCapTx;
-    interface FrameRx as SubFrameExtracted;
-  }
-}
-implementation
-{
-  command error_t Init.init() { return SUCCESS; }
-
-  command ieee154_status_t FrameTx.tx[uint8_t client](ieee154_txframe_t *data) { return TRANSACTION_OVERFLOW; }
-
-  event void DeviceCapTx.transmitDone(ieee154_txframe_t *data, ieee154_status_t status) { }
-
-  event message_t* SubFrameExtracted.received(message_t* data) { return data; }
-
-  command ieee154_status_t Purge.purge(uint8_t msduHandle) { return INVALID_HANDLE; }
-}
index 0cda4b605558976d5cba939732fe8857f33fd976..0b3dfc7924525cb47bc0f0099aa17c14d15f3765 100644 (file)
@@ -106,8 +106,7 @@ implementation
   async event void RadioOff.offDone() {}
 
   async event void RadioTx.loadDone(){}
-  async event void RadioTx.transmitDone(ieee154_txframe_t *frame, 
-      ieee154_reftime_t *referenceTime, bool ackPendingFlag, error_t error){}
+  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;}
@@ -120,4 +119,9 @@ 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/NoFrameDispatchP.nc b/tos/lib/mac/tkn154/dummies/NoFrameDispatchP.nc
new file mode 100644 (file)
index 0000000..eec5166
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2008, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright 
+ *   notice, this list of conditions and the following disclaimer in the 
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names 
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+#include "TKN154_PHY.h"
+#include "TKN154_MAC.h"
+
+generic module NoFrameDispatchP(uint8_t superframeDirection)
+{
+  provides
+  {
+    interface Init as Reset;
+    interface FrameTx as FrameTx;
+    interface FrameRx as FrameRx[uint8_t frameType];
+    interface FrameExtracted as FrameExtracted[uint8_t frameType];
+    interface FrameTxNow as BroadcastTx;
+    interface Notify<bool> as WasRxEnabled;
+    interface Notify<bool> as FindBeacon;
+  }
+  uses
+  {
+    interface Alarm<TSymbolIEEE802154,uint32_t> as CapEndAlarm;
+    interface Alarm<TSymbolIEEE802154,uint32_t> as BLEAlarm;
+    interface Alarm<TSymbolIEEE802154,uint32_t> as IndirectTxWaitAlarm;
+    interface Alarm<TSymbolIEEE802154,uint32_t> as BroadcastAlarm;
+    interface Resource as Token;
+    interface GetNow<bool> as IsTokenRequested;
+    interface ResourceTransfer as TokenToCfp;
+    interface ResourceTransferred as TokenTransferred;
+    interface GetNow<uint32_t> as CapStart; 
+    interface GetNow<ieee154_reftime_t*> as CapStartRefTime; 
+    interface GetNow<uint32_t> as CapLen; 
+    interface GetNow<bool> as IsBLEActive; 
+    interface GetNow<uint16_t> as BLELen; 
+    interface GetNow<bool> as IsRxBroadcastPending; 
+    interface GetNow<bool> as IsRxEnableActive; 
+    interface Get<ieee154_txframe_t*> as GetIndirectTxFrame; 
+    interface Notify<bool> as RxEnableStateChange;
+    interface GetNow<bool> as IsTrackingBeacons;
+    interface FrameUtility;
+    interface RadioTx;
+    interface RadioRx;
+    interface RadioOff;
+    interface GetNow<bool> as IsBeaconEnabledPAN;
+    interface MLME_GET;
+    interface MLME_SET;
+    interface Ieee802154Debug as Debug;
+    interface TimeCalc;
+    interface Leds;
+    interface SetNow<ieee154_cap_frame_backup_t*> as FrameBackup;
+    interface GetNow<ieee154_cap_frame_backup_t*> as FrameRestore;
+  }
+}
+implementation
+{
+  command error_t Reset.init()
+  {
+    return SUCCESS;
+  }
+
+  async event void TokenTransferred.transferred()
+  {
+    call TokenToCfp.transfer();
+  }
+
+  command ieee154_status_t FrameTx.transmit(ieee154_txframe_t *frame)
+  {
+    return IEEE154_TRANSACTION_OVERFLOW;
+   }
+
+  async event void RadioTx.loadDone(){ }
+  async event void RadioOff.offDone(){ }
+  async event void RadioRx.prepareDone(){ }
+
+  async event void CapEndAlarm.fired(){ }
+  async event void BLEAlarm.fired(){ }
+  event void RxEnableStateChange.notify(bool whatever){ }
+  async event void BroadcastAlarm.fired(){ }
+
+  async event void IndirectTxWaitAlarm.fired() { }
+  
+  async event void RadioTx.transmitUnslottedCsmaCaDone(ieee154_txframe_t *frame,
+      bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result)
+  {
+  }
+
+  async event void RadioTx.transmitSlottedCsmaCaDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime, 
+      bool ackPendingFlag, uint16_t remainingBackoff, ieee154_csma_t *csmaParams, error_t result)
+  {
+  }
+
+  void transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime, 
+      bool ackPendingFlag, ieee154_csma_t *csmaParams, error_t result)
+  {
+  }
+
+  event message_t* RadioRx.received(message_t* frame, ieee154_reftime_t *timestamp)
+  {
+    return frame;
+  }
+
+  async command ieee154_status_t BroadcastTx.transmitNow(ieee154_txframe_t *frame) 
+  {
+    return IEEE154_TRANSACTION_OVERFLOW;
+  }
+
+  event void Token.granted()
+  {
+  }
+
+  async event void RadioTx.transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime){}
+
+  default event void FrameTx.transmitDone(ieee154_txframe_t *data, ieee154_status_t status){}
+  default event message_t* FrameRx.received[uint8_t client](message_t* data){return data;}
+  default async command bool IsRxEnableActive.getNow(){return FALSE;}
+
+  default async command void IndirectTxWaitAlarm.start(uint32_t dt){call Leds.led0On();}
+  default async command void IndirectTxWaitAlarm.stop(){call Leds.led0On();}
+  default async command void IndirectTxWaitAlarm.startAt(uint32_t t0, uint32_t dt){call Leds.led0On();}
+  
+  default async command void BroadcastAlarm.start(uint32_t dt){call Leds.led0On();}
+  default async command void BroadcastAlarm.stop(){call Leds.led0On();}
+  default async command void BroadcastAlarm.startAt(uint32_t t0, uint32_t dt){call Leds.led0On();}
+
+  default async command bool IsRxBroadcastPending.getNow(){ return FALSE;}
+  default async event void BroadcastTx.transmitNowDone(ieee154_txframe_t *frame, ieee154_status_t status){}
+  default event message_t* FrameExtracted.received[uint8_t client](message_t* msg, ieee154_txframe_t *txFrame){return msg;}
+  default async command error_t FrameBackup.setNow(ieee154_cap_frame_backup_t* val ){return FAIL;}
+  default async command ieee154_cap_frame_backup_t* FrameRestore.getNow(){return NULL;}
+
+  command error_t WasRxEnabled.enable(){return FAIL;}
+  command error_t WasRxEnabled.disable(){return FAIL;}
+  command error_t FindBeacon.enable(){return FAIL;}
+  command error_t FindBeacon.disable(){return FAIL;}
+}
diff --git a/tos/lib/mac/tkn154/dummies/NoFrameDispatchQueueP.nc b/tos/lib/mac/tkn154/dummies/NoFrameDispatchQueueP.nc
new file mode 100644 (file)
index 0000000..54671cd
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2008, Technische Universitaet Berlin
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright 
+ *   notice, this list of conditions and the following disclaimer in the 
+ *   documentation and/or other materials provided with the distribution.
+ * - Neither the name of the Technische Universitaet Berlin nor the names 
+ *   of its contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * - Revision -------------------------------------------------------------
+ * $Revision$
+ * $Date$
+ * @author Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+#include "TKN154_MAC.h"
+generic module NoFrameDispatchQueueP() {
+  provides
+  {
+    interface Init as Reset;
+    interface FrameTx[uint8_t client];
+    interface FrameRx as FrameExtracted[uint8_t client];
+    interface Purge;
+  } uses {
+    interface Queue<ieee154_txframe_t*>;
+    interface FrameTx as FrameTxCsma;
+    interface FrameRx as SubFrameExtracted;
+  }
+}
+implementation
+{
+  command error_t Reset.init() { return SUCCESS; }
+
+  command ieee154_status_t FrameTx.transmit[uint8_t client](ieee154_txframe_t *txFrame)
+  {
+    return IEEE154_TRANSACTION_OVERFLOW;
+  }
+
+  event void FrameTxCsma.transmitDone(ieee154_txframe_t *txFrame, ieee154_status_t status) { }
+
+  event message_t* SubFrameExtracted.received(message_t* frame) { return frame; }
+
+  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)
+  {
+    return IEEE154_INVALID_HANDLE;
+  }
+  
+  default event void Purge.purgeDone(ieee154_txframe_t *txFrame, ieee154_status_t status){}
+}
index 38a7697a0c56a5beb77849ae96ddd1f56fa04c75..2ff5a0454fdb90cb795d8e93ef2dffc4bd01e3cc 100644 (file)
@@ -96,9 +96,14 @@ implementation
   }
 
   async event void RadioTx.loadDone() { }
-  
-  async event void RadioTx.transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *t0, 
-      bool ackPendingFlag, error_t error){}
+
+  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.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() { }
 
index 5870943857f8b4fae6ccc18b2f2118fe26cd5694..6c2cf76c41171c1c391b78c4ea59849ee1ef76cd 100644 (file)
@@ -44,12 +44,12 @@ interface MCPS_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 (<code>frame<\code>
-   * parameter) and can be accessed through the <code>IEEE154Frame<\code
+   * The MSDU is the payload portion of a message_t (<tt>frame</tt>
+   * parameter) and can be accessed through the <tt>IEEE154Frame</tt
    * interface. In contrast to the standard interface definition address 
    * information is not passed as separate parameters; instead, the 
-   * address information is already part of the <code>frame<\code>, 
-   * i.e. it must have been set (through the <code>IEEE154Frame<\code
+   * address information is already part of the <tt>frame</tt>, 
+   * i.e. it must have been set (through the <tt>IEEE154Frame</tt
    * interface) before this command is called.
    * 
    * If this command returns IEEE154_SUCCESS, then the confirm event
@@ -93,7 +93,7 @@ interface MCPS_DATA
 
   /**
    * Indicates the arrival of a frame. Address information can be accessed 
-   * through the <code>IEEE154Frame<\code> interface.
+   * through the <tt>IEEE154Frame</tt> interface.
    * 
    * @return A frame buffer for the stack to use for the next received frame
    */
index c7e81d940b0c1c6389c9e41ff734dc97f50a80e1..3b9d9dd682d84b8110eb3d029683b08e56d820d9 100644 (file)
@@ -43,8 +43,8 @@ interface MLME_BEACON_NOTIFY {
    * beacon payload is not empty.
    *
    * The beacon parameters can be accessed through the 
-   * <code>IEEE154BeaconFrame<\code> interface. The 
-   * <code>IEEE154Frame<\code> interface can be used to
+   * <tt>IEEE154BeaconFrame<\tt> interface. The 
+   * <tt>IEEE154Frame<\tt> interface can be used to
    * inspect the addressing fields in the MAC header.
    *
    * @param beacon The beacon frame
index 7378323080eb005e5ece0f845302817d25664c5c..29efcc3a7b32ada2bce02b727669d5843952cb9e 100644 (file)
@@ -39,7 +39,7 @@
  * command per attribute (and there are no confirm events). 
  *
  * NOTE: for the attributes macBeaconPayload (0x45) and
- * macBeaconPayloadLength (0x46) use the <code>IEEE154TxBeaconPayload <\code
+ * macBeaconPayloadLength (0x46) use the <tt>IEEE154TxBeaconPayload <\tt
  * interface; for promiscuous mode there is a separate (SplitControl)
  * interface. 
  **/
@@ -87,7 +87,7 @@ interface MLME_GET {
   command ieee154_macBattLifeExtPeriods_t macBattLifeExtPeriods();
 
   /* macBeaconPayload (0x45) and macBeaconPayloadLength (0x46) are read
-   * through the <code>IEEE154TxBeaconPayload<\code> interface. */
+   * through the <tt>IEEE154TxBeaconPayload<\tt> interface. */
 
   /** @return PIB attribute macBeaconOrder (0x47) */
   command ieee154_macBeaconOrder_t macBeaconOrder();
index b2ba46ee5e3699a13d5cff77c9940ff5d8c04b9b..2935fc01e5106223dfd767def8cbcec41baaae39 100644 (file)
@@ -40,7 +40,7 @@
  * command per attribute (and there are no confirm events). 
  *
  * NOTE: for the attributes macBeaconPayload (0x45) and
- * macBeaconPayloadLength (0x46) use the <code>IEEE154TxBeaconPayload <\code
+ * macBeaconPayloadLength (0x46) use the <tt>IEEE154TxBeaconPayload <\tt
  * interface; for promiscuous mode there is a separate (SplitControl)
  * interface. 
  **/
@@ -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 <code>IEEE154TxBeaconPayload<\code> interface. */
+   * through the <tt>IEEE154TxBeaconPayload<\tt> interface. */
 
   /** @param value new PIB attribute value for macBeaconOrder (0x47) 
    *  @returns IEEE154_SUCCESS if PIB attribute was updated, INVALID_PARAMETER if 
@@ -138,7 +138,7 @@ interface MLME_SET {
   command ieee154_status_t macPANId(ieee154_macPANId_t value);
 
   /* macPromiscuousMode (0x51) is (re-)set through the 
-   * <code>PromiscuousMode<\code> (SplitControl) interface. */
+   * <tt>PromiscuousMode<\tt> (SplitControl) interface. */
 
   /** @param value new PIB attribute value for macRxOnWhenIdle (0x52) 
    *  @returns IEEE154_SUCCESS if PIB attribute was updated, INVALID_PARAMETER if 
index fb17fe46746afa8c9862a21aba0ad4729198b9ab..a3476cb243b96e7bece6bcbe2a30be65504e0c58 100644 (file)
@@ -37,24 +37,24 @@ interface EnergyDetection
 {
   /**
    * Requests to measure the energy level on the current channel; the
-   * measurement should last for <code>duration<\code> symbols and the  
-   * maximum energy level is signalled through the <code>done<\code>
+   * measurement should last for <tt>duration</tt> symbols and the  
+   * maximum energy level is signalled through the <tt>done</tt>
    * event.
    *
    * @param duration Duration of the energy detection measurement 
    * (in symbol time)
    * @return SUCCESS if the request was accepted and only then 
-   * the <code>done<\code> event will be signalled, FAIL otherwise
+   * the <tt>done</tt> event will be signalled, FAIL otherwise
    **/
   command error_t start(uint32_t duration);
 
   /**
-   * Signalled in response to a call to <code>start<\code>;
+   * Signalled in response to a call to <tt>start<\tt>;
    * returns the maximum energy measured on the channel over the
    * specified period of time.
    *
    * @param status SUCCESS if the measurement succeeded
-   * and only then <code>EnergyLevel<\code> is valid, FAIL 
+   * and only then <tt>EnergyLevel<\tt> is valid, FAIL 
    * otherwise
    * @param EnergyLevel The maximum energy on the channel
    **/
index d9e3aef6d088a0e5f850b3ccebd97a3d47ceff3c..665d5543233c4fc16bd55ca4c1a87213b9093394 100644 (file)
@@ -38,7 +38,7 @@ interface FrameTx
    *
    * @param  txFrame    the frame to transmit
    * @return IEEE154_SUCCESS if the request was accepted and
-   * only then <code>transmitDone()</code> will be signalled
+   * only then <tt>transmitDone()</tt> will be signalled
    */  
   command ieee154_status_t transmit(ieee154_txframe_t *txFrame); 
 
index ce876296339aaba385d507cafd763bc466dff8b4..beca22a1b3cbcdd33361737bb9fb89be39ba27cc 100644 (file)
@@ -38,7 +38,7 @@ interface FrameTxNow
    *
    * @param  txFrame    the frame to transmit
    * @return IEEE154_SUCCESS if the request was accepted and
-   * only then <code>transmitDone()</code> will be signalled
+   * only then <tt>transmitDone()</tt> will be signalled
    */  
   async command ieee154_status_t transmitNow(ieee154_txframe_t *frame); 
 
index 24317842876f3fac0055f126c285827b5df3dfdf..3405932cf50b0b308e7a5b21a0bfd478c37e3369 100644 (file)
@@ -37,14 +37,14 @@ interface RadioOff
 {
 
   /** 
-   * Switches the radio off and changes the radio state to RADIO_OFF. This
+   * 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.
    *
-   * @return EALREADY if radio is already switched off <br> FAIL if radio the
-   * current radio state is neither TX_LOADED, RX_PREPARED nor RECEIVING <br>
-   * SUCCESS if the command was accepted and the <tt>offDone()</tt> event will
-   * be signalled.
+   * @return SUCCESS if the command was accepted and the <tt>offDone()</tt>
+   * event will be signalled; EALREADY if radio is already switched off; FAIL
+   * if the current radio state is neither TX_LOADED, RX_PREPARED nor
+   * RECEIVING.
    */
   async command error_t off();
 
@@ -54,6 +54,9 @@ interface RadioOff
    **/  
   async event void offDone();
 
- /** @return TRUE if the radio is in the state RADIO_OFF, FALSE otherwise */
-  async command bool isOff();
+  /** 
+   * 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(); 
 }
index e548e20f08e5f077028b0583f0b472f3228b720f..597ab758c8184c2b0f09a9efb9590b62b106915f 100644 (file)
@@ -35,7 +35,6 @@
 #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
@@ -55,13 +54,15 @@ interface RadioRx
    **/    
   async event void prepareDone(); 
 
-  /** @return TRUE if the radio is in the state RX_PREPARED, FALSE otherwise */
+  /** 
+   * Tells whether the radio is in state RX_PREPARED.
+   * @return TRUE if the radio is in the state RX_PREPARED, FALSE otherwise 
+   */
   async command bool isPrepared();
 
   /** 
    * Switches the radio to receive mode at time <tt>t0 + dt</tt>.  If
-   * <tt>t0</tt> is NULL, then the callee interprets <tt>t0</tt> as the current
-   * time. 
+   * <tt>t0</tt> is NULL, then the callee interprets <tt>t0</tt> as now. 
    *
    * @param t0 Reference time for receive operation (NULL means now)  
    *
@@ -73,7 +74,10 @@ interface RadioRx
    */
   async command error_t receive(ieee154_reftime_t *t0, uint32_t dt); 
   
-  /** @return TRUE if the radio is in the state RECEIVING, FALSE otherwise */
+  /**
+   * Tells whether the radio is in state RECEIVING.
+   * @return TRUE if the radio is in the state RECEIVING, FALSE otherwise 
+   */
   async command bool isReceiving();
 
   /** 
index 7229b1921f52e7bed12b6e60493c325b920ff698..f5d45c8904b29ad0833a3b96516f9c510d3f3638 100644 (file)
@@ -49,7 +49,7 @@ interface RadioTx
    * The frame will be loaded (and the radio will stay in the state
    * TX_LOADED) until either the transmission was successful, i.e.
    * <tt>transmitDone()</tt> was signalled with a status IEEE154_SUCCESS, or
-   * the radio is explicitly switched off through the <tt>RadioOff</tt>
+   * the radio is switched off through the <tt>RadioOff</tt>
    * interface. Until then the callee might have to reserve certain resources
    * (e.g. the bus connected to the radio), so the caller should keep the time
    * while a frame is loaded as short as possible.
@@ -80,87 +80,137 @@ interface RadioTx
 
   /** 
    * Transmits the frame whose transmission has previously been prepared
-   * through a call to <tt>load()</tt>. The actual time of transmission -- the
-   * point in time when the first symbol of the PPDU is transmitted -- is
-   * defined by: <tt>t0 + dt</tt>. The data type of the <tt>t0</tt> parameter
-   * is platform-specific (symbol precision or better) while <tt>dt</tt> is
-   * expressed in 802.15.4 symbols. If <tt>t0</tt> is NULL, then the callee
-   * interprets <tt>t0</tt> as the current time. The caller guarantees (through
+   * through a call to <tt>load()</tt> at time <tt>t0+dt</tt> or immediately if
+   * <tt>t0</tt> is NULL. In the first case the caller has to guarantee (through
    * platform-specific guard times and by calling <tt>transmit</tt> in an
-   * atomic block) that the callee can start the transmission on time, taking
-   * any prior clear channel assesment(s) into consideration. 
-   *
-   * A transmission may require 0, 1 or 2 prior clear channel assesments
-   * (<tt>numCCA</tt> parameter) to be performed 0, 20 or 40 symbols,
-   * respectively, before the actual transmission. If a CCA determines a busy
-   * channel, then the frame will not be transmitted. 
-   *
-   * A successful transmission may also require an acknowledgement from the
-   * destination (indicated through the <tt>ackRequest</tt> parameter); then,
-   * the callee has to perform the necessary steps for receiving that
-   * acknowledgement (switching the radio to Rx mode immediately after
-   * transmission, etc.; for details see IEEE 802.15.4-2006).
-   *
-   * The <tt>transmit()</tt> command will succeed iff the radio is in state
-   * TX_LOADED. The <tt>transmitDone()</tt> event will then signal the result
+   * atomic block) that the callee can start the transmission on time.
+   * The frame is transmitted without carrier sense (without CCA).  
+   * The <tt>transmitDone()</tt> event will signal the result
    * of the transmission.
    *
    * @param t0 Reference time for transmission (NULL means now)  
-   *
    * @param dt A positive offset relative to <tt>t0</tt>.  
    *
-   * @param numCCA Number of clear channel assesments.
-   *
-   * @param ackRequest TRUE means an acknowledgement is required, FALSE means
-   * no acknowledgement is not required
-   *
    * @return SUCCESS if the transmission was triggered successfully and only
    * then <tt>transmitDone()</tt> will be signalled; FAIL, if the transmission
    * was not triggered because no frame was loaded.
-   */  
-  async command error_t transmit(ieee154_reftime_t *t0, uint32_t dt, 
-      uint8_t numCCA, bool ackRequest);
+   */
+  async command error_t transmit(ieee154_reftime_t *t0, uint32_t dt);
 
   /**
-   * Signalled in response to a call to <tt>transmit()</tt>. Depending on the
-   * <tt>error</tt> parameter the radio is now in state RADIO_OFF
-   * (<tt>error</tt> == IEEE154_SUCCESS) or still in state TX_LOADED
-   * (<tt>error</tt> != IEEE154_SUCCESS).  If the transmission succeeded then
-   * the time of transmission -- the point in time when the first symbol of the
-   * PPDU was transmitted -- will be stored in the metadata field of the frame.
-   * In addition, the <tt>t0</tt> parameter will hold a platform-specific
-   * representation of the same point in time (possibly with higher precision)
-   * to be used as future reference time in a <tt>transmit()</tt> command. If
-   * the transmission did not succeed no timestamp will be stored in the
-   * metadata portion, but <tt>t0</tt> will still represent the hypothetical
-   * transmission time. 
-   *
-   * If <tt>error</tt> has a value other than IEEE154_SUCCESS the frame will
-   * stay loaded and a subsequent call to <tt>transmit</tt> will (re-)transmit
-   * the same <tt>frame</tt> again. If <tt>error</tt> has a value of
-   * IEEE154_SUCCESS then the frame was automatically un-loaded and a new frame
-   * has to be loaded before the <tt>transmit()</tt> command will succeed.
-   *
-   * When the <tt>transmit()</tt> command was called with an
-   * <tt>ackRequest</tt> parameter with value TRUE, and <tt>error</tt> has a
-   * value of IEEE154_SUCCESS, then this means that a corresponding
-   * acknowledgement was successfully received. In this case, the
-   * <tt>ackPendingFlag</tt> represents the "pending" flag in the header of the
-   * acknowledgement frame (TRUE means set, FALSE means reset).
+   * Signalled in response to a call to <tt>transmit()</tt> and completing the transmission. Depending on the
+   * <tt>error</tt> parameter the radio is now in the state RADIO_OFF
+   * (<tt>error == IEEE154_SUCCESS</tt>) or back in state TX_LOADED
+   * (<tt>error != IEEE154_SUCCESS</tt>). 
    *
    * @param frame The frame that was transmitted.  
+   * @param txTime The time of transmission of the first symbol of the PPDU or NULL if the transmission failed.  
+   */
+  async event void transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime);
+
+
+ /** 
+   * Transmits the frame whose transmission has previously been prepared
+   * through a call to <tt>load()</tt> using the unslotted CSMA-CA 
+   * algorithm as specified in the IEEE 802.15.4-2006 standard Sect. 7.5.1.4. The initial 
+   * CSMA-CA parameters are passed as a parameter, the algorithm should start immediately.
+   * The <tt>transmitUnslottedCsmaCaDone()</tt> event will signal the result
+   * of the transmission.
+   * A successful transmission may include an acknowledgement from the
+   * destination if the ACK_REQUESTED flag is set in the loaded frame's header; then,
+   * the callee also has to perform the necessary steps for receiving the
+   * acknowledgement (switching the radio to Rx mode immediately after
+   * transmission, etc., as specified in IEEE 802.15.4-2006 Sect. 7.5.6.4). 
+   * 
+   * @param csmaParameters parameters for the unslotted CSMA-CA algorithm. 
    *
-   * @param t0 The (hypothetical) transmission time; the pointer is only valid
-   * until the eventhandler returns.  
+   * @return SUCCESS if the unslotted CSMA-CA was triggered successfully,
+   * FAIL otherwise.
+   */
+  async command error_t transmitUnslottedCsmaCa(ieee154_csma_t *csmaParameters);
+
+  /**
+   * Signalled in response to a call to <tt>transmitUnslottedCsmaCa()</tt>. 
+   * Depending on the
+   * <tt>error</tt> parameter the radio is now in the state RADIO_OFF
+   * (<tt>error == IEEE154_SUCCESS</tt>) or still in state TX_LOADED
+   * (<tt>error != IEEE154_SUCCESS</tt>). If the transmission succeeded then
+   * the time of the transmission -- the point in time when the first symbol of the
+   * PPDU was transmitted -- will be stored in the metadata field of the frame. 
    *
+   * @param frame The frame that was transmitted.  
+   * @param csmaParameters csmaParameters parameters for the unslotted CSMA-CA algorithm
    * @param ackPendingFlag TRUE if an acknowledgement was received and the
    * "pending" flag is set in the header of the ACK frame, FALSE otherwise
+   * @param result SUCCESS if the the frame was transmitted (and a matching
+   * acknowledgement was received, if requested); FAIL if the CSMA-CA algorithm failed
+   * because NB > macMaxCsmaBackoffs.  
+   *
+   * unslotted CSMA-CA was triggered successfully,
+   * FAIL otherwiseThe time of transmission or NULL if the transmission failed.  
+   */
+  async event void transmitUnslottedCsmaCaDone(ieee154_txframe_t *frame,
+      bool ackPendingFlag, ieee154_csma_t *csmaParameters, error_t result);
+
+
+ /** 
+   * Transmits the frame whose transmission has previously been prepared
+   * through a call to <tt>load()</tt> using the slotted CSMA-CA 
+   * algorithm as specified in the IEEE 802.15.4-2006 standard Sect. 7.5.1.4. The initial 
+   * CSMA-CA parameters are passed as a parameter, the algorithm should start immediately,
+   * but the frame transmission should start no later than <tt>slot0Time+dtMax</tt>. The backoff slot boundaries
+   * are defined relative to <tt>slot0Time</tt>, if the <tt>resume</tt>
+   * then the initial backoff (in symbols) is passed as the <tt>initialBackoff</tt> parameter.
+   *
+   * The <tt>transmitSlottedCsmaCaDone()</tt> event will signal the result
+   * of the transmission.
+   * A successful transmission may include an acknowledgement from the
+   * destination if the ACK_REQUESTED flag is set in the loaded frame's header; then,
+   * the callee also has to perform the necessary steps for receiving the
+   * acknowledgement (switching the radio to Rx mode immediately after
+   * transmission, etc., as specified in IEEE 802.15.4-2006 Sect. 7.5.6.4). 
+   * 
+   * @param slot0Time Reference time (last beacon)  
+   * @param dtMax <tt>slot0Time+dtMax</tt> is the last time the frame may be transmitted.
+   * @param resume TRUE means that the initial backoff is defined by the
+   * <tt>initialBackoff</tt> parameter, FALSE means the <tt>initialBackoff</tt>
+   * should be ignored.
+   * @param initialBackoff initial backoff.
+   * @param csmaParameters parameters for the slotted CSMA-CA algorithm. 
+   *
+   * @return SUCCESS if the slotted CSMA-CA was triggered successfully,
+   * FAIL otherwise.
+   */
+  async command error_t transmitSlottedCsmaCa(ieee154_reftime_t *slot0Time, uint32_t dtMax, 
+      bool resume, uint16_t initialBackoff, ieee154_csma_t *csmaParameters);
+
+  /**
+   * Signalled in response to a call to <tt>transmitSlottedCsmaCa()</tt>. 
+   * Depending on the
+   * <tt>error</tt> parameter the radio is now in the state RADIO_OFF
+   * (<tt>error == IEEE154_SUCCESS</tt>) or still in state TX_LOADED
+   * (<tt>error != IEEE154_SUCCESS</tt>). If the transmission succeeded then
+   * the time of the transmission -- the point in time when the first symbol of the
+   * PPDU was transmitted -- will be stored in the metadata field of the frame.
+   * It will also passed (possibly with higher precision) through the
+   * <tt>txTime</tt> parameter.
    *
-   * @param error SUCCESS if the transmission succeeded (including successful
-   * CCA and acknowledgement reception, if requested); EBUSY if CCA was
-   * unsuccessful (frame was not transmitted); ENOACK if frame was transmitted
-   * but no matching acknowledgement was received.
-   **/  
-  async event void transmitDone(ieee154_txframe_t *frame, ieee154_reftime_t *t0, 
-      bool ackPendingFlag, error_t error);   
+   * @param frame The frame that was transmitted.  
+   * @param txTime The time of transmission of the first symbol of the PPDU or NULL if the transmission failed.  
+   * @param ackPendingFlag TRUE if an acknowledgement was received and the
+   * "pending" flag is set in the header of the ACK frame, FALSE otherwise
+   * @param remainingBackoff only valid if <tt>error == ERETRY</tt>, i.e.
+   * when the frame could not be transmitted because transmission would have
+   * started later than <tt>slot0Time+dtMax</tt>; then it 
+   * specifies the remaining offset (in symbols) relative to <tt>slot0Time+dtMax</tt>,
+   * when the frame would have been transmitted
+   * @param csmaParameters csmaParameters parameters for the unslotted CSMA-CA algorithm
+   *
+   * @result result SUCCESS if the the frame was transmitted (and a matching
+   * acknowledgement was received, if requested); FAIL if the CSMA-CA algorithm failed
+   * because NB > macMaxCsmaBackoffs; ERETRY if the frame could not be transmitted because transmission would have
+   * started later than <tt>slot0Time+dtMax</tt>
+   */
+  async event void transmitSlottedCsmaCaDone(ieee154_txframe_t *frame, ieee154_reftime_t *txTime, 
+      bool ackPendingFlag, uint16_t remainingBackoff, ieee154_csma_t *csmaParameters, error_t result);
 }
index 01d59541c4e7858bce2a6fc89ca5f8898369aa25..eaa1c3bf7b60c79a630f37a059a938d3652bd413 100644 (file)
@@ -115,10 +115,10 @@ interface IEEE154Frame
  /**
    * Sets the addressing fields in the MAC header of a frame. The source 
    * PAN identifier and the source address will be set automatically, their
-   * values depend on the <code>SrcAddrMode</code> parameter: if 
-   * <code>SrcAddrMode</code> is a short or extended address, then
-   * the current PIB attributes <code>macShortAddress</code> or 
-   * <code>aExtendedAddress</code> and <code>macPANId</code> are used.
+   * values depend on the <tt>SrcAddrMode</tt> parameter: if 
+   * <tt>SrcAddrMode</tt> is a short or extended address, then
+   * the current PIB attributes <tt>macShortAddress</tt> or 
+   * <tt>aExtendedAddress</tt> and <tt>macPANId</tt> are used.
    *
    * @param frame         the frame
    * @param srcAddrMode   the source addressing mode
@@ -157,7 +157,7 @@ interface IEEE154Frame
 
  /**
    * Returns the point in time when the frame was received. If 
-   * <code>isTimestampValid()<\code> returns FALSE then the 
+   * <tt>isTimestampValid()<\tt> returns FALSE then the 
    * timestamp is not valid and must be ignored.
    *
    * @param frame     the frame
@@ -192,7 +192,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 <code>IEEE154BeaconFrame<\code>
+    * Note: For beacon frames one can use the <tt>IEEE154BeaconFrame<\tt>
     * interface to inspect additional fields of the frame.
     *
     * @param  frame   the frame
@@ -233,8 +233,8 @@ interface IEEE154Frame
     * received while in promiscuous mode, because then no filtering
     * (except CRC check) was applied. Note: if this command returns
     * FALSE, then all other commands in this interface (except
-    * <code>wasPromiscuousModeEnabled()</code>) and the 
-    * <code>IEEE154BeaconFrame</code> interface return undefined values!
+    * <tt>wasPromiscuousModeEnabled()</tt>) and the 
+    * <tt>IEEE154BeaconFrame</tt> interface return undefined values!
     *
     * @param  frame   the frame
     * @return         TRUE if frame has a standard compliant header,
index 4415ee60373e2955ca6f08468874d03ba8766738..bc42d77ca442c739af38b2431580b2ca064559e4 100644 (file)
@@ -42,28 +42,28 @@ 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
-   * <code>setBeaconPayloadDone()<\code> event will be signalled when the 
-   * beacon payload has been set -- until then <code>beaconPayload<\code> must 
+   * <tt>setBeaconPayloadDone()<\tt> event will be signalled when the 
+   * beacon payload has been set -- until then <tt>beaconPayload<\tt> must 
    * not be modified.
    *
    * @param beaconPayload   the new beacon payload
    * @param length          the length of the new beacon payload (in byte)
    *
    * @return EBUSY if another transaction is pending, ESIZE if length is too big, 
-   * SUCCESS otherwise (and only then the <code>setBeaconPayloadDone<\code> event 
+   * SUCCESS otherwise (and only then the <tt>setBeaconPayloadDone<\tt> event 
    * will be signalled)
    */
  command error_t setBeaconPayload(void *beaconPayload, uint8_t length);
 
   /**
-   * Signalled in response to a <code>setBeaconPayload()<\code> request.
+   * Signalled in response to a <tt>setBeaconPayload()<\tt> request.
    * Indicates that the beacon payload has been copied and returns the
    * ownership of the buffer to the next higher layer. 
    * 
-   * @param beaconPayload   the <code>beaconPayload<\code> passed in the 
-   *                        <code>setBeaconPayload()<\code> command
-   * @param length          the <code>length<\code> passed in the 
-   *                        <code>setBeaconPayload()<\code> command
+   * @param beaconPayload   the <tt>beaconPayload<\tt> passed in the 
+   *                        <tt>setBeaconPayload()<\tt> command
+   * @param length          the <tt>length<\tt> passed in the 
+   *                        <tt>setBeaconPayload()<\tt> command
    */
  event void setBeaconPayloadDone(void *beaconPayload, uint8_t length);
 
@@ -84,9 +84,9 @@ 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 <code>setBeaconPayload()<\code> command.  The
-   * <code>modifyBeaconPayloadDone()<\code> event will be signalled when the 
-   * beacon payload has been updated -- until then <code>buffer<\code> must 
+   * command over the <tt>setBeaconPayload()<\tt> command.  The
+   * <tt>modifyBeaconPayloadDone()<\tt> event will be signalled when the 
+   * beacon payload has been updated -- until then <tt>buffer<\tt> must 
    * not be modified.
    *
    * @param offset      offset into the current beacon payload
@@ -94,21 +94,21 @@ interface IEEE154TxBeaconPayload
    * @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 <code>modifyBeaconPayloadDone<\code> event 
+   * SUCCESS otherwise (and only then the <tt>modifyBeaconPayloadDone<\tt> event 
    * will be signalled)
    */
  command error_t modifyBeaconPayload(uint8_t offset, void *buffer, uint8_t bufferLength);
 
   /**
-   * Signalled in response to a <code>modifyBeaconPayload()<\code> request.
+   * Signalled in response to a <tt>modifyBeaconPayload()<\tt> request.
    * Indicates that the beacon payload has been updated. 
    * 
-   * @param offset        the <code>offset<\code> passed in the 
-   *                      <code>modifyBeaconPayload()<\code> command
-   * @param buffer        the <code>buffer<\code> passed in the 
-   *                      <code>modifyBeaconPayload()<\code> command
-   * @param bufferLength  the <code>bufferLength<\code> passed in the 
-   *                      <code>modifyBeaconPayload()<\code> command
+   * @param offset        the <tt>offset<\tt> passed in the 
+   *                      <tt>modifyBeaconPayload()<\tt> command
+   * @param buffer        the <tt>buffer<\tt> passed in the 
+   *                      <tt>modifyBeaconPayload()<\tt> command
+   * @param bufferLength  the <tt>bufferLength<\tt> passed in the 
+   *                      <tt>modifyBeaconPayload()<\tt> command
    */
  event void modifyBeaconPayloadDone(uint8_t offset, void *buffer, uint8_t bufferLength);
 
@@ -117,7 +117,7 @@ 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 <code>setPayload<\code>
+   * transmission, and (2) that a subsequent call to <tt>setPayload<\tt>
    * will update the beacon payload portion of this beacon.  However, 
    * because of tight timing constraints in beacon-enabled mode neither can be
    * guaranteed!
@@ -126,7 +126,7 @@ interface IEEE154TxBeaconPayload
 
   /** 
    * Indicates that a beacon frame has been transmitted (the 
-   * <code>getBeaconPayload<\code> command can be used to inspect the
+   * <tt>getBeaconPayload<\tt> command can be used to inspect the
    * beacon payload).
    */
  event void beaconTransmitted();  
index f59ebd76267bbef44280e7b5a2c65553597424a1..950db2f09e70da1a297c74334388eafbae7f51c4 100644 (file)
@@ -95,8 +95,9 @@ implementation
   Packet = MAC;
 
   components CC2420TKN154C as PHY,
-             new Alarm62500hz32VirtualizedC() as PHYAlarm1,
+             new Alarm62500hz32C() as PHYAlarm1,
              new Alarm62500hz32VirtualizedC() as PHYAlarm2,
+             new Alarm62500hz32C() as TKN154TimingPAlarm,
              LocalTime62500hzC, TKN154TimingP;
 
   // wire PHY to the PIB
@@ -117,7 +118,8 @@ implementation
   PHY.TimeCalc -> MAC;
   PHY.Leds -> LedsC;
   TKN154TimingP.TimeCalc -> MAC;
-  TKN154TimingP.LocalTime -> LocalTime62500hzC;
+  TKN154TimingP.Leds -> LedsC;
+  TKN154TimingP.SymbolAlarm -> TKN154TimingPAlarm;
 
   components new Alarm62500hz32VirtualizedC() as  MACAlarm1,
              new Alarm62500hz32VirtualizedC() as  MACAlarm2,
@@ -164,6 +166,7 @@ implementation
   components RandomC, LedsC, NoLedsC;
   MAC.Random -> RandomC;
   MAC.Leds -> LedsC;
+  PHY.Random -> RandomC;
 
 #ifdef TKN154_SERIAL_DEBUG
   components SerialDebugC as Debug;
index 2d72821179f89dca6aeb885fc6f90826fb4fac5f..b109e1d792fd17333d70c1c5fa0bc5179b070ee8 100644 (file)
@@ -1,3 +1,7 @@
+ifdef TKN154_PIERCEBOARD
+CFLAGS += -I$(TOSDIR)/platforms/telosb/mac/tkn154/timer/pierceboard
+endif
+
 CFLAGS += -I$(TOSDIR)/platforms/telosb/mac/tkn154 \
        -I$(TOSDIR)/platforms/telosb/mac/tkn154/timer \
        -I$(TOSDIR)/chips/cc2420_tkn154
index d9713c201d0985a60f553d5b45fa8ad8d96caa11..ceb71191482fb8d44fae1fd21cac4338a7317cd2 100644 (file)
  */
 
 /** 
- * NOTE:
  * In slotted CSMA-CA frames must be sent on backoff boundaries (slot width:
- * 320 us). On TelosB the only clock source with sufficient accuracy is the
- * external quartz, unfortunately it is not precise enough (32.768 Hz).
- * Therefore, currently the following code is not even trying to achieve
- * accurate timing. 
+ * 320 us). The TelosB platform lacks a clock with sufficient precision/
+ * accuracy, i.e. for slotted CSMA-CA the timing is *not* standard compliant.
  */
 
 #include "TKN154_platform.h"
@@ -49,15 +46,18 @@ module TKN154TimingP
   provides interface ReliableWait;
   provides interface ReferenceTime;
   uses interface TimeCalc;
-  uses interface LocalTime<T62500hz>;
+  uses interface Alarm<T62500hz,uint32_t> as SymbolAlarm;
+  uses interface Leds;
 }
 implementation
 {
-
-#define UWAIT1 nop();nop();nop();nop()
-#define UWAIT2 UWAIT1;UWAIT1
-#define UWAIT4 UWAIT2;UWAIT2
-#define UWAIT8 UWAIT4;UWAIT4
+  enum {
+    S_WAIT_OFF,
+    S_WAIT_RX,
+    S_WAIT_TX,
+    S_WAIT_BACKOFF,
+  };
+  uint8_t m_state = S_WAIT_OFF;
 
   async command void CaptureTime.convert(uint16_t time, ieee154_reftime_t *localTime, int16_t offset)
   {
@@ -65,7 +65,7 @@ implementation
     // we now need to convert the capture "time" into ieee154_reftime_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; this could probably
+    // (deviating about +-50 microseconds, which could probably
     // improved if we don't go through LocalTime)
     uint16_t tbr1, tbr2, delta;
     uint32_t now;
@@ -74,7 +74,7 @@ implementation
         tbr1 = TBR;
         tbr2 = TBR;
       } while (tbr1 != tbr2); // majority vote required (see msp430 manual)
-      now = call LocalTime.get(); 
+      now = call SymbolAlarm.getNow(); 
     }
     if (time < tbr1)
       delta = tbr1 - time;
@@ -85,35 +85,76 @@ implementation
 
   async command void ReliableWait.busyWait(uint16_t dt)
   {
-    uint32_t start = call LocalTime.get();
-    while (!call TimeCalc.hasExpired(start, dt))
-      ;
+    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)
+    }
   }
 
-  async command void ReliableWait.waitCCA(ieee154_reftime_t *t0, uint16_t dt)
+  async command void ReliableWait.waitRx(ieee154_reftime_t *t0, uint16_t dt)
   {
-    while (!call TimeCalc.hasExpired(*t0, dt))
-      ;
-    signal ReliableWait.waitCCADone();
+    if (m_state != S_WAIT_OFF){
+      call Leds.led0On();
+      return;
+    }
+    m_state = S_WAIT_RX;
+    call SymbolAlarm.startAt(*t0 - 12, dt); // subtract 12 symbols required for Rx calibration
+    //signal SymbolAlarm.fired();
   }
 
   async command void ReliableWait.waitTx(ieee154_reftime_t *t0, uint16_t dt)
   {
-    while (!call TimeCalc.hasExpired(*t0, dt))
-      ;
-    signal ReliableWait.waitTxDone();
+    if (m_state != S_WAIT_OFF){
+      call Leds.led0On();
+      return;
+    }
+    m_state = S_WAIT_TX;
+    call SymbolAlarm.startAt(*t0 - 12, dt); // subtract 12 symbols required for Tx calibration
+  }
+    
+  async command void ReliableWait.waitBackoff(ieee154_reftime_t *t0, uint16_t dt)
+  {
+    if (m_state != S_WAIT_OFF){
+      call Leds.led0On();
+      return;
+    }
+    m_state = S_WAIT_BACKOFF;
+    call SymbolAlarm.startAt(*t0, dt);
+    //signal SymbolAlarm.fired();
   }
 
-  async command void ReliableWait.waitRx(ieee154_reftime_t *t0, uint16_t dt)
+  async event void SymbolAlarm.fired() 
   {
-    while (!call TimeCalc.hasExpired(*t0, dt))
-      ;
-    signal ReliableWait.waitRxDone();
+    switch (m_state)
+    {
+      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;
+    }
   }
+
+  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)
   {
-    *reftime = call LocalTime.get();
+    *reftime = call SymbolAlarm.getNow() + dt;
   }
 
   async command uint32_t ReferenceTime.toLocalTime(ieee154_reftime_t* refTime)
index e129e2550377a11738d0a59d6237dd6c3c59aff0..cf5b1972345817ac6482669492a8c4ac6f3639d7 100644 (file)
@@ -43,7 +43,7 @@
 
 enum {
   // guard time to give up the token before actual end of CAP/CFP
-  IEEE154_RADIO_GUARD_TIME = 1000,
+  IEEE154_ACTIVE_PERIOD_GUARD_TIME = 300,
 
   // the expected time for a RadioTx.prepare() operation to execute (return)
   IEEE154_RADIO_TX_PREPARE_DELAY = 220,
index 20f0822d49e1d7863038d7f834e28b9ad3770734..2af284dd9d1e3375c11b87da5735fdad8444a625 100644 (file)
@@ -41,10 +41,13 @@ module Alarm32khzTo62500hzTransformC
 implementation
 {
 /**
- * This is the place where we cheat: since we don't have a clock source
- * running at 62500 Hz, we cast 2 symbols to 1 tick of the 32768
- * clock, which introduces a small (5%) error.
-*/
+ * 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)!"
 
   async command void Alarm.start[ uint8_t num ](uint32_t dt){ call AlarmFrom.start[num](dt >> 1);}
@@ -61,15 +64,17 @@ implementation
 
   async command void Alarm.startAt[ uint8_t num ](uint32_t t0, uint32_t dt){
     // t0 occured before "now"
-    uint32_t now = call Alarm.getNow[num](), elapsed;
-    if (t0 <= now)
-      elapsed = now - t0;
-    else
-      elapsed = ~(t0 - now) + 1;
-    if (elapsed > dt)
-      elapsed = dt;
-    dt -= elapsed;
-    call AlarmFrom.start[num](dt >> 1);
+    atomic {
+      uint32_t now = call Alarm.getNow[num](), elapsed;
+      if (t0 < now)
+        elapsed = now - t0;
+      else
+        elapsed = ~(t0 - now) + 1;
+      if (elapsed > dt)
+        dt = elapsed;
+      dt -= elapsed;
+      call Alarm.start[num](dt);
+    }
   }
 
   /******************** Defaults ****************************/
diff --git a/tos/platforms/telosb/mac/tkn154/timer/Alarm62500hz32C.nc b/tos/platforms/telosb/mac/tkn154/timer/Alarm62500hz32C.nc
new file mode 100644 (file)
index 0000000..26f5de2
--- /dev/null
@@ -0,0 +1,15 @@
+#include "Timer62500hz.h"
+generic configuration Alarm62500hz32C()
+{
+  provides interface Alarm<T62500hz,uint32_t> as Alarm;
+}
+implementation
+{
+  components new Alarm32khz32C(), MainC;
+  components new Alarm62500hz32P();
+
+  Alarm = Alarm62500hz32P;
+
+  MainC -> Alarm32khz32C.Init;
+  Alarm62500hz32P.AlarmFrom -> Alarm32khz32C;
+}
diff --git a/tos/platforms/telosb/mac/tkn154/timer/Alarm62500hz32P.nc b/tos/platforms/telosb/mac/tkn154/timer/Alarm62500hz32P.nc
new file mode 100644 (file)
index 0000000..7d6d886
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * 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 -------------------------------------------------------------
+ * $Date$
+ * @author Jan Hauer <hauer@tkn.tu-berlin.de>
+ * ========================================================================
+ */
+
+generic module Alarm62500hz32P()
+
+{
+  provides interface Alarm<T62500hz,uint32_t> as Alarm;
+  uses interface Alarm<T32khz,uint32_t> as AlarmFrom;
+}
+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!
+ */
+
+  async command void Alarm.start(uint32_t dt){ call AlarmFrom.start(dt >> 1);}
+  async command void Alarm.stop(){ call AlarmFrom.stop();}
+  async event void AlarmFrom.fired(){ signal Alarm.fired();}
+  async command bool Alarm.isRunning(){ return call AlarmFrom.isRunning();}
+  async command uint32_t Alarm.getAlarm(){ return call AlarmFrom.getAlarm() << 1;}
+
+  async command uint32_t Alarm.getNow(){ 
+    // this might shift out the most significant bit
+    // that's why Alarm.startAt() is converted to a Alarm.start()
+    return call AlarmFrom.getNow() << 1; 
+  }
+
+  async command void Alarm.startAt(uint32_t t0, uint32_t dt){
+    // t0 occured before "now"
+    atomic {
+      uint32_t now = call Alarm.getNow(), elapsed;
+      if (t0 < now)
+        elapsed = now - t0;
+      else
+        elapsed = ~(t0 - now) + 1;
+      if (elapsed > dt)
+        dt = elapsed;
+      dt -= elapsed;
+      call Alarm.start(dt);
+    }
+  }
+
+  /******************** Defaults ****************************/
+
+  default async command void AlarmFrom.start(uint32_t dt){ }
+  default async command void AlarmFrom.stop(){ }
+  default async command bool AlarmFrom.isRunning(){ return FALSE;}
+  default async event void Alarm.fired(){}
+  default async command void AlarmFrom.startAt(uint32_t t0, uint32_t dt){ }
+  default async command uint32_t AlarmFrom.getNow(){ return 0;}
+  default async command uint32_t AlarmFrom.getAlarm(){ return 0;}
+}