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

📄 smacm.nc

📁 tinyos最新版
💻 NC
📖 第 1 页 / 共 5 页
字号:
      result_t knownNeighb;      MACHeader* packet = (MACHeader*)pkt;            // check if it is from a known neighbor      knownNeighb = getNodeIdx(packet->fromAddr, &nodeIdx, &emptyIdx);#ifdef SMAC_NO_SLEEP_CYCLE      if (!knownNeighb && emptyIdx != SMAC_MAX_NUM_NEIGHB) {         // put the new node into neighbor list, if there is room         nodeIdx = emptyIdx;         neighbList[nodeIdx].state = 1;         neighbList[nodeIdx].nodeId = packet->fromAddr;         neighbList[nodeIdx].schedId = 0;         neighbList[nodeIdx].active = 1;         neighbList[nodeIdx].txSeqNo = 0;         neighbList[nodeIdx].rxSeqNo = SMAC_MAX_UCAST_SEQ_NO;         numNeighb++;  // increment number of neighbors         if (numNeighb == 1) { // start timer to update neighbor list            dataActiveTime = DATA_ACTIVE_PERIOD;         }         signal LinkState.nodeJoin(packet->fromAddr);         knownNeighb = TRUE;      }#endif            if (packet->toAddr == TOS_BCAST_ADDR) {  // broadcast packet         uartDebug_txByte(RX_BCAST_DONE);#ifdef SMAC_NO_SLEEP_CYCLE         if (state == BACKOFF) state = IDLE;         uartDebug_txByte(state);         if (state == IDLE) {                     if (txRequest == 1) {               uartDebug_txByte(SMAC_TX_REQUEST_IS_1);               tryToSend();            } else {               uartDebug_txByte(SMAC_TX_REQUEST_IS_0);            }         }#else         sleep(TRY);#endif         if (knownNeighb) {            signal LinkState.rxBcastPkt(packet->fromAddr, packet->seqFragNo);         }         tmp = signal MACComm.rxMsgDone(packet);         return tmp;      } else if (packet->toAddr == TOS_LOCAL_ADDRESS) {  // unicast packet         // could receive data in idle, backoff and wait_data state         uartDebug_txByte(RX_UCAST_DONE);         if (state == WAIT_DATA && packet->fromAddr == recvAddr) {            // Should track neighbors' NAV, in case tx extended            TRACK_NAV(packet->duration);            // schedule sending ACK            state = TX_PKT;            howToSend = SEND_ACK;            txDelay = SIFS;            // check neighbor list            fragNo = packet->seqFragNo & 0x7;  // lower 3 bits            if (!knownNeighb) {  // unknow neighbor               // just pass data up               if (lastRxFrag != fragNo) {  // new fragment                  lastRxFrag = fragNo;                  tmp = signal MACComm.rxMsgDone(packet);                  return tmp;               }            } else {  // a know neighbor               // update link quality and check duplicate               seqNo = packet->seqFragNo >> 3;  // higher 5 bits               numTxFragNew = (packet->type & 0xf) + 1;  // reTx + original Tx               if (neighbList[nodeIdx].rxSeqNo != seqNo) {  // new msg                  neighbList[nodeIdx].rxSeqNo = seqNo;                  lastRxFrag = fragNo;                  numTxFragOld = numTxFragNew;                  numTx1Msg = numTxFragNew;                  numRx1Msg = 1; // first fragment received                  if (lastRxFrag == rxFragAll - 1) { // only 1 frag in this msg                     signal LinkState.rxUcastPkt(recvAddr, seqNo, numTx1Msg,                                                 numRx1Msg);                  }                  tmp = signal MACComm.rxMsgDone(packet);                  return tmp;               } else {  // the same msg                  numTx1Msg += numTxFragNew;                  numRx1Msg++;                  if (lastRxFrag != fragNo) {  // new fragment                     lastRxFrag = fragNo;                     if (lastRxFrag == rxFragAll - 1) { // all frags received                        signal LinkState.rxUcastPkt(recvAddr, seqNo, numTx1Msg,                                                 numRx1Msg);                     }                     tmp = signal MACComm.rxMsgDone(packet);                     return tmp;                  } else {  // duplicated fragment                     numTx1Msg -= numTxFragOld;                     if (lastRxFrag == rxFragAll - 1) { // last fragment                        signal LinkState.rxUcastPkt(recvAddr, seqNo, numTx1Msg,                                                   numRx1Msg);                     }                  }                  numTxFragOld = numTxFragNew;               }            }         } else {            handleErrPkt();         }      } else { // unicast packet destined to another node         if (state == IDLE || state == BACKOFF) {            UPDATE_NAV(packet->duration);            sleep(FORCE); // avoid overhearing other's packet            if (nav == 0) nav = 1;  // in case duration is 0 by mistake         }      }      return pkt;   }   void handleACK(void* pkt)   {      // internal handler for ACK packet      MACCtrlPkt* packet;      packet = (MACCtrlPkt*)pkt;      if (packet->toAddr == TOS_LOCAL_ADDRESS) {         if (state == WAIT_ACK && packet->fromAddr == sendAddr) {            // cancel ACK timer            geneTime = 0;            txFragCount++;  // number of successfully transmitted frags            if (txFragCount < txFragAll) {               state = TX_NEXT_FRAG;               uartDebug_txByte(state);               if (signal MACComm.txFragDone(dataPkt) == FAIL)                  txMsgDone();            } else { // no more fragment, tx done               txMsgDone();            }         } else {            handleErrPkt();         }      } else { // packet destined to another node         if (state == IDLE || state == BACKOFF) {            UPDATE_NAV(packet->duration);            sleep(FORCE);            if (nav == 0) nav = 1;         }      }   }   void handleSYNC(void* pkt)   {      // internal handler for SYNC packet      MACSyncPkt* packet = (MACSyncPkt*)pkt;      uint8_t i, nodeId, emptyId, schedId;      uint16_t refTime, rxDelay;      char timeDiff;            // if carrier sense failed and received a sync pkt, go back to idle      if (state == BACKOFF) {         state = IDLE;         uartDebug_txByte(state);      }            // calculate Rx delay of sync packet      // adjust TX_TRANSITION_TIME to make rxDelay calculated correctly      rxDelay = (uint16_t)(clockTime - ((PhyPktBuf*)pkt)->info.timeCoarse) +                PRE_PKT_BYTES * 8 / BANDWIDTH + TX_TRANSITION_TIME;      //uartDebug_txByte1(rxDelay);      // sanity check      if (rxDelay < durSyncPkt - 2 || rxDelay > durSyncPkt + 10)         return;      refTime = packet->sleepTime - rxDelay;#ifdef SMAC_DEBUG      // output syncDiff1 in every data packet      syncDiff1 = schedTab[0].counter - refTime;      //uartDebug_txByte1(syncDiff1);#endif      if (numNeighb == 0) {  // I have no neighbor now         setMySched(packet, refTime);  // follow this schedule         signal LinkState.nodeJoin(packet->fromAddr);         signal LinkState.rxSyncPkt(packet->fromAddr, packet->seqNo);#ifdef SMAC_SLAVE_SCHED         timeToTxSync = 1; // will send SYNC and enter low duty cycles#endif         return;      }      // check if sender is on my neighbor list      if (getNodeIdx(packet->fromAddr, &nodeId, &emptyId)) { //a known neighbor         schedId = neighbList[nodeId].schedId;         if (neighbList[nodeId].state == packet->state) {            // update the existing schedule            schedTab[schedId].counter = refTime; //packet->sleepTime;            neighbList[nodeId].active = 1;            signal LinkState.rxSyncPkt(packet->fromAddr, packet->seqNo);            return;         } else {  // the node just changed schedule            if (schedTab[schedId].numNodes == 1 && txRequest == 1)               // set flag to decrement numNodes after tx pkt is done               schedTab[schedId].chkSched = 1;            else    	           // decrement number of nodes on old schedule               schedTab[schedId].numNodes--;         }      } else {  // a new neighbor         // if neighbor list is full, drop the node         if (emptyId == SMAC_MAX_NUM_NEIGHB) return;      }      // now it's either a new node or an old node switching to a new schedule      // check if its schedule is a known one to me      schedId = SMAC_MAX_NUM_SCHED;      for (i = 0; i < SMAC_MAX_NUM_SCHED; i++) {         if (schedTab[i].numNodes > 0) {            timeDiff = schedTab[i].counter - refTime;            if (timeDiff > -GUARDTIME && timeDiff < GUARDTIME) {               schedTab[i].counter = refTime; // packet->sleepTime;               schedTab[i].numNodes++; // it will follow this schedule               schedId = i;               break;#ifdef SMAC_DEBUG            } else {               syncDiff2 = timeDiff;       //bigger GUARDTIME only#endif            }         }      }      if (schedId == SMAC_MAX_NUM_SCHED) {  // unknow schedule         // add an entry to the schedule table         if (numSched < SMAC_MAX_NUM_SCHED){            for (i = 0; i < SMAC_MAX_NUM_SCHED; i++) {              if (schedTab[i].numNodes == 0) { // found an empty entry                 schedTab[i].counter = refTime; //packet->sleepTime;                 schedTab[i].txSync = 1;  // need send sync                 schedTab[i].txData = 0;                 schedTab[i].numNodes = 1; // 1st node following this sched                 schedId = i;                 numSched++;  // increment number of schedules                 break;              }            }         }        }            if (nodeId == SMAC_MAX_NUM_NEIGHB) {  // a new node         // if no room in schedule table for a new schedule, drop the new node         if (schedId == SMAC_MAX_NUM_SCHED) return;         // add it to my neighbor list -- we know there's still room         neighbList[emptyId].state = packet->state;         neighbList[emptyId].nodeId = packet->fromAddr;         neighbList[emptyId].schedId = schedId;         neighbList[emptyId].active = 1;         neighbList[emptyId].txSeqNo = 0;         neighbList[emptyId].rxSeqNo = SMAC_MAX_UCAST_SEQ_NO;         numNeighb++;  // increment number of neighbors         signal LinkState.nodeJoin(packet->fromAddr);      } else {  // old node switches to a new schedule         // if no room in schedule table, delete the old node         if (schedId == SMAC_MAX_NUM_SCHED) {             neighbList[nodeId].state = 0;            numNeighb--;  // decrement number of neighbors         } else {            neighbList[nodeId].state = packet->state;            neighbList[nodeId].schedId = schedId;            neighbList[nodeId].active = 1;         }         // maybe the old node switches from schedTab[0]         // check if I am the only one on schedTab[0] now         // if yes, I should follow the next available schedule         if (txRequest == 0) {            checkMySched();         } else {            // set flag to call checkMySched() when txRequest becomes 0            schedTab[0].chkSched = 1;         }      }      //uartDebug_txByte(numNeighb);      signal LinkState.rxSyncPkt(packet->fromAddr, packet->seqNo);   }   void sendRTS()   {      // construct and send RTS packet      ctrlPkt.type = (RTS_PKT << 4) + txFragAll;      ctrlPkt.toAddr = sendAddr;      // reserve time for CTS + all fragments + all ACKs      ctrlPkt.duration = (txFragAll + 1) * durCtrlPkt +                txFragAll * durDataPkt +                (txFragAll + txFragAll + 1) * (PROC_DELAY + SIFS);      // send RTS      call PhyComm.txPkt(&ctrlPkt, sizeof(ctrlPkt));      radioState = RADIO_TX;      state = TX_PKT;      geneTime = TX_PKT_DONE_TIME;      uartDebug_txByte(state);   }   void sendCTS()   {      // construct and send CTS      // input duration is the duration field from received RTS pkt      ctrlPkt.type = CTS_PKT << 4;      ctrlPkt.toAddr = recvAddr;      // should track neighbors' NAV as soon as RTS is received      ctrlPkt.duration = neighbNav - durCtrlPkt;      // send CTS      call PhyComm.txPkt(&ctrlPkt, sizeof(ctrlPkt));      geneTime = TX_PKT_DONE_TIME;      radioState = RADIO_TX;      uartDebug_txByte(state);   }   void sendDATA()   {      // send a unicast data packet      // assume all MAC header fields have been filled except the duration#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      // neighbNav tracks the time I have left for tx      dataPkt->duration = neighbNav - durDataPkt;            call PhyComm.txPkt(dataPkt, txPktLen);      radioState = RADIO_TX;      geneTime = TX_PKT_DONE_TIME;      uartDebug_txByte(state);   }   void sendACK()   {      // construct and send ACK      ctrlPkt.type = ACK_PKT << 4;      ctrlPkt.toAddr = recvAddr;      // stick to neighbNav -- should update it when rx data packet      ctrlPkt.duration = neighbNav - durCtrlPkt;      call PhyComm.txPkt(&ctrlPkt, sizeof(ctrlPkt));      radioState = RADIO_TX;      geneTime = TX_PKT_DONE_TIME;   }   void sendSYNC()   {      // construct and send SYNC packet      syncPkt.sleepTime = schedTab[0].counter;      syncPkt.seqNo = syncSeqNo;      call PhyComm.txPkt(&syncPkt, sizeof(syncPkt));      radioState = RADIO_TX;      state = TX_PKT;      geneTime = TX_PKT_DONE_TIME;      uartDebug_txByte(state);   }   // default internal time stamp.   // To use external time stamp, provide wiring at application   default command void TimeStamp.getTime32(uint32_t *timePtr)   {	  *timePtr = clockTime;   }   // default command to if PowerManagement is not used   default async command uint8_t PowerManagement.adjustPower()   {      return 1;   }   // default do-nothing handler for LinkState interface   default event void LinkState.nodeJoin(uint16_t nodeAddr) { }   default event void LinkState.nodeGone(uint16_t nodeAddr) { }   default event void LinkState.rxSyncPk

⌨️ 快捷键说明

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