📄 smac.cc
字号:
schedTab_[0].numNodes = schedTab_[i].numNodes + 1; // delete this schedule schedTab_[i].numNodes = 0; numSched_--; schedId = i; break; } } if (schedId > 0){ schedState_++; // update my neighbor list which relative to this schedId for (i = 0; i < SMAC_MAX_NUM_NEIGHBORS; i++) { if (neighbList_[i].state > 0 ) if (neighbList_[i].schedId == schedId) neighbList_[i].schedId = 0; } } }}// update_schedTab_neighbList() is executed whenever the transmission is donevoid SMAC::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; }} //update_myNeighbList() is executed whenever the UpdateNeighb timer timesoutvoid SMAC::update_myNeighbList(){ //we should update the schedTab[].numNodes before we call checkMySched() //to ensure the next available schedule is correct check_schedFlag(); update_neighbList(); updateNeighbList_ = 0; schedTab_[0].chkSched = 0; //we already did checkMySched() in update_neighbList() txRequest_ = 0;} void SMAC::update_neighbList(){ // update neighbor list, // if the node is not active (moved away or died) for a certain time, // need to drop it from neighbor list //printf("\nupdate_neighbList:node %d at %.6f \n", index_, Scheduler::instance().clock()); int i, schedId; //dump(); for (i = 0; i < SMAC_MAX_NUM_NEIGHBORS; i++) { if (neighbList_[i].state > 0 ){ if (neighbList_[i].active != 1){ // this node is not active recently //printf("node %d lost a neighbor of node %d: ............at %.6f\n", index_, neighbList_[i].nodeId, Scheduler::instance().clock()); schedId = neighbList_[i].schedId; schedTab_[schedId].numNodes--; if (schedTab_[schedId].numNodes == 0) numSched_--; neighbList_[i].state = 0; numNeighb_--; } else //printf("node %d has a neighbor of node %d: ............at %.6f\n", index_, neighbList_[i].nodeId, Scheduler::instance().clock()); neighbList_[i].active = 0; } } //printf("#####################################################\n"); // maybe the inactive nodes were dropped from schedTab[0] // check if I am the only one on schedTab[0] // if yes, I should follow the next available schedule checkMySched(); mhUpdateNeighb_.resched(SMAC_UPDATE_NEIGHB_PERIOD);}void SMAC::check_schedFlag(){ int i; // decrease the numNodes in the old schedule first for (i = 1; i < SMAC_MAX_NUM_SCHEDULES; i++) { if (schedTab_[i].numNodes > 0 && schedTab_[i].chkSched == 1){ schedTab_[i].chkSched = 0; schedTab_[i].numNodes--; if (schedTab_[i].numNodes == 0) numSched_--; } }}#endifvoid SMAC::handleRTS(Packet *p) { // internal handler for RTS struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_); if(cf->dstAddr == index_) { if((state_ == IDLE || state_ == CR_SENSE) && nav_ == 0) { recvAddr_ = cf->srcAddr; // remember sender's addr#ifdef JOURNAL_PAPER updateNeighNav(cf->duration);#endif if(sendCTS(cf->duration)) { state_ = WAIT_DATA; lastRxFrag_ = -3; //reset frag no } } } else { // pkt destined to another node // don't go to sleep unless hear first data fragment // so I know how long to sleep if (state_ == CR_SENSE) state_ = IDLE;#ifdef JOURNAL_PAPER updateNav(cf->duration); state_ = DATA_SENSE1; mhGene_.sched(timeWaitCtrl_);#else updateNav(durCtrlPkt_ + durDataPkt_);#endif }}void SMAC::handleCTS(Packet *p) { // internal handler for CTS struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_); if(cf->dstAddr == index_) { // for me if(state_ == WAIT_CTS && cf->srcAddr == sendAddr_) { // cancel CTS timer mhGene_.cancel(); if(sendDATA()) { state_ = WAIT_ACK;#ifndef JOURNAL_PAPER if (!syncFlag_) txData_ = 0; else schedTab_[currSched_].txData = 0;#endif } } } else { // for others updateNav(cf->duration);#ifdef JOURNAL_PAPER if(state_ == DATA_SENSE1 || state_ == DATA_SENSE2) { mhGene_.cancel();} if(state_ == IDLE || state_ == CR_SENSE || state_ == DATA_SENSE1 || state_ == DATA_SENSE2) sleep();#else if(state_ == IDLE || state_ == CR_SENSE) sleep();#endif }}void SMAC::handleDATA(Packet *p) { // internal handler for DATA packet struct hdr_cmn *ch = HDR_CMN(p); struct hdr_smac * sh = HDR_SMAC(p); if((u_int32_t)sh->dstAddr == MAC_BROADCAST) { // brdcast pkt state_ = IDLE; // hand pkt over to higher layer rxMsgDone(p); } else if (sh->dstAddr == index_) { // unicast pkt if(state_ == WAIT_DATA && sh->srcAddr == recvAddr_) { // Should track neighbors' NAV, in case tx extended updateNeighNav(sh->duration); sendACK(sh->duration);#ifdef JOURNAL_PAPER if (sh->duration > durCtrlPkt_) { // wait for more frag rxFragDone(p); //no frag for now state_ = WAIT_DATA; } else { // no more fragments state_ = IDLE; rxMsgDone(p); }#else //if (sh->duration > durCtrlPkt_) { // wait for more frag //rxFragDone(p); no frag for now //state_ = IDLE; //} else { // no more fragments state_ = IDLE; if(lastRxFrag_ != ch->uid()) { lastRxFrag_ = ch->uid(); rxMsgDone(p); } else { printf("Recd duplicate data pkt at %d from %d! free pkt\n",index_,sh->srcAddr); Packet::free(p); if (!syncFlag_) checkToSend(); }#endif } else if (state_ == IDLE || state_ == CR_SENSE ) { printf("got data pkt in %d state XXX %d\n", state_, index_); //updateNav(sh->duration + 0.00001); // incase I have a pkt to send sendACK(sh->duration); state_ = IDLE; if(lastRxFrag_ != ch->uid()) { lastRxFrag_ = ch->uid(); rxMsgDone(p); } else { printf("Recd duplicate data pkt! free pkt\n"); Packet::free(p); if (!syncFlag_) checkToSend(); } } else { // some other state // not sure we can handle this // so drop pkt printf("Got data pkt in !WAIT_DATA/!CR_SENSE/!IDLE state(%d) XXX %d\n", state_, index_); printf("Dropping data pkt\n"); Packet::free(p); } } else { // unicast pkt destined to other node updateNav(sh->duration); Packet::free(p);#ifdef JOURNAL_PAPER if (state_ == DATA_SENSE2) { mhGene_.cancel();} if (state_ == IDLE || state_ == CR_SENSE || state_ == DATA_SENSE2) sleep();#else if (state_ == IDLE || state_ == CR_SENSE) sleep();#endif }}void SMAC::handleACK(Packet *p) { // internal handler for ack struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_); if (cf->dstAddr == index_) { if (state_ == WAIT_ACK && cf->srcAddr == sendAddr_) { // cancel ACK timer mhGene_.cancel();#ifdef JOURNAL_PAPER numFrags_--; succFrags_++; if (numFrags_ > 0) { //need to send more frags state_ = TX_NEXT_FRAG; txFragDone(); } else { state_ = IDLE; txMsgDone(); }#else Packet::free(dataPkt_); dataPkt_ = 0; //numFrags_--; //succFrags_++; // if (numFrags_ > 0) { //need to send more frags // if (neighNav__ < (durDataPkt_ + durCtrlPkt_)) { // // used up reserved time, have to stop // state_ = IDLE; // // txMsgFailed(succFrags_); // txMsgDone(); // } else { // continue on next fragment // state_ = WAIT_NEXTFRAG; // txFragDone(dataPkt_); // } // } else { state_ = IDLE; txMsgDone(); //}#endif } } else { // destined to another node if (cf->duration > 0) { updateNav(cf->duration); if (state_ == IDLE || state_ == CR_SENSE) sleep(); } }}#ifdef JOURNAL_PAPERvoid SMAC::handleSYNC(Packet *p) { struct smac_sync_frame *sf = (struct smac_sync_frame *)p->access(hdr_mac::offset_); int i, j,nodeId, schedId, flag; struct SchedTable tempSched; int foundNeighb = 0; if (index_ == 5){ double t = Scheduler::instance().clock(); //printf("Recvd SYNC (not/f) at %d from %d.....at %.6f\n", index_, sf->srcAddr, t); } if (numSched_ == 0) { // in choose_sched state mhGene_.cancel(); setMySched(p); return; } if (numNeighb_ == 0 && globalSchedule_ == 1) { // follow this schedule if having no other neighbor and if this schedule has smaller ID if (schedTab_[0].syncNode > sf->syncNode || !sendSYNCFlag_ ) { setMySched(p); return; } } else if (numNeighb_ == 0) { // getting first sync pkt // follow this sched as have no other neighbor setMySched(p); return; } state_ = IDLE; // check if sender is on my neighbor list nodeId = SMAC_MAX_NUM_NEIGHBORS; schedId = SMAC_MAX_NUM_SCHEDULES; for (i = 0; i < SMAC_MAX_NUM_NEIGHBORS; i++) { if (neighbList_[i].state > 0 && neighbList_[i].nodeId == sf->srcAddr) { nodeId = i; schedId = neighbList_[i].schedId; // a known neighbor break; } } if (nodeId < SMAC_MAX_NUM_NEIGHBORS) { if (neighbList_[nodeId].state == sf->state) { // update the existing schedule mhCounter_[schedId]->sched(sf->sleepTime); neighbList_[nodeId].active = 1; if (globalSchedule_ == 1 && schedTab_[0].syncNode > sf->syncNode ){ // change state schedState_++; //printf("#############################################################\n"); //printf("node %d hears SYNC from node %d and changes schedule from %d to schedule %d : ............at %.6f\n", index_, sf->srcAddr, schedTab_[0].syncNode, sf->syncNode, Scheduler::instance().clock()); //printf("#############################################################\n"); tempSched.syncNode = schedTab_[schedId].syncNode; tempSched.txSync = schedTab_[schedId].txSync; // need send sync tempSched.txData = schedTab_[schedId].txData; tempSched.numPeriods = schedTab_[schedId].numPeriods; tempSched.numNodes = schedTab_[schedId].numNodes ; // tempSched.chkSched = schedTab_[schedId].chkSched; if (schedTab_[0].numNodes == 1) { numSched_--; } mhCounter_[schedId]->sched(mhCounter_[0]->timeToSleep()); schedTab_[schedId].syncNode = schedTab_[0].syncNode; schedTab_[schedId].txSync = schedTab_[0].txSync; // need send sync schedTab_[schedId].txData = schedTab_[0].txData; schedTab_[schedId].numPeriods = schedTab_[0].numPeriods; schedTab_[schedId].numNodes = schedTab_[0].numNodes - 1; // I switch schedule schedTab_[schedId].chkSched = schedTab_[0].chkSched; // new schedule is schedule 0 now mhCounter_[0]->sched(sf->sleepTime); schedTab_[0].syncNode = sf->syncNode; schedTab_[0].txSync = 1; schedTab_[0].txData = tempSched.txData; schedTab_[0].numPeriods = 0; schedTab_[0].numNodes = tempSched.numNodes + 1; // I are following this sched schedTab_[0].chkSched = tempSched.chkSched; // change all the neighbor who was following shedule 0 for (j = 0; j < SMAC_MAX_NUM_NEIGHBORS; j++) { if (neighbList_[j].schedId == 0) { // found an empty entry neighbList_[j].schedId = schedId; } else if (neighbList_[j].schedId == schedId) { // found an empty entry neighbList_[j].schedId = 0; } } } return; } else { // decrement number of nodes on old schedule if (schedTab_[schedId].numNodes ==1 && txRequest_ == 1) { //set flag to decrement numNodes after tx pkt is done schedTab_[schedId].chkSched = 1; } else { schedTab_[schedId].numNodes--; if (schedTab_[schedId].numNodes == 0){ numSched_--; } } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -