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

网络

开发平台:

Others

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