📄 smac.cc
字号:
// now it's either a new node or an old node switching to a new schedule // it is also possible that a node switches to an existing schedule // check if its schedule is a known one to me schedId = SMAC_MAX_NUM_SCHEDULES; for (i = 0; i < SMAC_MAX_NUM_SCHEDULES; i++) { if (schedTab_[i].numNodes > 0) { double t = mhCounter_[i]->timeToSleep(); double st = sf->sleepTime; double timeDiff = st - t; if ( timeDiff > -GUARDTIME && timeDiff < GUARDTIME) { mhCounter_[i]->sched(sf->sleepTime); schedTab_[i].numNodes++; // it will follow this schedule schedId = i; break; } } } if (schedId == SMAC_MAX_NUM_SCHEDULES) { // unknow schedule flag =1; // add an entry to the schedule table if (numSched_ < SMAC_MAX_NUM_SCHEDULES){ for (i = 0; i < SMAC_MAX_NUM_SCHEDULES; i++) { if (schedTab_[i].numNodes == 0) { // found an empty entry // check if I need to switch 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"); if (schedTab_[0].numNodes >= 2) { // need to move old schedule 0 to schedule i mhCounter_[i]->sched(mhCounter_[0]->timeToSleep()); schedTab_[i].syncNode = schedTab_[0].syncNode; schedTab_[i].txSync = schedTab_[0].txSync; // need send sync schedTab_[i].txData = schedTab_[0].txData; schedTab_[i].numPeriods = schedTab_[0].numPeriods; schedTab_[i].numNodes = schedTab_[0].numNodes - 1; // I switch schedule schedTab_[i].chkSched = schedTab_[0].chkSched; numSched_++; // increment number of schedules // 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 = i; } } } // new schedule is schedule 0 now mhCounter_[0]->sched(sf->sleepTime); schedTab_[0].syncNode = sf->syncNode; schedTab_[0].txSync = 1; // need send sync schedTab_[0].txData = 0; schedTab_[0].numPeriods = 0; schedTab_[0].numNodes = 2; // 1st node + I are following this sched schedTab_[0].chkSched = 0; schedId = 0; } else { // fill new schedule in schedule i mhCounter_[i]->sched(sf->sleepTime); schedTab_[i].syncNode = sf->syncNode; schedTab_[i].txSync = 1; // need send sync schedTab_[i].txData = 0; schedTab_[i].numPeriods = 0; schedTab_[i].numNodes = 1; // 1st node following this sched schedTab_[i].chkSched = 0; schedId = i; numSched_++; // increment number of schedules } break; } } } } if (nodeId == SMAC_MAX_NUM_NEIGHBORS) { // a new node // didn't find an empty entry in schedule table, just drop the new node if (schedId == SMAC_MAX_NUM_SCHEDULES) return; // add it to my neighbor list if (numNeighb_ < SMAC_MAX_NUM_NEIGHBORS){ for (i = 0; i < SMAC_MAX_NUM_NEIGHBORS; i++) { if (neighbList_[i].state == 0) { // found an empty entry neighbList_[i].state = sf->state; neighbList_[i].nodeId = sf->srcAddr; neighbList_[i].schedId = schedId; neighbList_[i].active = 1; numNeighb_++; // increment number of neighbors return; } } } // didn't find an empty entry in neighb list, just drop the new node schedTab_[schedId].numNodes--; if (schedTab_[schedId].numNodes == 0) numSched_--; } else if (flag == 1) { // old node switches to a new schedule // didn't find an empty entry in schedule table, delete the old node if (schedId == SMAC_MAX_NUM_SCHEDULES) { neighbList_[nodeId].state = 0; numNeighb_--; // decrement number of neighbors } else { neighbList_[nodeId].state = sf->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; } } else { // old node switches to old schedule neighbList_[nodeId].state = sf->state; neighbList_[nodeId].schedId = schedId; neighbList_[nodeId].active = 1; if (globalSchedule_ == 1 && schedTab_[0].syncNode > sf->syncNode ){ //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"); // change state schedState_++; 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; }}#elsevoid SMAC::handleSYNC(Packet *p) { if ( selfConfigFlag_ == 1) { if(numSched_ == 0) { // in choose_sched state mhGene_.cancel(); //double t = Scheduler::instance().clock(); //struct smac_sync_frame *sf = (struct smac_sync_frame *)p->access(hdr_mac::offset_); //printf("Recvd SYNC (follow) at %d from %d.....at %.6f\n", index_, sf->srcAddr, t); setMySched(p); return; } if (numNeighb_ == 0) { // getting first sync pkt // follow this sched as have no other neighbor //double t = Scheduler::instance().clock(); //struct smac_sync_frame *sf = (struct smac_sync_frame *)p->access(hdr_mac::offset_); //printf("Recvd SYNC (follow) at %d from %d.....at %.6f\n", index_, sf->srcAddr, t); setMySched(p); return; } } state_ = IDLE; // check if sender is on my neighbor list struct smac_sync_frame *sf = (struct smac_sync_frame *)p->access(hdr_mac::offset_); int i, j; int foundNeighb = 0; int schedId = SMAC_MAX_NUM_SCHEDULES; //double t = Scheduler::instance().clock(); //printf("Recvd SYNC (not/f) at %d from %d.....at %.6f\n", index_, sf->srcAddr, t); for(i = 0; i < numNeighb_; i++) { if (neighbList_[i].nodeId == sf->srcAddr) { foundNeighb = 1; schedId = neighbList_[i].schedId; // a known neighbor mhCounter_[schedId]->sched(sf->sleepTime); break; } if (neighbList_[i].nodeId == sf->syncNode) // // found its synchronizer, remember it schedule id schedId = neighbList_[i].schedId; } if (!foundNeighb) { // unknown node, add it onto neighbor list neighbList_[numNeighb_].nodeId = sf->srcAddr; if (schedId < SMAC_MAX_NUM_SCHEDULES) { // found its synchronizer neighbList_[numNeighb_].schedId = schedId; } else if (sf->syncNode == index_) { // this node follows my schedule neighbList_[numNeighb_].schedId = 0; } else { // its synchronizer is unknown // check if its schedule equals to an existing one int foundSched = 0; for (j = 0; j < numSched_; j++) { double t = mhCounter_[j]->timeToSleep(); double st = sf->sleepTime; if (t == st || (t + CLKTICK2SEC(1)) == st || t == (st + CLKTICK2SEC(1))) { neighbList_[numNeighb_].schedId = j; foundSched = 1; break; } } if (!foundSched) { // this is unknown schedule schedTab_[numSched_].txSync = 1; schedTab_[numSched_].txData = 0; schedTab_[numSched_].numPeriods = 0; neighbList_[numNeighb_].schedId = numSched_; mhCounter_[numSched_]->sched(sf->sleepTime); numSched_++; } } numNeighb_++; // increment number of neighbors }}#endifvoid SMAC::rxMsgDone(Packet *p) { // no more fragments // defragment all pkts and send them up // fragmentation/de-frag to be implemented if (p) uptarget_->recv(p, (Handler*)0); if (!syncFlag_) // check if any pkt waiting to get tx'ed checkToSend();#ifdef JOURNAL_PAPER //node tries to go to sleep after receiving the message //we temperarily disable sleep() here, because in the testcases where ARP messages exist, more than one message need to be transmitted in one round else {// if( mhCounter_[0]->value_ == sleepTime_ ) // sleep(); }#endif}#ifdef JOURNAL_PAPERvoid SMAC::rxFragDone(Packet *p) {// more fragments to come}#endif//void SMAC::rxFragDone(Packet *p) {// more fragments to come//}// mac transmission functionsvoid SMAC::transmit(Packet *p) { radioState_ = RADIO_TX; tx_active_ = 1; pktTx_ = p; double transTime = txtime(p); hdr_cmn *ch = hdr_cmn::access(p); ch->txtime() = transTime; downtarget_->recv(p->copy(), this); //Scheduler::instance().schedule(downtarget_, p, 0.000001); mhSend_.sched(txtime(p));}bool SMAC::chkRadio() { // check radiostate if (radioState_ == RADIO_IDLE || radioState_ == RADIO_SLP) return (1); return (0); // phy interface is ready to tx}int SMAC::startBcast(){ // broadcast data directly; don't use RTS/CTS hdr_smac *mh = HDR_SMAC(dataPkt_); mh->duration = 0; if(chkRadio()) { transmit(dataPkt_); return 1; } return 0;}int SMAC::startUcast(){ // start unicast data; send RTS first hdr_smac *mh = HDR_SMAC(dataPkt_); sendAddr_ = mh->dstAddr; numRetry_ = 0; //succFrags_ = 0;#ifdef JOURNAL_PAPER succFrags_ = 0;#endif numExtend_ = 0; if(sendRTS()) { state_ = WAIT_CTS; return 1; } return 0;}void SMAC::txMsgDone() {#ifdef JOURNAL_PAPER // update schedTab and neighbList if flags are set when txRequest_=1 update_schedTab_neighbList(); txRequest_ = 0;#endif if (!syncFlag_) {#ifdef JOURNAL_PAPER txData_ = 0;#endif // check if any data is waiting to get tx'ed if(checkToSend()) return; else if (callback_) { // signal upper layer Handler *h = callback_; callback_ = 0; h->handle((Event*) 0); } } else {#ifdef JOURNAL_PAPER schedTab_[dataSched_].txData = 0;#endif if (callback_) { // signal upper layer Handler *h = callback_; callback_ = 0; h->handle((Event*) 0); }#ifdef JOURNAL_PAPER //node tries to go to sleep after transmission is done (both unicast and broadcast) if( mhCounter_[0]->value_ == sleepTime_ ) sleep();#endif } }// void SMAC::txFragDone() // {// // send next fragment// }#ifdef JOURNAL_PAPERvoid SMAC::txFragDone(){ // send next fragment txNextFrag(&dataPkt_);} bool SMAC::txNextFrag(void* data){ // Send subsequent fragments if (state_ != TX_NEXT_FRAG || data == 0) return 0;// dataPkt = (MACHeader*)data; // fill in MAC header fields except du
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -