CC1000RadioIntM.nc
上传用户:joranyuan
上传日期:2022-06-23
资源大小:3306k
文件大小:54k
源码类别:

网络

开发平台:

Others

  1. includes crc;
  2. includes CC1000Const;
  3. includes zmacInfo;
  4. includes DrandInfo;
  5. module CC1000RadioIntM {
  6.   provides {
  7.     interface StdControl;
  8.     interface BareSendMsg as Send;
  9.     interface ReceiveMsg as Receive;
  10.     interface RadioCoordinator as RadioSendCoordinator;
  11.     interface RadioCoordinator as RadioReceiveCoordinator;
  12.     interface MacControl;
  13.     interface MacBackoff;
  14.     interface LowPowerListening;
  15.     interface SetDrand;
  16.     
  17.     // legacy commands supported, but should now use the
  18.     // Low Power Listening interface
  19.     async command result_t SetListeningMode(uint8_t power);
  20.     async command uint8_t GetListeningMode();
  21.     async command result_t SetTransmitMode(uint8_t power);
  22.     async command uint8_t GetTransmitMode();
  23.     // Used for debugging the noise floor (gets the current squelch value)
  24.     async command uint16_t GetSquelch();
  25.     // Used for debugging; gets an estimate of the power consumed by the radio
  26.     async command uint16_t GetPower();
  27.     async command uint16_t GetDataSent();
  28.     async command uint16_t GetPower_tx();
  29.     async command uint16_t GetPower_rx();
  30.     async command uint16_t GetPower_sp();
  31.     async command result_t ResetPower();
  32.     async command result_t ResetDataSent();
  33.   }
  34.   uses {
  35.     interface SClock;
  36.     interface StdControl as SubControl;
  37.     interface PowerManagement;
  38.     interface StdControl as CC1000StdControl;
  39.     interface CC1000Control;
  40.     interface Random;
  41.     interface ADCControl;
  42.     interface ADC as RSSIADC;
  43.     interface SpiByteFifo;
  44.     interface StdControl as TimerControl;
  45.     interface Timer as WakeupTimer;
  46.     interface Timer as SquelchTimer;
  47.     interface Timer as TDMATimer;
  48.     interface Leds;
  49.   }
  50. }
  51. implementation {
  52. #include "DrandMSG.h"
  53. #include "zmacConst.h"
  54. #ifdef ZMAC_DEBUG
  55. #include "SODebug.h"
  56. #endif
  57.   enum {
  58.     NULL_STATE,
  59.     TX_STATE,
  60.     DISABLED_STATE,
  61.     IDLE_STATE,
  62.     PRETX_STATE,
  63.     SYNC_STATE,
  64.     RX_STATE,
  65.     SENDING_ACK,
  66.     POWER_DOWN_STATE,
  67.     PULSE_CHECK_STATE,
  68.   };
  69.   enum {
  70.     TXSTATE_WAIT,
  71.     TXSTATE_START,
  72.     TXSTATE_PREAMBLE,
  73.     TXSTATE_SYNC,
  74.     TXSTATE_DATA,
  75.     TXSTATE_CRC,
  76.     TXSTATE_FLUSH,
  77.     TXSTATE_WAIT_FOR_ACK,
  78.     TXSTATE_READ_ACK,
  79.     TXSTATE_DONE
  80.   };
  81.   enum {
  82.     SYNC_BYTE = 0x33,
  83.     NSYNC_BYTE = 0xcc,
  84.     SYNC_WORD = 0x33cc,
  85.     NSYNC_WORD = 0xcc33,
  86.     ACK_LENGTH = 16,
  87.     MAX_ACK_WAIT = 18,
  88.     TIME_BETWEEN_CHECKS = 50,
  89.     TIME_AFTER_CHECK = 30,
  90.     CHECK_MA_COUNT = 100, //8888,
  91.     SEND_MA_COUNT = 100, //7200,
  92.     PREAMBLE_LENGTH_TO_BASE = 8,
  93.     RECEIVE_MA_COUNT = 100, //9600
  94.   };
  95.   uint8_t ack_code[5] = {0xab, 0xba, 0x83, 0xaa, 0xaa};
  96.   uint8_t RadioState;
  97.   uint8_t RadioTxState;
  98.   norace uint8_t iRSSIcount;
  99.   uint8_t RSSIInitState;
  100.   uint8_t iSquelchCount;
  101.   uint16_t txlength;
  102.   uint16_t rxlength;
  103.   TOS_MsgPtr txbufptr;  // pointer to transmit buffer
  104.   TOS_MsgPtr rxbufptr;  // pointer to receive buffer
  105.   TOS_Msg retxbuf; //re-transmit buffer in case ECN preempts send 
  106.   TOS_Msg RxBuf; // save received messages
  107.   uint8_t NextTxByte;
  108.   uint8_t lplpower;        //  low power listening mode
  109.   uint8_t lplpowertx;      //  low power listening transmit mode
  110.   uint16_t preamblelen;    //  current length of the preamble
  111.   uint16_t sleeptime;       //  current check interval (sleep time)
  112.  
  113.   uint16_t PreambleCount;   //  found a valid preamble
  114.   uint8_t SOFCount;
  115.   uint16_t search_word;
  116.   //modified by Mahesh
  117.   enum {
  118.     BMAC,
  119.     ZMAC
  120.   };
  121.   enum{
  122.     MAX_VAL = 0xFFFF
  123.   };
  124.   enum{
  125.     POSITIVE = 1,
  126.     NEGATIVE = 2,
  127.     ZERO = 3
  128.   };
  129.   
  130. #ifdef DRAND_ENABLE
  131.   nodeInfo *nbrInfo;
  132. #else
  133.   nodeInfo nbrInfo[MAX_NBR], myInfo; //CHANGE THIS, ONLY FOR TESTING !!!!!!!
  134. #endif
  135.   GTime currentDiff, constOffset;
  136.   uint16_t currentSender;
  137.   uint8_t currentSign;
  138.   uint8_t currentMAC; // default must be BMAC and change to ZMAC after DRAND completes
  139.   uint16_t localFrameLength; // local frame length in slots
  140.   uint16_t globalFrameLength;
  141.   uint16_t slotSize; 
  142.   uint16_t nextHop;
  143.   uint16_t ownSlot;
  144.   uint16_t slots_since_ecnsend;
  145.   uint16_t slots_since_ecnrecv;
  146.   uint16_t slots_since_ecncheck;
  147.   uint16_t globalFrameSize;
  148.   uint16_t localFrameSize;
  149.   uint16_t globalSlot;
  150.   uint16_t currentSlot;
  151.   uint16_t slotMultiplier;
  152.   uint32_t slotNum;
  153.   uint16_t packetsSent;
  154.   uint16_t pktsLastSync;
  155.   bool needTimeSync;
  156.   uint16_t congBackOffs;
  157.   double avgLoss;
  158.   uint32_t curHCLlist;
  159.   bool HCLselect;
  160.   bool ackOrig;
  161.   bool ecnPending;
  162.   bool ecnforward;
  163.   bool enableHCL;
  164.   bool pureHCL;
  165.   TOS_Msg ecnMsgHdr;
  166.   TOS_Msg ecnForwardMsgHdr;
  167.   TOS_Msg syncMsgHdr;
  168.   union {
  169.     uint16_t W;
  170.     struct {
  171.       uint8_t LSB;
  172.       uint8_t MSB;
  173.     };
  174.   } RxShiftBuf;
  175.   uint8_t RxBitOffset; // bit offset for spibus
  176.   uint16_t RxByteCnt; // received byte counter
  177.   uint16_t TxByteCnt;
  178.   uint16_t RSSISampleFreq; // in Bytes rcvd per sample
  179.   norace bool bInvertRxData; // data inverted
  180.   norace bool bTxPending;
  181.   bool bAckEnable;
  182.   bool bCCAEnable;
  183.   bool bTxBusy;
  184.   bool bRSSIValid;
  185.   uint16_t CC1K_PulseLevel;
  186.   uint16_t usRunningCRC; // Running CRC variable
  187.   uint16_t usRSSIVal;
  188.   uint16_t usSquelchVal;
  189.   uint16_t usTempSquelch;
  190.   uint8_t usSquelchIndex;
  191.   norace uint8_t pulse_check_count;
  192.   norace uint16_t pulse_check_sum;
  193.   norace uint16_t send_sum;
  194.   norace uint16_t receive_sum;
  195.   norace uint16_t power_sum;
  196.   norace uint16_t sp_sum;
  197.   norace uint16_t rx_sum;
  198.   norace uint16_t tx_sum;
  199.   norace uint16_t dataSent;
  200.   uint16_t usSquelchTable[CC1K_SquelchTableSize];
  201.   int16_t sMacDelay;    // MAC delay for the next transmission
  202.   // XXX-PB:
  203.   // Here's the deal, the mica (RFM) radio stacks used TOS_LOCAL_ADDRESS
  204.   // to determine if an L2 ack was reqd.  This stack doesn't do L2 acks
  205.   // and, thus doesn't need it.  HOWEVER, some set-mote-id versions
  206.   // break if this symbol is missing from the binary.
  207.   // Thus, I put this LocalAddr here and set it to TOS_LOCAL_ADDRESS
  208.   // to keep things happy for now.
  209.   volatile uint16_t LocalAddr;
  210.   ///**********************************************************
  211.   //* local function definitions
  212.   //**********************************************************/
  213.   /*
  214.     int sortByShort(const void *x, const void *y) {
  215.     uint16_t* x1 = (uint16_t*)x;
  216.     uint16_t* y1 = (uint16_t*)y;
  217.     if (x1[0] > y1[0]) return -1;
  218.     if (x1[0] == y1[0]) return 0;
  219.     if (x1[0] < y1[0]) return 1;
  220.     return 0; // shouldn't reach here becasue it covers all the cases
  221.     }
  222.   */
  223.   uint16_t getOwnerBackoff(){
  224.     return (call Random.rand() & (T_O - 1)) + 1;
  225.   }
  226.   uint16_t getNonOwnerBackoff(){
  227.     return (call Random.rand() & (T_NO - 1)) + T_O + 1;
  228.   }
  229.   void DivTime2(GTime* B, GTime* A){
  230.     if (A->mticks % 2 == 1){
  231.       B->mticks = (A->mticks >> 1);
  232.       B->sticks = (A->sticks >> 1)  + ((MAX_VAL) >>1);
  233.     }
  234.     else{
  235.       B->mticks = (A->mticks >>1);
  236.       B->sticks = (A->sticks >>1);
  237.     }
  238.   }
  239.   void AddTime(GTime* C, GTime* A, GTime* B){
  240.     if ((MAX_VAL - B->sticks) < A->sticks){
  241.       C->sticks = A->sticks - (MAX_VAL - B->sticks);
  242.       C->mticks = A->mticks + B->mticks + 1;
  243.     }
  244.     else{
  245.       C->sticks = A->sticks + B->sticks;
  246.       C->mticks = A->mticks + B->mticks;
  247.     }
  248.   }
  249.   void SubTime(GTime* C, GTime* A, GTime* B){
  250.     if (B->sticks > A->sticks){
  251.       C->sticks = MAX_VAL - (B->sticks - A->sticks);
  252.       C->mticks = A->mticks - (B->mticks + 1);
  253.     }
  254.     else {
  255.       C->sticks = A->sticks -  B->sticks;
  256.       C->mticks = A->mticks -  B->mticks;
  257.     }
  258.   }
  259.   uint16_t getZMACBackoff(uint16_t residualBackoff){
  260.     if(residualBackoff > 0){
  261.       congBackOffs++;
  262.       if((currentSlot == ownSlot) && (residualBackoff >= T_O)){
  263.         return getOwnerBackoff();
  264.       } else if((currentSlot != ownSlot) && (residualBackoff < T_O)){
  265.         if((residualBackoff + T_O) < (T_O + T_NO))
  266.           return (residualBackoff + T_O);
  267.         else
  268.           return getNonOwnerBackoff();
  269.       } else
  270.         return residualBackoff;
  271.     } else{
  272.       if(currentSlot == ownSlot)
  273.         return getOwnerBackoff();
  274.       else
  275.         return getNonOwnerBackoff();
  276.     }
  277.   }
  278.   uint8_t ModSubTime(GTime* C, GTime* A, GTime* B){
  279.     uint8_t retval;
  280.     if (A->mticks > B->mticks) 
  281.       retval = POSITIVE;
  282.     else if (A->mticks < B->mticks) 
  283.       retval = NEGATIVE;
  284.     else{
  285.       if (A->sticks > B->sticks)
  286.         retval = POSITIVE;
  287.       else if (A->sticks < B->sticks)
  288.         retval = NEGATIVE;
  289.       else
  290.         retval = ZERO;
  291.     }
  292.     if (retval == POSITIVE) SubTime(C,A,B);
  293.     else if (retval == NEGATIVE) SubTime(C,B,A);
  294.     else {
  295.       C->sticks = 0;
  296.       C->mticks = 0;
  297.     }
  298.     return retval;
  299.   }
  300.   bool IsHCL(uint32_t gSlot){
  301.     uint32_t tempHCL = 0x1;
  302.     bool flag;
  303.     tempHCL = tempHCL << gSlot;
  304.     atomic{
  305.       if(tempHCL & curHCLlist)
  306.         flag = TRUE;
  307.       else
  308.         flag = FALSE;
  309.     }
  310.     return flag;
  311.   }
  312.   task void adjustSquelch() {
  313.     uint16_t tempArray[CC1K_SquelchTableSize];
  314.     char i,j,min; 
  315.     uint16_t min_value;
  316.     uint32_t tempsquelch;
  317.     atomic {
  318.       usSquelchTable[usSquelchIndex] = usTempSquelch;
  319.       usSquelchIndex++;
  320.       if (usSquelchIndex >= CC1K_SquelchTableSize)
  321.         usSquelchIndex = 0;
  322.       if (iSquelchCount <= CC1K_SquelchCount)
  323.         iSquelchCount++;  
  324.     }
  325.     for (i=0; i<CC1K_SquelchTableSize; i++) {
  326.       tempArray[(int)i] = usSquelchTable[(int)i];
  327.     }
  328.     min = 0;
  329.     //    for (j = 0; j < ((CC1K_SquelchTableSize) >> 1); j++) {
  330.     for (j = 0; j < 3; j++) {
  331.       for (i = 1; i < CC1K_SquelchTableSize; i++) {
  332.         if ((tempArray[(int)i] != 0xFFFF) && 
  333.             ((tempArray[(int)i] > tempArray[(int)min]) ||
  334.              (tempArray[(int)min] == 0xFFFF))) {
  335.           min = i;
  336.         }
  337.       }
  338.       min_value = tempArray[(int)min];
  339.       tempArray[(int)min] = 0xFFFF;
  340.     }
  341.     tempsquelch = ((uint32_t)(usSquelchVal << 5) + (uint32_t)(min_value << 1));
  342.     atomic usSquelchVal = (uint16_t)((tempsquelch / 34) & 0x0FFFF);
  343.     /*
  344.     // XXX: qsort actually causes ~600bits/sec lower bandwidth... why???
  345.     //
  346.     qsort (tempArray,CC1K_SquelchTableSize, sizeof(uint16_t),sortByShort);
  347.     min_value = tempArray[CC1K_SquelchTableSize >> 1];
  348.     atomic usSquelchVal = ((usSquelchVal << 5) + (min_value << 1)) / 34;
  349.     */
  350.   }
  351.   void getTimeDiff(){ // called as soon as time sync message is received, regardless of crc
  352.     atomic{
  353.       uint16_t i, trust;
  354.       GTime loctime, timeStamp;
  355.       syncMsgType* syncMsgPtr = (syncMsgType *) rxbufptr->data;
  356.       timeStamp.mticks = syncMsgPtr->mticks;
  357.       timeStamp.sticks = syncMsgPtr->sticks;
  358.       trust = syncMsgPtr->trust;
  359.       currentSender = syncMsgPtr->sender;
  360.       call SClock.getTime(&loctime);
  361.       currentSign = ModSubTime(&currentDiff, &timeStamp, &loctime);
  362.       if(trust < MIN_TRUST)
  363.         trust = MIN_TRUST;
  364.       if(trust < MAX_TRUST){
  365.         for(i = 0; i < trust; i++){
  366.           DivTime2(&currentDiff, &currentDiff);
  367.         }
  368.       }
  369.     }
  370.   }
  371.   void Blacklist(uint8_t slot, uint8_t fsize){
  372.     uint8_t black_slot;
  373.     atomic {
  374.       if(fsize <= globalFrameLength){
  375.         black_slot = slot;
  376.         while(black_slot < globalFrameLength){
  377.           uint32_t tempHCL2 = 0x1;
  378.           tempHCL2 = tempHCL2 << black_slot;
  379.           curHCLlist = curHCLlist | tempHCL2;
  380.           black_slot = black_slot + fsize;
  381.         }
  382.       }
  383.     }
  384.   }
  385.   
  386.   task void adjustTime(){
  387.     needTimeSync = TRUE;
  388.     call SClock.setTime(currentSign, &currentDiff);
  389. #ifdef ZMAC_TIME_SYNC
  390.     SODbg(DBG_USR2, "diff = %u, %u, from %un", currentDiff.mticks, currentDiff.sticks, currentSender);
  391. #endif
  392.   }
  393.   task void PacketRcvd(){
  394.     TOS_MsgPtr pBuf;
  395.     ecnForwardMsgType *recvEcnMsgPtr;
  396.     ecnForwardMsgType *ecnForwardMsgPtr;
  397.     atomic {
  398.       if(pktsLastSync > SYNC_PERIOD){
  399.         atomic{ 
  400.           ackOrig = bAckEnable;
  401.           bAckEnable = FALSE;
  402.         }
  403.         call Send.send(&syncMsgHdr);
  404.         pktsLastSync = 0;
  405.       }
  406.       pktsLastSync++;
  407.       rxbufptr->time = 0;
  408.       pBuf = rxbufptr;
  409.       recvEcnMsgPtr = (ecnForwardMsgType *) rxbufptr->data;
  410.       ecnForwardMsgPtr = (ecnForwardMsgType *) ecnForwardMsgHdr.data;
  411. #ifdef ZMAC_ECN
  412.       if((currentMAC == ZMAC) && (pBuf->type == ECNTYPE)){
  413.         SODbg(DBG_USR2,"Received %u hop ECN from %u, deciding whether significant..n",
  414.               recvEcnMsgPtr->hopCount, recvEcnMsgPtr->senderAddress);
  415.       }
  416. #endif
  417.       if((currentMAC == ZMAC) && (HCLselect) && (pBuf->type == ECNTYPE) && (pBuf->crc != 0) &&
  418.          (recvEcnMsgPtr->senderAddress != TOS_LOCAL_ADDRESS)){ //Message is an ECN
  419.         if((recvEcnMsgPtr->hopCount == 0) && (recvEcnMsgPtr->nextHop == TOS_LOCAL_ADDRESS)){
  420. #ifdef ZMAC_ECN
  421.           SODbg(DBG_USR2,"Received one-hop ECN from %un", recvEcnMsgPtr->senderAddress);
  422. #endif
  423.           ecnForwardMsgPtr->hopCount = 1;
  424.           ecnForwardMsgPtr->nextHop = nextHop;
  425.           ecnForwardMsgPtr->senderAddress = TOS_LOCAL_ADDRESS;
  426.           if(!bTxBusy){
  427.             ackOrig = bAckEnable;
  428.             bAckEnable = FALSE;
  429.             call Send.send(&ecnForwardMsgHdr);  //take care of case where we are not currently sending
  430. #ifdef ZMAC_ECN
  431.             SODbg(DBG_USR2,"Forwarded ECNn");
  432. #endif
  433.           } else
  434.             ecnforward = TRUE;
  435.         } else if(recvEcnMsgPtr->hopCount == 1){ //check if two-hop ECN
  436. #ifdef ZMAC_ECN
  437.           SODbg(DBG_USR2,"????????????????????? Received two hop ECN from %un", recvEcnMsgPtr->senderAddress);
  438. #endif
  439.           atomic enableHCL = TRUE;
  440.           if(recvEcnMsgPtr->senderAddress == nextHop){  //check forwarding node's address
  441.             //suppress ECN
  442. #ifdef ZMAC_ECN
  443.             SODbg(DBG_USR2,"Suppressed own ECNn");
  444. #endif
  445.             atomic ecnPending = FALSE;
  446.             slots_since_ecnsend = 0;
  447.             slots_since_ecnrecv = 0;
  448.           }
  449.         }
  450.       } else if((pBuf->type != SYNCTYPE) && (pBuf->type != ECNTYPE)){
  451. #ifdef ZMAC_ECN
  452.         //        SODbg(DBG_USR2,"Received packet of type %u, crc = %un", pBuf->type, pBuf->crc);
  453. #endif
  454.         pBuf = signal Receive.receive((TOS_MsgPtr)pBuf);
  455.       }
  456.       
  457.       if (pBuf)
  458.         rxbufptr = pBuf;
  459.       rxbufptr->length = 0;
  460.     }
  461.     call SpiByteFifo.enableIntr();
  462.   }
  463.   
  464.   task void PacketSent() {
  465.     TOS_MsgPtr pBuf; //store buf on stack 
  466.     atomic {
  467.       txbufptr->time = 0;
  468.       pBuf = txbufptr;
  469.     }
  470.       
  471.     if ((txbufptr->type != ECNTYPE) && (txbufptr->type != SYNCTYPE)){
  472.       //      if(txbufptr->type == AM_MULTIHOP)
  473.       //        dataSent++;
  474.       signal Send.sendDone((TOS_MsgPtr)pBuf, SUCCESS);
  475.     } else if(txbufptr->type == SYNCTYPE){
  476. #ifdef ZMAC_DEBUG
  477.       //      SODbg(DBG_USR2, "Sent one sync message $$$$$$$$$n");
  478. #endif
  479.     } else if(txbufptr->type == ECNTYPE){
  480. #ifdef ZMAC_DEBUG
  481.       //      SODbg(DBG_USR2, "Sent one ecn message $$$$$$$$$n");
  482. #endif
  483.     }
  484.       
  485.     atomic bTxBusy = FALSE;
  486.     if(pktsLastSync > SYNC_PERIOD){
  487.       atomic{
  488.         ackOrig = bAckEnable;
  489.         bAckEnable = FALSE;
  490.       }
  491.       call Send.send(&syncMsgHdr);
  492.       pktsLastSync = 0;
  493.     } else if((currentMAC == ZMAC) && (ecnforward == TRUE)){
  494.       atomic{
  495.         ackOrig = bAckEnable;
  496.         bAckEnable = FALSE;
  497.       }
  498.       call Send.send(&ecnForwardMsgHdr);
  499.       atomic ecnforward = FALSE;
  500. #ifdef ZMAC_ECN
  501.       SODbg(DBG_USR2,"Forwarded ECNn");
  502. #endif
  503.     } else if((currentMAC == ZMAC) && (ecnPending == TRUE)){
  504.       atomic{
  505.         ackOrig = bAckEnable;
  506.         bAckEnable = FALSE;
  507.       }
  508.       call Send.send(&ecnMsgHdr);
  509.       atomic ecnPending = FALSE;
  510.       atomic slots_since_ecnsend = 0;
  511. #ifdef ZMAC_ECN
  512.       SODbg(DBG_USR2,"Sent own ECNn");
  513. #endif
  514.     }
  515.   }
  516.   ///**********************************************************
  517.   //* Exported interface functions
  518.   //**********************************************************/
  519.   command void SetDrand.setParent(uint8_t id){ nextHop = id; }
  520.   command result_t SetDrand.Set(nodeInfo *mInfo, uint8_t nHop, nodeInfo *nInfo, uint16_t sSize){
  521.     uint32_t slotOffset = 0, globalTimeStamp = 0;
  522.     GTime loctime;
  523.     uint8_t i = 0;
  524.     slotSize = sSize;
  525.     nextHop = nHop;
  526. #ifdef DRAND_ENABLE
  527.       localFrameLength = mInfo->frame;
  528.       ownSlot = mInfo->slot;
  529.       nbrInfo = nInfo;
  530.       for(i = 0; (i < MAX_NBR) && (nbrInfo[i].nodeID != 0xFF); i++)
  531.         if(nbrInfo[i].bitMap & TWO_HOP)
  532.           Blacklist(nbrInfo[i].slot, nbrInfo[i].frame);
  533. #else
  534.       for(i = 0 ; i<MAX_NBR ; i++){ // initialize the nbr table
  535.         nbrInfo[i].nodeID = 0xFF;
  536.         nbrInfo[i].slot = 0xFF;
  537.         nbrInfo[i].frame = 0xFF;
  538.         nbrInfo[i].bitMap = 0x0;
  539.       }
  540. #include "nbrTable.h"
  541.       /*       slotSize = sSize; */
  542.       /*       localFrameLength = 8; */
  543.       /*       nextHop = nHop; */
  544.       /*       switch(TOS_LOCAL_ADDRESS){ */
  545.       /*       case 1: */
  546.       /*         ownSlot = 6; */
  547.       /*         break; */
  548.       /*       case 10: */
  549.       /*         ownSlot = 4; */
  550.       /*         break; */
  551.       /*       case 11: */
  552.       /*         ownSlot = 0; */
  553.       /*         break; */
  554.       /*       case 13: */
  555.       /*         ownSlot = 1; */
  556.       /*         break; */
  557.       /*       case 2: */
  558.       /*         ownSlot = 1; */
  559.       /*         break; */
  560.       /*       case 20: */
  561.       /*         ownSlot = 1; */
  562.       /*         break; */
  563.       /*       case 21: */
  564.       /*         ownSlot = 2; */
  565.       /*         break; */
  566.       /*       case 22: */
  567.       /*         ownSlot = 7; */
  568.       /*         break; */
  569.       /*       case 24: */
  570.       /*         ownSlot = 0; */
  571.       /*         break; */
  572.       /*       case 0: */
  573.       /*         ownSlot = 5; */
  574.       /*         break; */
  575.       /*       case 8: */
  576.       /*         ownSlot = 2; */
  577.       /*         break; */
  578.       /*       case 9: */
  579.       /*         ownSlot = 3; */
  580.       /*         break; */
  581.       /*       } */
  582.       //    }
  583. #endif
  584.     localFrameSize = localFrameLength * slotSize;
  585.     globalFrameSize = globalFrameLength * slotSize;
  586.     slotMultiplier = (uint16_t) (slotSize * 1.024);
  587.     call SClock.getTime(&loctime);
  588.     globalTimeStamp = (uint32_t)(loctime.mticks * 568.889 + loctime.sticks * 0.00868056); //in ms
  589.     slotOffset = (uint32_t) (1.024 * (slotSize - (globalTimeStamp % slotSize))); // in timer units .976562 = 1000/1024
  590.     slotNum = (uint32_t) (globalTimeStamp/slotSize);
  591.     currentSlot = slotNum & (localFrameLength - 1);
  592.     globalSlot = slotNum & (globalFrameLength - 1);
  593.     
  594.     call TDMATimer.start(TIMER_ONE_SHOT, slotOffset);
  595. #ifdef ZMAC_TIMER
  596.     // SODbg(DBG_USR2,"Started timer slotsize - offset is %in",slotSize - slotOffset);
  597. #endif
  598.     return SUCCESS; 
  599.   }
  600.   command result_t StdControl.init() {
  601.     char i;
  602.     ecnMsgType *ecnMsgPtr = (ecnMsgType *) ecnMsgHdr.data;
  603.     syncMsgType* syncMsgPtr;
  604.     atomic {
  605.       RadioState = DISABLED_STATE;
  606.       RadioTxState = TXSTATE_PREAMBLE;
  607.       rxbufptr = &RxBuf;
  608.       rxbufptr->length = 0;
  609.       rxlength = MSG_DATA_SIZE-2;
  610.       RxBitOffset = 0;
  611.       iSquelchCount = 0;
  612.       
  613.       PreambleCount = 0;
  614.       RSSISampleFreq = 0;
  615.       RxShiftBuf.W = 0;
  616.       iRSSIcount = 0;
  617.       bTxPending = FALSE;
  618.       bTxBusy = FALSE;
  619.       bRSSIValid = FALSE;
  620.       bAckEnable = FALSE; // to test for ECN only
  621.       bCCAEnable = TRUE;
  622.       CC1K_PulseLevel = 300;
  623.       sMacDelay = -1;
  624.       usRSSIVal = -1;
  625.       usSquelchIndex = 0;
  626.       pulse_check_count = 0;
  627.       lplpower =  0;//0x87;
  628.       RSSIInitState = NULL_STATE;
  629.       //      if(TOS_LOCAL_ADDRESS == 0) lplpower = 0;
  630.       //      lplpowertx = 7;
  631.       usSquelchVal = CC1K_SquelchInit;
  632.       currentMAC = BMAC;
  633.       congBackOffs = 0;
  634.       packetsSent = 0;
  635.       pktsLastSync = 0;
  636.       avgLoss = 0.0;
  637.       curHCLlist = 0;
  638.       globalFrameLength = GLOBAL_FRAME_LENGTH;
  639.       localFrameLength = GLOBAL_FRAME_LENGTH;
  640.       slotSize = 50;
  641.       localFrameSize = localFrameLength * slotSize;
  642.       globalFrameSize = globalFrameLength * slotSize;
  643.       ackOrig = bAckEnable;
  644.       ecnPending = FALSE;
  645.       ecnforward = FALSE;
  646.       enableHCL = FALSE; // ecn flag, set if currently ecn is going on ...
  647.       pureHCL = FALSE;
  648.       HCLselect = SELECTHCL;
  649.       needTimeSync = FALSE;
  650.       slots_since_ecnsend = 0;
  651.       slots_since_ecnrecv = 0;
  652.       slots_since_ecncheck = 0;
  653.       ecnMsgHdr.type = ECNTYPE;  //set ecnMsg headers
  654.       ecnMsgHdr.addr = TOS_BCAST_ADDR; //ECN Indicator;
  655.       ecnMsgHdr.length = sizeof(ecnMsgType);
  656.       ecnMsgHdr.group = 125;
  657.       ecnMsgHdr.crc = 0;
  658.       ecnForwardMsgHdr.type = ECNTYPE;
  659.       ecnForwardMsgHdr.addr = TOS_BCAST_ADDR; 
  660.       ecnForwardMsgHdr.length = sizeof(ecnMsgType);
  661.       ecnForwardMsgHdr.group = 125;
  662.       ecnForwardMsgHdr.crc = 0;
  663.       syncMsgPtr = (syncMsgType *) syncMsgHdr.data;
  664.       syncMsgPtr->trust = 1;
  665.       syncMsgPtr->sender = TOS_LOCAL_ADDRESS;
  666.       syncMsgHdr.type = SYNCTYPE;  //set syncMsg headers
  667.       syncMsgHdr.addr = TOS_BCAST_ADDR; //SYNC Indicator;
  668.       syncMsgHdr.length = sizeof(syncMsgType);
  669.       syncMsgHdr.group = 125;
  670.       syncMsgHdr.crc = 0;
  671.       ecnMsgPtr->hopCount = 0; //hopcount
  672.       ecnMsgPtr->nextHop = nextHop; //parent node
  673.       ecnMsgPtr->senderAddress = TOS_LOCAL_ADDRESS;
  674.     }
  675.     for (i = 0; i < CC1K_SquelchTableSize; i++)
  676.       usSquelchTable[(int)i] = CC1K_SquelchInit;
  677.     call SpiByteFifo.initSlave(); // set spi bus to slave mode
  678.    
  679.     call CC1000StdControl.init();
  680.     call CC1000Control.SelectLock(0x9); // Select MANCHESTER VIOLATION
  681.     bInvertRxData = call CC1000Control.GetLOStatus();
  682.     call ADCControl.bindPort(TOS_ADC_CC_RSSI_PORT,TOSH_ACTUAL_CC_RSSI_PORT);
  683.     call ADCControl.init();
  684.     
  685.     call Random.init();
  686.     call TimerControl.init();
  687. #ifdef ZMAC_DEBUG
  688.     init_debug();
  689. #endif
  690.     LocalAddr = TOS_LOCAL_ADDRESS;
  691.     return SUCCESS;
  692.   }
  693.   
  694.   /**
  695.    * Get the current Low Power Listening transmit mode
  696.    * @return mode number (see SetListeningMode)
  697.    */
  698.   async command uint8_t LowPowerListening.GetTransmitMode() {
  699.     return lplpowertx;
  700.   }
  701.   // legacy support
  702.   async command uint8_t GetTransmitMode() {
  703.     return call LowPowerListening.GetTransmitMode();
  704.   }
  705.   /**
  706.    * Set the transmit mode.  This allows for hybrid schemes where
  707.    * the transmit mode is different than the receive mode.
  708.    * Use SetListeningMode first, then change the mode with SetTransmitMode.
  709.    *
  710.    * @param mode mode number (see SetListeningMode)
  711.    * @return SUCCESS if the mode was successfully changed
  712.    */
  713.   async command result_t LowPowerListening.SetTransmitMode(uint8_t power) {
  714.     if ((power >= CC1K_LPL_STATES) || (power == lplpowertx))
  715.       return FAIL;
  716.     // check if the radio is currently doing something
  717.     if ((!bTxPending) && ((RadioState == POWER_DOWN_STATE) || 
  718.                           (RadioState == IDLE_STATE) ||
  719.                           (RadioState == DISABLED_STATE))) {
  720.       atomic {
  721.         lplpowertx = power;
  722.         preamblelen = ((PRG_RDB(&CC1K_LPL_PreambleLength[lplpowertx*2]) << 8)
  723.                        | PRG_RDB(&CC1K_LPL_PreambleLength[(lplpowertx*2)+1]));
  724.       }
  725.       return SUCCESS;
  726.     }
  727.     return FAIL;
  728.   }
  729.   // legacy support
  730.   async command result_t SetTransmitMode(uint8_t power) {
  731.     return call LowPowerListening.SetTransmitMode(power);
  732.   }
  733.   /**
  734.    * Set the current Low Power Listening mode.
  735.    * Setting the LPL mode sets both the check interval and preamble length.
  736.    *
  737.    * Modes include:
  738.    *  0 = Radio full on
  739.    *  1 = 10ms check interval
  740.    *  2 = 25ms check interval
  741.    *  3 = 50ms check interval
  742.    *  4 = 100ms check interval (recommended)
  743.    *  5 = 200ms check interval
  744.    *  6 = 400ms check interval
  745.    *  7 = 800ms check interval
  746.    *  8 = 1600ms check interval
  747.    *
  748.    * @param mode the mode number
  749.    * @return SUCCESS if the mode was successfully changed
  750.    */
  751.   async command result_t LowPowerListening.SetListeningMode(uint8_t power) {
  752.     // valid low power listening values are 0 to 8
  753.     // 0 is "always on" and 8 is lowest duty cycle
  754.     if ((power >= CC1K_LPL_STATES) || (power == lplpower))
  755.       return FAIL;
  756.     // check if the radio is currently doing something
  757.     if ((!bTxPending) && ((RadioState == POWER_DOWN_STATE) || 
  758.                           (RadioState == IDLE_STATE) ||
  759.                           (RadioState == DISABLED_STATE))) {
  760.       // change receiving function in CC1000Radio
  761.       call WakeupTimer.stop();
  762.       atomic {
  763.         if (lplpower == lplpowertx) {
  764.           lplpowertx = power;
  765.         }
  766.         lplpower = power;
  767.       }
  768.       // if successful, change power here
  769.       if (RadioState == IDLE_STATE) {
  770.         RadioState = DISABLED_STATE;
  771.         call StdControl.stop();
  772.         call StdControl.start();
  773.       }
  774.       if (RadioState == POWER_DOWN_STATE) {
  775.         RadioState = DISABLED_STATE;
  776.         call StdControl.start();
  777.         call PowerManagement.adjustPower();
  778.       }
  779.     }
  780.     else {
  781.       return FAIL;
  782.     }
  783.     return SUCCESS;
  784.   }
  785.   // legacy support
  786.   async command result_t SetListeningMode(uint8_t power) {
  787.     return call SetListeningMode(power);
  788.   }
  789.   /**
  790.    * Gets the state of low power listening on the chipcon radio.
  791.    * @return Current low power listening state value
  792.    */
  793.   async command uint8_t LowPowerListening.GetListeningMode() {
  794.     return lplpower;
  795.   }
  796.   // legacy support
  797.   async command uint8_t GetListeningMode() {
  798.     return call LowPowerListening.GetListeningMode();
  799.   } 
  800.   /**
  801.    * Set the preamble length of outgoing packets
  802.    *
  803.    * @param bytes length of the preamble in bytes
  804.    * @return SUCCESS if the preamble length was successfully changed
  805.    */
  806.   async command result_t LowPowerListening.SetPreambleLength(uint16_t bytes) {
  807.     result_t result = FAIL;
  808.     atomic {
  809.       if (RadioState != TX_STATE) {
  810.         preamblelen = bytes;
  811.         result = SUCCESS;
  812.       }
  813.     }
  814.     return result;
  815.   }
  816.   /**
  817.    * Get the preamble length of outgoing packets
  818.    *
  819.    * @return length of the preamble in bytes
  820.    */
  821.   async command uint16_t LowPowerListening.GetPreambleLength() {
  822.     return preamblelen;
  823.   }
  824.   /**
  825.    * Set the check interval (time between waking up and sampling
  826.    * the radio for activity in low power listening)
  827.    *
  828.    * @param ms check interval in milliseconds
  829.    * @return SUCCESS if the check interval was successfully changed
  830.    */
  831.   async command result_t LowPowerListening.SetCheckInterval(uint16_t ms) {
  832.     // sleep time will go into effect after the next wakeup time
  833.     atomic sleeptime = ms;
  834.     return SUCCESS;
  835.   }
  836.   /**
  837.    * Get the check interval currently used by low power listening
  838.    *
  839.    * @return length of the check interval in milliseconds
  840.    */
  841.   async command uint16_t LowPowerListening.GetCheckInterval() {
  842.     return sleeptime;
  843.   }
  844.   event result_t SquelchTimer.fired() {
  845.     char currentRadioState;
  846.     atomic currentRadioState = RadioState;
  847.     if (currentRadioState == IDLE_STATE) {
  848.       atomic RSSIInitState = currentRadioState;
  849.       call RSSIADC.getData();
  850.     }
  851.     return SUCCESS;
  852.   }
  853.   event result_t WakeupTimer.fired() {
  854.     uint8_t currentRadioState;
  855.     if (lplpower == 0)
  856.       return SUCCESS;
  857.     
  858.     atomic currentRadioState = RadioState;
  859.     switch(currentRadioState) {
  860.     case IDLE_STATE:
  861.       if (!bTxPending) {
  862.         atomic {
  863.           RadioState = POWER_DOWN_STATE;
  864.           call SpiByteFifo.disableIntr();
  865.         }
  866.         call WakeupTimer.start(TIMER_ONE_SHOT, sleeptime);
  867.         call SquelchTimer.stop();
  868.         call CC1000StdControl.stop();
  869.       } else {
  870.         call WakeupTimer.start(TIMER_ONE_SHOT, sleeptime);
  871.       }
  872.       break;
  873.     case POWER_DOWN_STATE:
  874.       atomic RadioState = PULSE_CHECK_STATE;
  875.       pulse_check_count = 0;
  876.       call CC1000StdControl.start();
  877.       call CC1000Control.BIASOn();
  878.       call WakeupTimer.start(TIMER_ONE_SHOT, 1);
  879.       return SUCCESS;
  880.       break;
  881.     case PULSE_CHECK_STATE:
  882.       call CC1000Control.RxMode();
  883.       if(!(call RSSIADC.getData())){
  884.         call WakeupTimer.start(TIMER_ONE_SHOT, TIME_BETWEEN_CHECKS);
  885.         atomic RadioState = POWER_DOWN_STATE;
  886.       }
  887.       else {
  888.         TOSH_uwait(80);
  889.       }
  890.       call CC1000StdControl.stop();
  891.       pulse_check_sum ++;
  892.       break;
  893.     default:
  894.       call WakeupTimer.start(TIMER_ONE_SHOT, 5);
  895.     }
  896.     return SUCCESS;
  897.   }
  898.   //added by Mahesh
  899.   event result_t TDMATimer.fired(){
  900.     call TDMATimer.start(TIMER_ONE_SHOT, slotMultiplier);
  901.     slotNum++;
  902.     atomic currentMAC = ZMAC;
  903.     atomic{
  904.       currentSlot = slotNum & (localFrameLength - 1);
  905.       globalSlot = slotNum & (globalFrameLength - 1);
  906. #ifdef ZMAC_TIMER
  907.       SODbg(DBG_USR2,"*************Timer fired with current slot = %u, own slot = %un", currentSlot, ownSlot);
  908. #endif 
  909.       if(HCLselect){
  910.         slots_since_ecnsend ++;
  911.         slots_since_ecnrecv ++;
  912.         slots_since_ecncheck++;
  913.         if((packetsSent > ECNMINPACKETS) && (slots_since_ecncheck >= ECNCHECKPERIOD)){
  914.           double currentLoss = (double)congBackOffs/packetsSent;
  915.           avgLoss = ALPHA * (currentLoss) + (1 - ALPHA) * avgLoss;
  916. #ifdef ZMAC_ECN
  917.           SODbg(DBG_USR2,"#####################Congestion Statistics: %i / %i, %in", congBackOffs, packetsSent, (uint16_t) avgLoss);
  918. #endif
  919.           slots_since_ecncheck = 0;
  920.           congBackOffs = 0;
  921.           packetsSent = 0;
  922.           if((avgLoss > ECNTHRESHOLD) && (slots_since_ecnsend >= ECNSENDPERIOD)){
  923.             ecnMsgType *ecnMsgPtr = (ecnMsgType *) ecnMsgHdr.data;
  924. #ifdef ZMAC_ECN
  925.             SODbg(DBG_USR2,"Setting ECN flagn");
  926. #endif
  927.             // change by acw, go to ecn myself if sending ecn
  928.             atomic enableHCL = TRUE;
  929.             slots_since_ecnrecv = 0;
  930.             // change by acw ends
  931.             ecnMsgPtr->nextHop = nextHop;
  932.             if(!pureHCL)
  933.               ecnPending = TRUE;
  934.           }
  935.         }
  936.         if((enableHCL) && (slots_since_ecnrecv >= ECNEXPIREPERIOD)){
  937.           if(!pureHCL)
  938.             enableHCL = FALSE;
  939. #ifdef ZMAC_ECN
  940.           SODbg(DBG_USR2,"ECN expired, into LCL againn");
  941. #endif
  942.         }
  943.         
  944. #ifdef ZMAC_ECN
  945.         if(enableHCL)
  946.           SODbg(DBG_USR2,"Current slot %i **********************n",currentSlot);
  947. #endif
  948. #ifdef ZMAC_ECN
  949.         if(enableHCL && IsHCL(globalSlot) && ownSlot != currentSlot)
  950.           SODbg(DBG_USR2,"***** ****** ****** ****** Current slot %i HCLn",currentSlot);
  951. #endif
  952.       }
  953.       if(bTxPending){
  954.         sMacDelay = getZMACBackoff(sMacDelay);
  955. #ifdef ZMAC_BACKOFF
  956.         SODbg(DBG_USR2,"TDMATimerFired: backoff %un", sMacDelay);
  957. #endif
  958.       }
  959.     }
  960.     return SUCCESS;
  961.   }
  962.  
  963.   command result_t StdControl.stop() {
  964.     atomic RadioState = DISABLED_STATE;
  965.     call SquelchTimer.stop();
  966.     call WakeupTimer.stop();
  967.     call CC1000StdControl.stop();
  968.     call SpiByteFifo.disableIntr(); // disable spi interrupt
  969.     return SUCCESS;
  970.   }
  971.   command result_t StdControl.start() {
  972.     uint8_t currentRadioState;
  973.     atomic currentRadioState = RadioState;
  974.     call SClock.SetRate(MAX_VAL,CLK_DIV_64);
  975.     if (currentRadioState == DISABLED_STATE) {
  976.       atomic {
  977.         rxbufptr->length = 0;
  978.         RadioState  = IDLE_STATE;
  979.         bTxPending = bTxBusy = FALSE;
  980.         sMacDelay = -1;
  981.         if(SLEEPTIME > 0){
  982.           sleeptime = SLEEPTIME;
  983.           preamblelen = PREAMBLELEN;
  984.         } else{
  985.           lplpower = lplpowertx = 0;
  986.           sleeptime = ((PRG_RDB(&CC1K_LPL_SleepTime[lplpower*2]) << 8) |
  987.                        PRG_RDB(&CC1K_LPL_SleepTime[(lplpower*2)+1]));
  988.           preamblelen = ((PRG_RDB(&CC1K_LPL_PreambleLength[lplpowertx*2]) << 8) |
  989.                          PRG_RDB(&CC1K_LPL_PreambleLength[(lplpowertx*2)+1]));
  990.         }
  991. /*         sleeptime = ((PRG_RDB(&CC1K_LPL_SleepTime[lplpower*2]) << 8) | */
  992. /*                      PRG_RDB(&CC1K_LPL_SleepTime[(lplpower*2)+1])); */
  993. /*         preamblelen = ((PRG_RDB(&CC1K_LPL_PreambleLength[lplpowertx*2]) << 8) | */
  994. /*                        PRG_RDB(&CC1K_LPL_PreambleLength[(lplpowertx*2)+1])); */
  995.       }
  996.       // all power on, captain!
  997.       rxbufptr->length = 0;
  998.       atomic RadioState = IDLE_STATE;
  999.       call CC1000StdControl.start();
  1000.       call CC1000Control.BIASOn();
  1001.       call SpiByteFifo.rxMode(); // SPI to miso
  1002.       call CC1000Control.RxMode();
  1003.       if (iSquelchCount > CC1K_SquelchCount)
  1004.         call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalSlow);
  1005.       else
  1006.         call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalFast);
  1007.       call SpiByteFifo.enableIntr(); // enable spi interrupt
  1008.       if (lplpower > 0) {
  1009.         // set a time to start sleeping after measuring the noise floor
  1010.         call WakeupTimer.start(TIMER_ONE_SHOT, CC1K_SquelchIntervalSlow);
  1011.       }
  1012.     }
  1013.     return SUCCESS;
  1014.   }
  1015.   command result_t Send.send(TOS_MsgPtr pMsg) {
  1016.     result_t Result = SUCCESS;
  1017.     uint8_t currentRadioState = 0;
  1018.    
  1019.     atomic {
  1020.       if (bTxBusy) {
  1021.         Result = FAIL;
  1022. #ifdef ZMAC_DEBUG
  1023.         //        SODbg(DBG_USR2, "Busy sending the message of type %u!n", txbufptr->type);
  1024. #endif
  1025.       } else {
  1026.         bTxBusy = TRUE;
  1027.         txbufptr = pMsg;
  1028.         txlength = pMsg->length + (MSG_DATA_SIZE - DATA_LENGTH - 2);
  1029.         if(bCCAEnable){ // initially back off [1,32] bytes (approx 2/3 packet)
  1030.           if(currentMAC == BMAC)
  1031.             sMacDelay = signal MacBackoff.initialBackoff(pMsg);
  1032.           else
  1033.             sMacDelay = getZMACBackoff(0);
  1034.         } else
  1035.           sMacDelay = 0;
  1036. #ifdef ZMAC_BACKOFF
  1037.         SODbg(DBG_USR2, "SendMSG(): Need to send type %u, myslot %u, current slot %u backoff %un",
  1038.               txbufptr->type, ownSlot, currentSlot, sMacDelay);
  1039. #endif
  1040.         bTxPending = TRUE;
  1041.       }
  1042.       currentRadioState = RadioState;
  1043.     }
  1044.     if (Result) {
  1045.       if (currentRadioState == POWER_DOWN_STATE) {       // if we're off, start the radio
  1046.         atomic RadioState = IDLE_STATE;         // disable wakeup timer
  1047.         call WakeupTimer.stop();
  1048.         call CC1000StdControl.start();
  1049.         call CC1000Control.BIASOn();
  1050.         call CC1000Control.RxMode();
  1051.         call SpiByteFifo.rxMode(); // SPI to miso
  1052.         call SpiByteFifo.enableIntr(); // enable spi interrupt
  1053.         if (iSquelchCount > CC1K_SquelchCount)
  1054.           call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalSlow);
  1055.         else
  1056.           call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalFast);
  1057.         call WakeupTimer.start(TIMER_ONE_SHOT, CC1K_LPL_PACKET_TIME*2);
  1058.       }
  1059.     }
  1060.     return Result;
  1061.   }
  1062.   
  1063.   /**********************************************************
  1064.    * make a spibus interrupt handler
  1065.    * needs to handle interrupts for transmit delay
  1066.    * and then go into byte transmit mode with
  1067.    *   timer1 baudrate delay as interrupt handler
  1068.    * else SODbg(DBG_USR2,"Sending Packet ..");
  1069.    * needs to handle interrupts for byte read and detect preamble
  1070.    *  then handle reading a packet
  1071.    * PB - We can use this interrupt handler as a transmit scheduler
  1072.    * because the CC1000 continuously clocks in data, regarless
  1073.    * of whether it's good or not.  Thus, this routine will be called
  1074.    * on every 8 ticks of DCLK. 
  1075.    **********************************************************/
  1076.   async event result_t SpiByteFifo.dataReady(uint8_t data_in) {
  1077.     GTime loctime;
  1078.     signal RadioSendCoordinator.blockTimer();
  1079.     signal RadioReceiveCoordinator.blockTimer();
  1080.      
  1081.     if (bInvertRxData)
  1082.       data_in = ~data_in;
  1083. #ifdef ENABLE_UART_DEBUG
  1084.     UARTPutChar(RadioState);
  1085. #endif
  1086.     switch (RadioState) {
  1087.     case TX_STATE:
  1088.       {
  1089.         call SpiByteFifo.writeByte(NextTxByte);
  1090.         TxByteCnt++;
  1091.         switch (RadioTxState) {
  1092.           
  1093.         case TXSTATE_PREAMBLE:
  1094.           send_sum ++;
  1095.           if (!(TxByteCnt < preamblelen)||
  1096.               (txbufptr->strength == 0xffff && TxByteCnt >= PREAMBLE_LENGTH_TO_BASE)) {
  1097.             NextTxByte = SYNC_BYTE;
  1098.             RadioTxState = TXSTATE_SYNC;
  1099. #ifdef ZMAC_ECN
  1100.             SODbg(DBG_USR2,"Sent packet in slot %in",currentSlot);
  1101.             SODbg(DBG_USR2, "ishcl = %un", IsHCL(currentSlot));
  1102. #endif
  1103.           }
  1104.           break;
  1105.         case TXSTATE_SYNC:
  1106.           send_sum ++;
  1107.           NextTxByte = NSYNC_BYTE;
  1108.           RadioTxState = TXSTATE_DATA;
  1109.           TxByteCnt = -1;
  1110.           // for Time Sync services
  1111.           signal RadioSendCoordinator.startSymbol(8, 0, txbufptr);
  1112.           break;
  1113.         case TXSTATE_DATA:
  1114.           send_sum ++;
  1115.           if ((uint8_t)(TxByteCnt) < txlength){
  1116.             if((txbufptr->type == SYNCTYPE) && (TxByteCnt == 5)){ // 5 = offset of timestamp
  1117.               syncMsgType *syncMsgPtr = (syncMsgType *) txbufptr->data;
  1118.               call SClock.getTime(&loctime);
  1119.               AddTime(&loctime, &loctime, &constOffset);
  1120.               syncMsgPtr->mticks = loctime.mticks;
  1121.               syncMsgPtr->sticks = loctime.sticks;
  1122.             }
  1123.             NextTxByte = ((uint8_t *)txbufptr)[(TxByteCnt)];
  1124.             usRunningCRC = crcByte(usRunningCRC,NextTxByte);
  1125.             signal RadioSendCoordinator.byte(txbufptr, (uint8_t)TxByteCnt); // Time Sync
  1126.           }
  1127.           else {
  1128.             NextTxByte = (uint8_t)(usRunningCRC);
  1129.             RadioTxState = TXSTATE_CRC;
  1130.           }
  1131.           break;
  1132.         case TXSTATE_CRC:
  1133.           send_sum ++;
  1134.           NextTxByte = (uint8_t)(usRunningCRC>>8);
  1135.           RadioTxState = TXSTATE_FLUSH;
  1136.           TxByteCnt = 0;
  1137.           break;
  1138.         case TXSTATE_FLUSH:
  1139.           send_sum ++;
  1140.           if (TxByteCnt > 3) {
  1141.             TxByteCnt = 0;
  1142. #ifdef ZMAC_DEBUG
  1143.             // SODbg(DBG_USR2,"Came heren");
  1144. #endif
  1145.             if (bAckEnable)
  1146.               RadioTxState = TXSTATE_WAIT_FOR_ACK;         
  1147.             else {
  1148. #ifdef ZMAC_DEBUG
  1149.               // SODbg(DBG_USR2,"came inside: current MAC: %i ackenabled :%i,ecnPending: %i ecnforward %i ecnSENT %in",currentMAC,bAckEnable,ecnPending,ecnforward,sentECN);
  1150. #endif
  1151.               packetsSent ++;
  1152.               call SpiByteFifo.rxMode();
  1153.               call CC1000Control.RxMode();
  1154.               RadioTxState = TXSTATE_DONE;
  1155.             }
  1156.           }
  1157.           break;
  1158.         case TXSTATE_WAIT_FOR_ACK:
  1159.           if(TxByteCnt == 1){
  1160.             send_sum ++;
  1161.             call SpiByteFifo.rxMode();
  1162.             call CC1000Control.RxMode();
  1163.             break;
  1164.           }
  1165.           receive_sum ++;
  1166.           if (TxByteCnt > 3) {
  1167.             RadioTxState = TXSTATE_READ_ACK;
  1168.             TxByteCnt = 0;
  1169.             search_word = 0;
  1170.           }
  1171.           break;
  1172.         case TXSTATE_READ_ACK:
  1173.           {
  1174.             uint8_t i;
  1175.             receive_sum ++;
  1176.             for(i = 0; i < 8; i ++){
  1177.               search_word <<= 1;
  1178.               if(data_in & 0x80) search_word |=  0x1;
  1179.               data_in <<= 1;
  1180.               if (search_word == 0xba83){
  1181.                 txbufptr->ack = 1;
  1182.                 RadioTxState = TXSTATE_DONE;
  1183. #ifdef ZMAC_DEBUG
  1184.                 //                SODbg(DBG_USR2,"received ackn");
  1185. #endif
  1186.                 return SUCCESS;
  1187.               }
  1188.             }
  1189.           }
  1190.           if(TxByteCnt >= MAX_ACK_WAIT){   
  1191.             txbufptr->ack = 0;  
  1192. #ifdef ZMAC_DEBUG
  1193.             //       SODbg(DBG_USR2,"did not receive ack %i %i %in",lostacks,packetsSent,avgLoss * 100);
  1194. #endif
  1195.             RadioTxState = TXSTATE_DONE;
  1196.           }
  1197.           break;
  1198.         case TXSTATE_DONE:
  1199.         default:
  1200.           bTxPending = FALSE;
  1201.           if((txbufptr->type == ECNTYPE) || (txbufptr->type == SYNCTYPE)){
  1202. #ifdef ZMAC_ECN
  1203.             ecnForwardMsgType *ecnForwardMsgPtr = (ecnForwardMsgType *) txbufptr->data;
  1204.             if(txbufptr->type == ECNTYPE && ecnForwardMsgPtr->hopCount == 1)
  1205.               SODbg(DBG_USR2,"Successfully forwarded ECNn");
  1206. #endif
  1207.             bAckEnable = ackOrig;
  1208.           }
  1209. #ifdef ZMAC_BACKOFF
  1210.           SODbg(DBG_USR2, "Sent one packet of type %u, myslot %u, current slot %u!n", txbufptr->type,
  1211.                 ownSlot, currentSlot);
  1212. #endif
  1213.           if(post PacketSent()) {
  1214.             // If the post operation succeeds, goto Idle
  1215.             // otherwise, we'll try again.
  1216. #ifdef ZMAC_DEBUG
  1217.             //  SODbg(DBG_USR2,"Packet type %in",txbufptr->type);
  1218. #endif
  1219.             RadioState = IDLE_STATE;
  1220.             pktsLastSync++;
  1221.             RSSIInitState = RadioState;
  1222.             call RSSIADC.getData();
  1223.           }
  1224.           break;
  1225.         }
  1226.       }
  1227.       break;
  1228.     case DISABLED_STATE:
  1229.       break;
  1230.     case IDLE_STATE: 
  1231.       {
  1232.         receive_sum ++;
  1233.         if (((data_in == (0xaa)) || (data_in == (0x55)))) {
  1234.           PreambleCount++;
  1235.           if (PreambleCount > CC1K_ValidPrecursor) {
  1236.             PreambleCount = SOFCount = 0;
  1237.             RxBitOffset = RxByteCnt = 0;
  1238.             usRunningCRC = 0;
  1239.             rxlength = MSG_DATA_SIZE-2;
  1240.             RadioState = SYNC_STATE;
  1241.           }
  1242.         } else {
  1243.           if ((currentMAC == BMAC) || (enableHCL == FALSE) || (!IsHCL(currentSlot))) {
  1244.             if((bTxPending) && (--sMacDelay <= 0)){
  1245.               RadioState = PRETX_STATE;
  1246.               RSSIInitState = PRETX_STATE;
  1247.               bRSSIValid = FALSE;
  1248.               iRSSIcount = 0;
  1249.               PreambleCount = 0;
  1250.               call RSSIADC.getData();
  1251.             }
  1252.           } else{
  1253. #ifdef ZMAC_ECN
  1254.             SODbg(DBG_USR2, "&&&&&&&&&&&&&&&&&&&&& ishcl = %un", IsHCL(currentSlot));
  1255. #endif
  1256.           }
  1257.         }
  1258.       }
  1259.       break;
  1260.     case PRETX_STATE:
  1261.       {
  1262.         receive_sum ++;
  1263.         if (((data_in == (0xaa)) || (data_in == (0x55)))) {
  1264.           // Back to the penalty box.
  1265.           sMacDelay = signal MacBackoff.congestionBackoff(txbufptr);
  1266. #ifdef ZMAC_BACKOFF
  1267.           SODbg(DBG_USR2,"SpiDataReady: detected preamble - backoff %un", sMacDelay);
  1268. #endif
  1269.           RadioState = IDLE_STATE;
  1270.         }
  1271.       }
  1272.       break;
  1273.     case SYNC_STATE:
  1274.       {
  1275.         // draw in the preamble bytes and look for a sync byte
  1276.         // save the data in a short with last byte received as msbyte
  1277.         //    and current byte received as the lsbyte.
  1278.         // use a bit shift compare to find the byte boundary for the sync byte
  1279.         // retain the shift value and use it to collect all of the packet data
  1280.         // check for data inversion, and restore proper polarity 
  1281.         // XXX-PB: Don't do this.
  1282.         uint8_t i;
  1283.         receive_sum ++;
  1284.         if ((data_in == 0xaa) || (data_in == 0x55)) {
  1285.           // It is actually possible to have the LAST BIT of the incoming
  1286.           // data be part of the Sync Byte.  SO, we need to store that
  1287.           // However, the next byte should definitely not have this pattern.
  1288.           // XXX-PB: Do we need to check for excessive preamble?
  1289.           RxShiftBuf.MSB = data_in;
  1290.         }
  1291.         else {
  1292.           // TODO: Modify to be tolerant of bad bits in the preamble...
  1293.           uint16_t usTmp;
  1294.           switch (SOFCount) {
  1295.           case 0:
  1296.             RxShiftBuf.LSB = data_in;
  1297.             break;
  1298.   
  1299.           case 1:
  1300.           case 2: 
  1301.           case 3: 
  1302.           case 4: 
  1303.           case 5: 
  1304.             // bit shift the data in with previous sample to find sync
  1305.             usTmp = RxShiftBuf.W;
  1306.             RxShiftBuf.W <<= 8;
  1307.             RxShiftBuf.LSB = data_in;
  1308.             for(i=0;i<8;i++) {
  1309.               usTmp <<= 1;
  1310.               if(data_in & 0x80)
  1311.                 usTmp  |=  0x1;
  1312.               data_in <<= 1;
  1313.               // check for sync bytes
  1314.               if (usTmp == SYNC_WORD) {
  1315.                 if (rxbufptr->length !=0) {
  1316.                   call Leds.redToggle();
  1317.                   RadioState = IDLE_STATE;
  1318.                 }
  1319.                 else {
  1320.                   RadioState = RX_STATE;
  1321.                   RSSIInitState = RX_STATE;
  1322.                   call RSSIADC.getData();
  1323.                   RxBitOffset = 7-i;
  1324.                   // For time sync services
  1325.                   signal RadioReceiveCoordinator.startSymbol(8, RxBitOffset, rxbufptr); 
  1326.                 }
  1327.                 break;
  1328.               }
  1329.             }
  1330.             break;
  1331.           default:
  1332.             // We didn't find it after a reasonable number of tries, so....
  1333.             RadioState = IDLE_STATE;  // Ensures we wait till the end of the transmission
  1334.             break;
  1335.           }
  1336.           SOFCount++;
  1337.         }
  1338.       }
  1339.       break;
  1340.       //  collect the data and shift into double buffer
  1341.       //  shift out data by correct offset
  1342.       //  invert the data if necessary
  1343.       //  stop after the correct packet length is read
  1344.       //  return notification to upper levels
  1345.       //  go back to idle state
  1346.     case RX_STATE:
  1347.       {
  1348.         char Byte;
  1349.         receive_sum ++;
  1350.         RxShiftBuf.W <<=8;
  1351.         RxShiftBuf.LSB = data_in;
  1352.         Byte = (RxShiftBuf.W >> RxBitOffset);
  1353.         ((char*)rxbufptr)[(int)RxByteCnt] = Byte;
  1354.         RxByteCnt++;
  1355.         signal RadioReceiveCoordinator.byte(rxbufptr, (uint8_t)RxByteCnt);
  1356.         if (RxByteCnt < rxlength) {
  1357.           usRunningCRC = crcByte(usRunningCRC,Byte);
  1358.           if (RxByteCnt == (offsetof(struct TOS_Msg,length) + 
  1359.                             sizeof(((struct TOS_Msg *)0)->length))) {
  1360.             rxlength = rxbufptr->length;
  1361.             if (rxlength > TOSH_DATA_LENGTH) {
  1362.               // The packet's screwed up, so just dump it
  1363.               rxbufptr->length = 0;
  1364.               RadioState = IDLE_STATE;  // Waits till end of transmission
  1365.               return SUCCESS;
  1366.             }
  1367.             //Add in the header size
  1368.             rxlength += offsetof(struct TOS_Msg,data);
  1369.           }
  1370.         }
  1371.         else if (RxByteCnt == rxlength) {
  1372.           if(rxbufptr->type == SYNCTYPE) // got all bytes of time stamp !
  1373.             getTimeDiff();
  1374.           usRunningCRC = crcByte(usRunningCRC,Byte);
  1375.           // Shift index ahead to the crc field.
  1376.           RxByteCnt = offsetof(struct TOS_Msg,crc);
  1377.         }
  1378.         else if (RxByteCnt >= MSG_DATA_SIZE) { 
  1379.           // Packet filtering based on bad CRC's is done at higher layers.
  1380.           // So sayeth the TOS weenies.
  1381.           if (rxbufptr->crc == usRunningCRC) {
  1382.             if(rxbufptr->type == SYNCTYPE)
  1383.               post adjustTime();
  1384.             rxbufptr->crc = 1;
  1385.             
  1386.             if(bAckEnable && (rxbufptr->addr == TOS_LOCAL_ADDRESS)){
  1387.               RadioState = SENDING_ACK; 
  1388.               call CC1000Control.TxMode();
  1389.               call SpiByteFifo.txMode();
  1390.               call SpiByteFifo.writeByte(0xaa);
  1391.               RxByteCnt = 0;
  1392.               return SUCCESS; 
  1393.             }
  1394.           } else {
  1395.             rxbufptr->crc = 0;
  1396.           }
  1397.           call SpiByteFifo.disableIntr();
  1398.   
  1399.           RadioState = IDLE_STATE; //DISABLED_STATE;
  1400.           if((currentMAC == ZMAC) && (bTxPending)){ //Ajit - reset timer when time slot boundary
  1401.             sMacDelay = getZMACBackoff(sMacDelay);
  1402. #ifdef ZMAC_BACKOFF
  1403.             SODbg(DBG_USR2,"JustAfterReceive: backoff %u mySlot %u currentSlot %un", sMacDelay,
  1404.                   ownSlot, currentSlot);
  1405. #endif
  1406.           }
  1407.           rxbufptr->strength = usRSSIVal;
  1408.           if (!(post PacketRcvd())) {
  1409.             // If there are insufficient resources to process the incoming packet
  1410.             // we drop it
  1411.             rxbufptr->length = 0;
  1412.             RadioState = IDLE_STATE;
  1413.             call SpiByteFifo.enableIntr();
  1414.           }
  1415.           RSSIInitState = RadioState;
  1416.           call RSSIADC.getData();
  1417.         }
  1418.       }
  1419.       break;
  1420.     case SENDING_ACK:
  1421.       {
  1422.         send_sum ++;
  1423.         RxByteCnt++;
  1424.         if (RxByteCnt >= ACK_LENGTH) { 
  1425.           call CC1000Control.RxMode();
  1426.           call SpiByteFifo.rxMode();
  1427.           call SpiByteFifo.disableIntr();
  1428.           RadioState = IDLE_STATE; //DISABLED_STATE;
  1429.           rxbufptr->strength = usRSSIVal;
  1430.           if (!(post PacketRcvd())) {
  1431.             rxbufptr->length = 0;
  1432.             RadioState = IDLE_STATE;
  1433.             call SpiByteFifo.enableIntr();
  1434.           }
  1435.         }else if(RxByteCnt >= ACK_LENGTH - sizeof(ack_code)){
  1436.           call SpiByteFifo.writeByte(ack_code[RxByteCnt + sizeof(ack_code) - ACK_LENGTH]);
  1437.         }
  1438.       }
  1439.       break;
  1440.     default:
  1441.       break;
  1442.     }
  1443.     if(pulse_check_sum > CHECK_MA_COUNT){
  1444.       power_sum ++;
  1445.       sp_sum++;
  1446.       pulse_check_sum -= CHECK_MA_COUNT;
  1447.     }
  1448.     if(send_sum > SEND_MA_COUNT){
  1449.       power_sum ++;
  1450.       tx_sum++;
  1451.       send_sum -= SEND_MA_COUNT;
  1452.     }
  1453.     if(receive_sum > RECEIVE_MA_COUNT){
  1454.       power_sum ++;
  1455.       rx_sum++;
  1456.       receive_sum -= RECEIVE_MA_COUNT;
  1457.     }
  1458.     return SUCCESS;
  1459.   }
  1460.   task void IdleTimerTask(){
  1461.     if (iSquelchCount > CC1K_SquelchCount)
  1462.       call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalSlow);
  1463.     else
  1464.       call SquelchTimer.start(TIMER_REPEAT, CC1K_SquelchIntervalFast);
  1465.     call WakeupTimer.start(TIMER_ONE_SHOT, TIME_AFTER_CHECK);
  1466.     /*if(pulse_check_sum > CHECK_MA_COUNT){
  1467.       power_sum ++;
  1468.       pulse_check_sum -= CHECK_MA_COUNT;
  1469.       }
  1470.       if(send_sum > SEND_MA_COUNT){
  1471.       power_sum ++;
  1472.       send_sum -= SEND_MA_COUNT;
  1473.       }
  1474.       if(receive_sum > RECEIVE_MA_COUNT){
  1475.       power_sum ++;
  1476.       receive_sum -= RECEIVE_MA_COUNT;
  1477.       }*/
  1478.   }
  1479.   task void SleepTimerTask(){
  1480.     call WakeupTimer.start(TIMER_ONE_SHOT, sleeptime);
  1481.   }
  1482.   async event result_t RSSIADC.dataReady(uint16_t data) { 
  1483.     atomic{
  1484.       uint8_t currentRadioState;
  1485.       // TOSH_CLR_PW3_PIN();
  1486.       currentRadioState = RadioState;
  1487.       // find the maximum RSSI value over CC1K_MAX_RSSI_SAMPLES
  1488.       switch(currentRadioState) {
  1489.       case IDLE_STATE:
  1490.         if (RSSIInitState == IDLE_STATE) {
  1491.           atomic usTempSquelch = data;
  1492.           post adjustSquelch();
  1493.         }
  1494.         RSSIInitState = NULL_STATE;
  1495.         break;
  1496.           
  1497.       case RX_STATE:
  1498.         if (RSSIInitState == RX_STATE) {
  1499.           atomic usRSSIVal = data;
  1500.         }
  1501.         RSSIInitState = NULL_STATE;
  1502.         break;
  1503.         
  1504.       case PRETX_STATE:
  1505.         iRSSIcount++;
  1506.         
  1507.         // if the channel is clear or CCA is disabled, GO GO GO!
  1508.         if (((data > (usSquelchVal + CC1K_SquelchBuffer)) ||
  1509.              (!bCCAEnable)) && (RSSIInitState == PRETX_STATE)) { 
  1510.           call SpiByteFifo.writeByte(0xaa);
  1511.           call CC1000Control.TxMode();
  1512.           call SpiByteFifo.txMode();
  1513.           
  1514.           usRSSIVal = data;
  1515.           iRSSIcount = CC1K_MaxRSSISamples;
  1516.           bRSSIValid = TRUE;
  1517.           TxByteCnt = 0;
  1518.           usRunningCRC = 0;
  1519.           RadioState = TX_STATE;
  1520.           RadioTxState = TXSTATE_PREAMBLE;
  1521.           NextTxByte = 0xaa;
  1522.           RSSIInitState = NULL_STATE;
  1523.         }
  1524.         else {
  1525.           RSSIInitState = NULL_STATE;
  1526.           if (iRSSIcount == CC1K_MaxRSSISamples) {
  1527.             sMacDelay = signal MacBackoff.congestionBackoff(txbufptr);
  1528. #ifdef ZMAC_BACKOFF
  1529.             SODbg(DBG_USR2,"adcDataReady: channel busy, backoff %un", sMacDelay);
  1530. #endif
  1531.             RadioState = IDLE_STATE;
  1532.           }
  1533.           else {
  1534.             RSSIInitState = currentRadioState;
  1535.             call RSSIADC.getData();
  1536.           }
  1537.         }
  1538.         break;
  1539.         
  1540.       case PULSE_CHECK_STATE:
  1541.         atomic{
  1542.           uint8_t done = 0;
  1543.           uint16_t threshold = call GetSquelch();
  1544.           threshold = threshold - (call GetSquelch() >> 2);
  1545.           if(data > threshold){
  1546.             // adjust the noise floor level
  1547.             atomic usTempSquelch = data;
  1548.             post adjustSquelch();
  1549.             
  1550.           }else if(pulse_check_count > 5){
  1551.             //go to the idle state since no outliers were found
  1552.             call CC1000Control.RxMode();
  1553.             RadioState = IDLE_STATE;
  1554.             call SpiByteFifo.rxMode();     // SPI to miso
  1555.             call SpiByteFifo.enableIntr(); // enable spi interrupt
  1556.             post IdleTimerTask();
  1557.             done = 1;
  1558.             
  1559.           }else {
  1560.             call CC1000Control.RxMode();
  1561.             if(call RSSIADC.getData()){
  1562.               TOSH_uwait(80);
  1563.               pulse_check_count ++;
  1564.               done = 1;
  1565.             }
  1566.             pulse_check_sum ++;
  1567.             call CC1000StdControl.stop();
  1568.           }
  1569.             
  1570.           if (bTxPending) { // bug fixed by Dr. Rhee
  1571.             //go to the idle state since no outliers were found
  1572.             call CC1000Control.RxMode();
  1573.             RadioState = IDLE_STATE;
  1574.             call SpiByteFifo.rxMode();     // SPI to miso
  1575.             call SpiByteFifo.enableIntr(); // enable spi interrupt
  1576.             post IdleTimerTask();
  1577.             done = 1;
  1578.           }
  1579.           if(done == 0){
  1580.             post SleepTimerTask();
  1581.             RadioState = POWER_DOWN_STATE;
  1582.             call SpiByteFifo.disableIntr();
  1583.           }
  1584.         }
  1585.         //go to the power down state
  1586.         break;
  1587.       default:
  1588.       }
  1589.     }
  1590.     return SUCCESS;
  1591.   }
  1592.   // XXX:JP- for testing the mac layer squlech value
  1593.   async command uint16_t GetSquelch() {
  1594.     return usSquelchVal;
  1595.   }
  1596.   // XXX:JP- for testing the mac layer power consumption
  1597.   async command uint16_t GetPower() {
  1598.     return power_sum;
  1599.   }
  1600.   async command uint16_t GetDataSent() {
  1601.     return dataSent;
  1602.   }
  1603.   async command result_t ResetDataSent() {
  1604.     dataSent = 0;
  1605.     return SUCCESS;
  1606.   }
  1607.   async command uint16_t GetPower_tx() {
  1608.     return tx_sum;
  1609.   }
  1610.   async command uint16_t GetPower_rx() {
  1611.     return rx_sum;
  1612.   }
  1613.   async command uint16_t GetPower_sp() {
  1614.     return sp_sum;
  1615.   }
  1616.   async command result_t ResetPower() {
  1617.     power_sum = 0;
  1618.     pulse_check_sum = 0;
  1619.     send_sum = 0;
  1620.     receive_sum = 0;
  1621.     sp_sum = 0;
  1622.     tx_sum = 0;
  1623.     rx_sum = 0;
  1624.     return SUCCESS;
  1625.   }
  1626.   async command result_t MacControl.enableAck() {
  1627.     atomic bAckEnable = TRUE;
  1628.     return SUCCESS;
  1629.   }
  1630.   async command result_t MacControl.disableAck() {
  1631.     atomic bAckEnable = FALSE;
  1632.     return SUCCESS;
  1633.   }
  1634.   async command result_t MacControl.enableCCA() {
  1635.     atomic bCCAEnable = TRUE;
  1636.     return SUCCESS;
  1637.   }
  1638.   async command result_t MacControl.disableCCA() {
  1639.     atomic bCCAEnable = FALSE; 
  1640.     return SUCCESS;
  1641.   }
  1642.   // ***Not yet implemented
  1643.   async command TOS_MsgPtr MacControl.HaltTx() {
  1644.     return 0;
  1645.   }
  1646.   // Default events for radio send/receive coordinators do nothing.
  1647.   // Be very careful using these, you'll break the stack.
  1648.   default async event void RadioSendCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset,
  1649.                                                             TOS_MsgPtr msgBuff) { }
  1650.   default async event void RadioSendCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }
  1651.   default async event void RadioSendCoordinator.blockTimer() { }
  1652.   default async event void RadioReceiveCoordinator.startSymbol(uint8_t bitsPerBlock, uint8_t offset,
  1653.                                                                TOS_MsgPtr msgBuff) { }
  1654.   default async event void RadioReceiveCoordinator.byte(TOS_MsgPtr msg, uint8_t byteCount) { }
  1655.   default async event void RadioReceiveCoordinator.blockTimer() { }
  1656.   default async event int16_t MacBackoff.initialBackoff(TOS_MsgPtr m){
  1657.     return (call Random.rand() & 0x1F) + 1;
  1658.   }
  1659.   default async event int16_t MacBackoff.congestionBackoff(TOS_MsgPtr m){
  1660.     congBackOffs++;
  1661.     return (call Random.rand() & 0xF) + 1;
  1662.   }
  1663.   /**************SClock Interface********/
  1664.   async event result_t SClock.syncDone(){
  1665.     if(needTimeSync){
  1666.       GTime loctime;
  1667.       uint32_t globalTimeStamp, slotOffset;
  1668.       call SClock.getTime(&loctime);
  1669.       globalTimeStamp = (uint32_t)(loctime.mticks * 568.889 + loctime.sticks * 0.00868056); //in ms
  1670.       slotOffset = (uint32_t) (1.024 * (slotSize - (globalTimeStamp % slotSize))); // in timer units .976562 = 1000/1024
  1671.       slotNum = (uint32_t) (globalTimeStamp/slotSize);
  1672.       currentSlot = slotNum & (localFrameLength - 1);
  1673.       globalSlot = slotNum & (globalFrameLength - 1);
  1674.       if(currentMAC == ZMAC)
  1675.         call TDMATimer.start(TIMER_ONE_SHOT, slotOffset);
  1676.       needTimeSync = FALSE;
  1677.     }
  1678.     return SUCCESS;
  1679.   }
  1680.   async event result_t SClock.fire(uint16_t mticks){ return SUCCESS; }  
  1681. }