?? smac.cc
字號:
}
// cancel carrier sense timer and wait for entire pkt
if (state_ == CR_SENSE) {
//printf("Cancelling CS- node %d\n", index_);
// cancels only if timer is pending; smac could be in CR_SENSE with timer cancelled
// incase it has already received a pkt and receiving again
mhCS_.checkToCancel();
}
// if the interface is already in process of recv'ing pkt
if (radioState_ == RADIO_RX) {
assert(pktRx_);
assert(mhRecv_.busy());
// if power of the incoming pkt is smaller than the power
// of the pkt currently being recvd by atleast the capture
// threshold then we ignore the new pkt.
if (pktRx_->txinfo_.RxPr / p->txinfo_.RxPr >= p->txinfo_.CPThresh)
capture(p);
else
collision(p);
}
else {
if (mhRecv_.busy()) { // and radiostate != RADIO_RX
assert(radioState_ == RADIO_SLP);
// The radio interface was recv'ing a pkt when it went to sleep
// should it postpone sleep till it finishes recving the pkt???
mhRecv_.resched(txtime(p));
} else
mhRecv_.sched(txtime(p));
radioState_ = RADIO_RX;
pktRx_ = p;
}
}
void SMAC::capture(Packet *p) {
// we update NAV for this pkt txtime
updateNav(CLKTICK2SEC(eifs_) + txtime(p));
Packet::free(p);
}
void SMAC::collision(Packet *p) {
if (!mac_collision_)
mac_collision_ = 1;
// since a collision has occured figure out which packet that caused
// the collision will "last" longer. Make this pkt pktRx_ and reset the
// recv timer.
if (txtime(p) > mhRecv_.timeToExpire()) {
mhRecv_.resched(txtime(p));
discard(pktRx_, DROP_MAC_COLLISION);
// shouldn't we free pkt here ???
pktRx_ = p;
}
else
discard(p, DROP_MAC_COLLISION);
// shouldn't we free pkt here ???
}
void SMAC::discard(Packet *p, const char* why)
{
hdr_cmn *ch = HDR_CMN(p);
hdr_smac *sh = HDR_SMAC(p);
/* if the rcvd pkt contains errors, a real MAC layer couldn't
necessarily read any data from it, so we just toss it now */
if(ch->error() != 0) {
Packet::free(p);
//p = 0;
return;
}
switch(sh->type) {
case RTS_PKT:
if (drop_RTS(p, why))
return;
break;
case CTS_PKT:
case ACK_PKT:
if (drop_CTS(p, why))
return;
break;
case DATA_PKT:
if (drop_DATA(p, why))
return;
break;
case SYNC_PKT:
if(drop_SYNC(p, why))
return;
break;
default:
fprintf(stderr, "invalid MAC type (%x)\n", sh->type);
//trace_pkt(p);
exit(1);
}
Packet::free(p);
}
int SMAC::drop_RTS(Packet *p, const char* why)
{
struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
if (cf->srcAddr == index_) {
drop(p, why);
return 1;
}
return 0;
}
int SMAC::drop_CTS(Packet *p, const char* why)
{
struct smac_control_frame *cf = (smac_control_frame *)p->access(hdr_mac::offset_);
if (cf->dstAddr == index_) {
drop(p, why);
return 1;
}
return 0;
}
int SMAC::drop_DATA(Packet *p, const char* why)
{
hdr_smac *sh = HDR_SMAC(p);
if ( (sh->dstAddr == index_) ||
(sh->srcAddr == index_) ||
((u_int32_t)sh->dstAddr == MAC_BROADCAST)) {
drop(p, why);
return 1;
}
return 0;
}
int SMAC::drop_SYNC(Packet *p, const char* why)
{
drop(p, why);
return 1;
}
#ifdef JOURNAL_PAPER
void SMAC::checkMySched()
{
// check if I am the only one on schedTab[0]
// if yes, should switch and follow the next available schedule
// happens when an old node switches to a new schedule
// and when I drop some inactive nodes from neighbor list(updating)
int i, schedId;
schedId = 0;
if (schedTab_[0].numNodes == 1 && numSched_ > 1 && numNeighb_ > 0) {
for (i = 1; i < SMAC_MAX_NUM_SCHEDULES; i++) {
if (schedTab_[i].numNodes > 0) { // switch to next available schedule
//schedTab_[0].counter = schedTab[i].counter;
schedTab_[0].numPeriods = 0;
schedTab_[0].txSync = 1;
schedTab_[0].txData = schedTab_[i].txData;
schedTab_[0].syncNode = schedTab_[i].syncNode;
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 done
void 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 timesout
void 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_--;
}
}
}
#endif
void 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 JORNAL_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);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -