?? smac.cc
字號:
//node tries to go to sleep if it needs to resend
if( mhCounter_[0]->value_ == sleepTime_ )
sleep();
#endif
if (!syncFlag_)
checkToSend();
} else {
state_ = IDLE;
Packet::free(dataPkt_);
dataPkt_ = 0;
numRetry_ = 0;
//numFrags_ = 0;
// signal upper layer about failure of tx
// txMsgFailed();
txMsgDone();
}
} else if (state_ == WAIT_ACK) { // ack timeout
if (numExtend_ < SMAC_EXTEND_LIMIT) { // extend time
printf("SMAC %d: no ACK received. Extend Tx time.\n", index_);
numExtend_++;
updateNeighNav(durDataPkt_ + durCtrlPkt_);
//neighNav_ = (durDataPkt_ + durCtrlPkt_);
} else { // reached extension limit, can't extend time
//numFrags_--;
}
if (neighNav_ < (durDataPkt_ + durCtrlPkt_)) {
// used up reserved time, stop tx
discard(dataPkt_, DROP_MAC_RETRY_COUNT_EXCEEDED);
dataPkt_ = 0;
pktTx_ = 0;
state_ = IDLE;
// signal upper layer the number of transmitted frags
//txMsgFailed(succFrags); -> no frag for now
txMsgDone();
} else { // still have time
// keep sending until use up remaining time
sendDATA();
}
#ifdef JOURNAL_PAPER
} else if (state_ == DATA_SENSE1) {
state_ = DATA_SENSE2;
mhGene_.resched(timeWaitCtrl_);
} else if (state_ == DATA_SENSE2) {
state_ = IDLE;
//node tries to go to sleep if it does not hear CTS or DATA for others' connection
if( mhCounter_[0]->value_ == sleepTime_ )
sleep();
#endif
}
}
void SMAC::handleNavTimer() {
// medium is now free
nav_ = 0; // why have this variable?? probably not required use the timer instead
if (!syncFlag_) {
if (state_ == SLEEP)
wakeup();
// try to send waiting data, if any
checkToSend();
}
#ifdef JOURNAL_PAPER
adaptiveListen();
#endif
}
int SMAC::checkToSend() {
#ifdef JOURNAL_PAPER
if (txRequest_ == 1 || syncFlag_) {
#else
if (txData_ == 1) {
#endif
assert(dataPkt_);
struct hdr_smac *mh = HDR_SMAC(dataPkt_);
if (radioState_ != RADIO_SLP && radioState_ != RADIO_IDLE)
goto done; // cannot send if radio is sending or recving
if (state_ != SLEEP && state_ != IDLE && state_ != WAIT_DATA )
goto done; // cannot send if not in any of these states
if (!(mhNav_.busy()) && !(mhNeighNav_.busy()) &&
(state_ == SLEEP || state_ == IDLE)) {
if (state_ == SLEEP) wakeup();
if ((u_int32_t)mh->dstAddr == MAC_BROADCAST)
howToSend_ = BCASTDATA;
else
howToSend_ = UNICAST;
state_ = CR_SENSE;
#ifdef JOURNAL_PAPER
adapSend_ = 0;
//printf("adaptiveListen sendData: node %d scheduletime: %f time:%.9f \n", index_, mhCounter_[0]->value_, Scheduler::instance().clock());
#endif
// start cstimer
double cw = (Random::random() % DATA_CW) * slotTime_sec_;
mhCS_.sched(CLKTICK2SEC(difs_) + cw);
return 1;
} else {
return 0;
}
done:
return 0;
} else {
return 0;
}
}
void SMAC::handleNeighNavTimer() {
// Timer to track my neighbor's NAV
neighNav_ = 0; // probably don't need to use this variable
if (state_ == WAIT_DATA) { // data timeout
state_ = IDLE;
// signal upper layer that rx msg is done
// didnot get any/all data
rxMsgDone(0);
} else {
if (!syncFlag_)
checkToSend();
}
#ifdef JOURNAL_PAPER
adaptiveListen();
#endif
}
void SMAC::handleCsTimer() {
// carrier sense successful
#ifdef MAC_DEBUG
if (howToSend_ != BCASTSYNC && dataPkt_ == 0)
numCSError++;
#endif // MAC_DEBUG
switch(howToSend_) {
case BCASTSYNC:
if (sendSYNC())
state_ = IDLE;
break;
case BCASTDATA:
startBcast();
break;
case UNICAST:
startUcast();
break;
}
}
void SMAC::handleCounterTimer(int id) {
//printf("MAC:%d,id:%d - time:%.9f\n", index_,id,Scheduler::instance().clock());
#ifdef JOURNAL_PAPER
if (schedTab_[id].numNodes > 0) {
#endif
if (mhCounter_[id]->value_ == sleepTime_) { //woken up from sleep
// listentime starts now
if (radioState_ != RADIO_SLP && radioState_ != RADIO_IDLE)
goto sched_1; // cannot send if radio is sending or recving
if (state_ != SLEEP && state_ != IDLE && state_ != WAIT_DATA )
goto sched_1;; // cannot send if not in any of these states
if (!(mhNav_.busy()) && !(mhNeighNav_.busy()) &&
(state_ == SLEEP || state_ == IDLE)) {
if (state_ == SLEEP &&
(id == 0 || schedTab_[id].txSync == 1)) {
wakeup();
}
if (schedTab_[id].txSync == 1) {
// start carrier sense for sending sync
howToSend_ = BCASTSYNC;
#ifdef JOURNAL_PAPER
syncSched_ = id;
#else
currSched_ = id;
#endif
state_ = CR_SENSE;
double cw = (Random::random() % SYNC_CW) * slotTime_sec_;
mhCS_.sched(CLKTICK2SEC(difs_) + cw);
}
}
// start to listen now
sched_1:
mhCounter_[id]->sched(CLKTICK2SEC(listenTime_));
} else if (mhCounter_[id]->value_ == syncTime_) { //synctime over
// can start datatime now
if (radioState_ != RADIO_SLP && radioState_ != RADIO_IDLE)
goto sched_2; // cannot send if radio is sending or recving
if (state_ != SLEEP && state_ != IDLE && state_ != WAIT_DATA )
goto sched_2; // cannot send if not in any of these states
if (schedTab_[id].txData == 1 &&
(!(mhNav_.busy()) && !(mhNeighNav_.busy())) &&
(state_ == SLEEP || state_ == IDLE)) {
// schedule sending data
if (state_ == SLEEP)
wakeup();
struct hdr_smac *mh = (struct hdr_smac *)dataPkt_->access(hdr_mac::offset_);
if ((u_int32_t)mh->dstAddr == MAC_BROADCAST)
howToSend_ = BCASTDATA;
else
howToSend_ = UNICAST;
#ifdef JOURNAL_PAPER
dataSched_ = id;
#else
currSched_ = id;
#endif
state_ = CR_SENSE;
// start cstimer
double cw = (Random::random() % DATA_CW) * slotTime_sec_;
mhCS_.sched(CLKTICK2SEC(difs_) + cw);
}
sched_2:
mhCounter_[id]->sched(CLKTICK2SEC(dataTime_));
} else if (mhCounter_[id]->value_ == dataTime_) { //datatime over
// check if in the middle of recving a pkt
if (radioState_ == RADIO_RX)
goto sched_3;
#ifdef JOURNAL_PAPER
if (id == 0 && state_ == IDLE && searchNeighb_ ==0 && adaptiveListen_ ==0 )
#else
if (id == 0 && state_ == IDLE && searchNeighb_ ==0 )
#endif
sleep();
sched_3:
// now time to go to sleep
mhCounter_[id]->sched(CLKTICK2SEC(cycleTime_));
// check if ready to send out sync
if (schedTab_[id].numPeriods > 0) {
schedTab_[id].numPeriods--;
if (schedTab_[id].numPeriods == 0) {
schedTab_[id].txSync = 1;
// neighbor discovery
if ( id == 0 ) {
numSync_--;
// printf("numSync_ %d: ............node %d at %.6f\n", numSync_, index_,Scheduler::instance().clock());
if ( numSync_ == 1 ) {
searchNeighb_ = 1; // node will go to neighbor discovery period starting from the next frame
//printf("Start Neighbor Discovery: ............node %d at %.6f\n", index_, Scheduler::instance().clock());
}
else if ( numSync_ == 0 ) {
searchNeighb_ = 0; // neighbor discovery period lasts exactly one SYNC period
//printf("Ending Neighbor Discovery: ............node %d at %.6f\n", index_, Scheduler::instance().clock());
if ( numNeighb_ == 0 ) {
numSync_ = SRCH_CYCLES_SHORT;
}
else {
numSync_ = SRCH_CYCLES_LONG;
}
}
}
}
}
}
#ifdef JOURNAL_PAPER
}
#endif
}
#ifdef JOURNAL_PAPER
void SMAC::handleUpdateNeighbTimer() {
//printf("SMAC::handleUpdateNeighbTimer: ............node %d at %.6f\n", index_, Scheduler::instance().clock());
if (txRequest_ == 0) { // No data waiting to be transmitted
txRequest_ = 1; // temporarily disable tx when updating
update_myNeighbList();
} else {
updateNeighbList_ = 1; // set flag to update when tx done
}
}
void SMAC::handleAdaptiveListenTimer() {
//node tries to go to sleep after adaptive listen times out
adaptiveListen_ = 0;
if (state_ == IDLE && state_ != TX_PKT && mhCounter_[0]->value_ == sleepTime_)
sleep();
}
#endif
// recv function for mac layer
void SMAC::recv(Packet *p, Handler *h) {
struct hdr_cmn *ch = HDR_CMN(p);
assert(initialized());
// handle outgoing pkt
if ( ch->direction() == hdr_cmn::DOWN) {
sendMsg(p, h);
return;
}
// handle incoming pkt
// we have just recvd the first bit of a pkt on the network interface
// if the interface is in tx mode it probably would not see this pkt
if (radioState_ == RADIO_TX && ch->error() == 0) {
assert(tx_active_);
ch->error() = 1;
pktRx_ = p;
mhRecv_.resched(txtime(p));
return;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -