⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smacm.nc

📁 tinyos最新版
💻 NC
📖 第 1 页 / 共 5 页
字号:
         }         if (length == 0 || length > PHY_MAX_PKT_LEN) {            uartDebug_txByte(SMAC_UCAST_REQUEST_REJECTED_PKTLEN_ERROR);         }         if (numFrags == 0) {            uartDebug_txByte(SMAC_UCAST_REQUEST_REJECTED_NUMFRAGS_IS_0);         }         return FAIL;      }      getNodeIdx(toAddr, &nodeIdx, &emptyIdx);#ifndef SMAC_NO_SLEEP_CYCLE      if (nodeIdx == SMAC_MAX_NUM_NEIGHB) { // unknown neighbor         return FAIL;      } else {         schedId = neighbList[nodeIdx].schedId;      }#endif      // Don't accept Tx request if I have already accepted a request      // disable interrupt when check the value of txRequest      intEnabled = inp(SREG) & 0x80;      cli();      if (txRequest == 0) {         txRequest = 1;         if (intEnabled) sei();      } else {              if (intEnabled) sei();         uartDebug_txByte(SMAC_UCAST_REQUEST_REJECTED_TXREQUEST_IS_1);         return FAIL;      }            dataPkt = (MACHeader*)data;      sendAddr = toAddr;      txPktLen = length;      txFragAll = numFrags;      txFragCount = 0;      numRetry = 0;      numExtend = 0;      // calculate duration of data packet/fragment      durDataPkt = (PRE_PKT_BYTES + length * ENCODE_RATIO)                   * 8 / BANDWIDTH + 1;      // fill in MAC header fields except duration      dataPkt->type = DATA_PKT << 4;  // higher 4 bits      dataPkt->toAddr = sendAddr;      dataPkt->fromAddr = TOS_LOCAL_ADDRESS;      if (nodeIdx < SMAC_MAX_NUM_NEIGHB) { // known neighbor         dataPkt->seqFragNo = neighbList[nodeIdx].txSeqNo << 3; //higher 5 bits         neighbList[nodeIdx].txSeqNo = (neighbList[nodeIdx].txSeqNo++) & 0x1f;      }#ifdef SMAC_NO_SLEEP_CYCLE      // try to send now      tryToSend();#else      // set flag for data transmission      dataSched = schedId;      schedTab[schedId].txData = 1;#endif      return SUCCESS;   }   command result_t MACComm.txNextFrag(void* data)   {      // Send subsequent fragments      if (state != TX_NEXT_FRAG || data == 0) return FAIL;      dataPkt = (MACHeader*)data;      // fill in MAC header fields except duration      dataPkt->type = DATA_PKT << 4;  // data pkt      dataPkt->toAddr = sendAddr;      dataPkt->fromAddr = TOS_LOCAL_ADDRESS;      dataPkt->seqFragNo++; // = txFragCount; // fragNo <= 7      if (neighbNav >= (SIFS + durDataPkt + timeWaitCtrl)) {         // schedule to send this fragment         state = TX_PKT;         howToSend = SEND_DATA;         txDelay = SIFS;      } // else will retry when neighbNav timeout      return SUCCESS;   }   command result_t MACComm.txReset()   {      // force MAC to drop currently buffered tx packet      // so that it will accept a new one#ifndef SMAC_NO_SLEEP_CYCLE      uint8_t i;      for (i = 0; i < SMAC_MAX_NUM_SCHED; i++) {         schedTab[i].txData = 0;      }#endif      txRequest = 0;	      return SUCCESS;   }   void startBcast()   {      // broadcast data directly; don't use RTS/CTS#ifdef SMAC_DEBUG      *((char*)dataPkt + sizeof(MACHeader) + 10) = numLenErr;      *((char*)dataPkt + sizeof(MACHeader) + 11) = numCrcErr;      *((char*)dataPkt + sizeof(MACHeader) + 12) = numSlpPkt;      *((char*)dataPkt + sizeof(MACHeader) + 13) = numCTStimeout;      *((char*)dataPkt + sizeof(MACHeader) + 14) = numDATAtimeout;      *((char*)dataPkt + sizeof(MACHeader) + 15) = numACKtimeout;	      *((char*)dataPkt + sizeof(MACHeader) + 17) = numSleeps;      *((char*)dataPkt + sizeof(MACHeader) + 18) = numWakeups;      *((char*)dataPkt + sizeof(MACHeader) + 19) = neighbNav;      *((char*)dataPkt + sizeof(MACHeader) + 20) = syncDiff1;      *((char*)dataPkt + sizeof(MACHeader) + 21) = syncDiff2;      *(uint16_t*)((char*)dataPkt + sizeof(MACHeader) + 22) = schedTab[0].counter;      *(uint16_t*)((char*)dataPkt + sizeof(MACHeader) + 24) = schedTab[1].counter;#endif#ifdef SMAC_TX_TIME_STAMP      dataPkt->txTimeStamp = clockTime;#endif      call PhyComm.txPkt(dataPkt, txPktLen);      radioState = RADIO_TX;      state = TX_PKT;      geneTime = TX_PKT_DONE_TIME;   }   void txMsgDone()   {      // update schedTab and neighbList if flags are set when txRequest=1      update_schedTab_neighbList();      // prepare to tx next msg      txRequest = 0;#ifdef SMAC_NO_SLEEP_CYCLE      state = IDLE;      uartDebug_txByte(state);#else      schedTab[dataSched].txData = 0;      sleep(TRY);#endif      signal MACComm.unicastDone(dataPkt, txFragCount);   }   void update_schedTab_neighbList()   {      //update schedTab and neighbList if flag is set      //we should update the schedTab[].numNodes before we call checkMySched()      //to ensure the next available schedule is correct      check_schedFlag();      if (updateNeighbList == 1) {         update_neighbList();         updateNeighbList = 0;         schedTab[0].chkSched = 0;  //we already did checkMySched() in update_neighbList()         }else if (schedTab[0].chkSched == 1) {         checkMySched();         schedTab[0].chkSched = 0;         }   }   event result_t PhyComm.txPktDone(void* packet)   {      char pktType;      geneTime = 0;      radioState = RADIO_IDLE;      if (packet == 0 || state != TX_PKT) return FAIL;  // CHECK if needed      pktType = (*((char*)packet + sizeof(PhyHeader))) >> 4;      switch (pktType) {  // the type field      case SYNC_PKT:         schedTab[syncSched].txSync = 0;         state = IDLE;         // reset SYNC timer after sending to my schedule         if (syncSched == 0) timeToTxSync = SYNC_PERIOD;         if (numSyncTx > 0) {            numSyncTx--;  // SYNC is done for one schedule            if (numSyncTx == 0) syncSeqNo++;  // increase sequence number         }         uartDebug_txByte(TX_SYNC_DONE);         break;      case RTS_PKT:         // track neighbors' NAV, need to clear it if CTS timeout         TRACK_NAV(((MACCtrlPkt*)packet)->duration);         // just sent RTS, set timer for CTS timeout         state = WAIT_CTS;         geneTime = timeWaitCtrl;         uartDebug_txByte(TX_RTS_DONE);         break;      case CTS_PKT:  // just sent CTS         // track my neighbors' NAV         // they update NAV and go to sleep after recv CTS         TRACK_NAV(((MACCtrlPkt*)packet)->duration);         state = WAIT_DATA;         // no data timeout, just use neighbors' NAV         // since they went to sleep, just wait data for the entire time         uartDebug_txByte(TX_CTS_DONE);         break;      case DATA_PKT:         if (((MACHeader*)packet)->toAddr == TOS_BCAST_ADDR) {            uartDebug_txByte(TX_BCAST_DONE);#ifdef SMAC_NO_SLEEP_CYCLE            state = IDLE;            uartDebug_txByte(state);            txRequest = 0;            signal MACComm.broadcastDone(dataPkt);#else            // broadcast data is done for one schedule            schedTab[dataSched].txData = 0;            sleep(TRY);            numBcast--;            if (numBcast == 0) {               // broadcast is done for all schedules               // update schedTab and neighbList if flags are set when txRequest=1               update_schedTab_neighbList();               txRequest = 0;               signal MACComm.broadcastDone(dataPkt);            }#endif         } else {  // unicast is done            state = WAIT_ACK;            // waiting for ACK, set timer for ACK timeout            geneTime = timeWaitCtrl;            uartDebug_txByte(TX_UCAST_DONE);         }         break;      case ACK_PKT:         TRACK_NAV(((MACCtrlPkt*)packet)->duration); // in case tx extended.         // MAC stay in WAIT_DATA state until neighbNav becomes zero         state = WAIT_DATA;         uartDebug_txByte(TX_ACK_DONE);         break;      }      return SUCCESS;   }   void tryToResend(uint8_t delay)   {      // try to re-send a packet when CTS or ACK timeout      if (numRetry < SMAC_RETRY_LIMIT) {         numRetry++;#ifdef SMAC_NO_SLEEP_CYCLE         state = IDLE;         uartDebug_txByte(state);         if (delay == 0) tryToSend();         else retryTime = delay;#else         // wait unitl receiver's next wake-up time         sleep(TRY);#endif      } else {         // reached retry limit, give up Tx         txMsgDone(); // with txFragCount < txFragAll;      }   }   void adaptiveListen()   {      // adaptively wake-up at the end of current transmission. Will try to       // send only if the buffered packet is unicast. Since my next-hop       // neighbor may not be aware of the Tx of my previous-hop neighbor,       // broadcast now is unreliable.      if (srchNeighb == 1 ||          schedTab[0].counter > dataTime + listenTime ||         schedTab[0].counter < dataTime) {         adapTime = dataTime; // set timer to bring me back to sleep         if (state == SLEEP) wakeup();         else state = IDLE;         uartDebug_txByte(state);         if (txRequest == 1 && sendAddr != TOS_BCAST_ADDR &&            (schedTab[dataSched].counter >             dataTime + listenTime ||            schedTab[dataSched].counter < dataTime)) {            tryToSend();         }      } else {         sleep(TRY);      }   }   event void Clock.fire()   {      // handle clock event      uint8_t numRemain;#ifndef SMAC_NO_SLEEP_CYCLE      uint8_t i;      char intEnabled;      uint16_t backoffSlots, listenBits;#endif#ifdef SMAC_PERFORMANCE      if (cntRadioTime) {         if (radioState == RADIO_SLEEP)            radioTime.sleepTime++;         else if (radioState == RADIO_IDLE)            radioTime.idleTime++;         else if (radioState == RADIO_RX)            radioTime.rxTime++;         else if (radioState == RADIO_TX)            radioTime.txTime++;      }#endif      // advance clock      clockTime++;            // NAV timer      if (nav > 0) {         nav--;         if (nav == 0) {  // my neighbor is done Tx/Rx            uartDebug_txByte(TIMER_FIRE_NAV);#if defined SMAC_NO_SLEEP_CYCLE            wakeup();            if (txRequest == 1) {               uartDebug_txByte(SMAC_TX_REQUEST_IS_1);               tryToSend();            } else {               uartDebug_txByte(SMAC_TX_REQUEST_IS_0);            }#elif defined SMAC_NO_ADAPTIVE_LISTEN            if (srchNeighb == 1) wakeup();#else            adaptiveListen();#endif         }      }      // timer to track my neighbor's NAV      if (neighbNav > 0) {         neighbNav--;         if (neighbNav == 0) {  // used up reserved Tx/Rx time            uartDebug_txByte(TIMER_FIRE_NEIGHBOR_NAV);            if (state == WAIT_ACK || state == TX_NEXT_FRAG) {               // last tx is not done within reserved time               tryToResend(0);  // try to resend now            } else { // could be in sleep, idle or wait_data state#if defined SMAC_NO_SLEEP_CYCLE               state = IDLE;               uartDebug_txByte(state);               if (txRequest == 1) {                  uartDebug_txByte(SMAC_TX_REQUEST_IS_1);                  tryToSend();               } else {                  uartDebug_txByte(SMAC_TX_REQUEST_IS_0);               }#elif defined SMAC_NO_ADAPTIVE_LISTEN               sleep(TRY);#else			               adaptiveListen();#endif            }         }      }      // generic timer      if (geneTime > 0) {         geneTime--;         if (geneTime == 0) {            if (state == DATA_SENSE1) {               uartDebug_txByte(TIMER_FIRE_DATA_SENSE1);               // didn't see a CTS reply to a previous RTS               geneTime = timeWaitCtrl;               state = DATA_SENSE2;               uartDebug_txByte(state);            } else if (state == DATA_SENSE2) {               uartDebug_txByte(TIMER_FIRE_DATA_SENSE2);               // didn't see data tx, sender of RTS didn't get a CTS               nav = 0;  // cancel my NAV#ifdef SMAC_NO_SLEEP_CYCLE               state = IDLE;               uartDebug_txByte(state);               if (txRequest == 1) {                  uartDebug_txByte(SMAC_TX_REQUEST_IS_1);                  tryToSend();               } else {                  uartDebug_txByte(SMAC_TX_REQUEST_IS_0);               }#else               sleep(TRY);#endif            } else if (state == WAIT_CTS) {	// CTS timeout               uartDebug_txByte(TIMER_FIRE_WAIT_CTS);#ifdef SMAC_DEBUG               numCTStimeout++;#endif               neighbNav = 0; // neighbors won't follow my reserved time               tryToResend(EIFS); // wait neighbors in data_sense2            } else if (state == WAIT_ACK) {	// ACK timeout               uartDebug_txByte(TIMER_FIRE_WAIT_ACK);#ifdef SMAC_DEBUG               numACKtimeout++;#endif               if (numExtend < SMAC_EXTEND_LIMIT &&                   neighbNav > durDataPkt) {                  // can extend tx time                  numExtend++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -