?? smac.cc
字號:
#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_PAPER
void 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_--;
}
}
}
}
// 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;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -