📄 channel.cc
字号:
// create list of mobilenodes for this channel if (xListHead_ == NULL) { fprintf(stderr, "INITIALIZE THE LIST xListHead\n"); xListHead_ = mn; xListHead_->nextX_ = NULL; xListHead_->prevX_ = NULL; } else { for (tmp = xListHead_; tmp->nextX_ != NULL; tmp=tmp->nextX_); tmp->nextX_ = mn; mn->prevX_ = tmp; mn->nextX_ = NULL; } numNodes_++;}voidWirelessChannel::removeNodeFromList(MobileNode *mn) { MobileNode *tmp; // Find node in list for (tmp = xListHead_; tmp->nextX_ != NULL; tmp=tmp->nextX_) { if (tmp == mn) { if (tmp == xListHead_) { xListHead_ = tmp->nextX_; if (tmp->nextX_ != NULL) tmp->nextX_->prevX_ = NULL; } else if (tmp->nextX_ == NULL) tmp->prevX_->nextX_ = NULL; else { tmp->prevX_->nextX_ = tmp->nextX_; tmp->nextX_->prevX_ = tmp->prevX_; } numNodes_--; return; } } fprintf(stderr, "Channel: node not found in list\n");}voidWirelessChannel::sortLists(void) { bool flag = true; MobileNode *m, *q; sorted_ = true; fprintf(stderr, "SORTING LISTS ..."); /* Buble sort algorithm */ // SORT x-list while(flag) { flag = false; m = xListHead_; while (m != NULL){ if(m->nextX_ != NULL) if ( m->X() > m->nextX_->X() ){ flag = true; //delete_after m; q = m->nextX_; m->nextX_ = q->nextX_; if (q->nextX_ != NULL) q->nextX_->prevX_ = m; //insert_before m; q->nextX_ = m; q->prevX_ = m->prevX_; m->prevX_ = q; if (q->prevX_ != NULL) q->prevX_->nextX_ = q; // adjust Head of List if(m == xListHead_) xListHead_ = m->prevX_; } m = m -> nextX_; } } fprintf(stderr, "DONE!\n");}voidWirelessChannel::updateNodesList(class MobileNode *mn, double oldX) { MobileNode* tmp; double X = mn->X(); bool skipX=false; if(!sorted_) { sortLists(); return; } /* xListHead cannot be NULL here (they are created during creation of mobilenode) */ /*** DELETE ***/ // deleting mn from x-list if(mn->nextX_ != NULL) { if(mn->prevX_ != NULL){ if((mn->nextX_->X() >= X) && (mn->prevX_->X() <= X)) skipX = true; // the node doesn't change its position in the list else{ mn->nextX_->prevX_ = mn->prevX_; mn->prevX_->nextX_ = mn->nextX_; } } else{ if(mn->nextX_->X() >= X) skipX = true; // skip updating the first element else{ mn->nextX_->prevX_ = NULL; xListHead_ = mn->nextX_; } } } else if(mn->prevX_ !=NULL){ if(mn->prevX_->X() <= X) skipX = true; // skip updating the last element else mn->prevX_->nextX_ = NULL; } if ((mn->prevX_ == NULL) && (mn->nextX_ == NULL)) skipX = true; //skip updating if only one element in list /*** INSERT ***/ //inserting mn in x-list if(!skipX){ if(X > oldX){ for(tmp = mn; tmp->nextX_ != NULL && tmp->nextX_->X() < X; tmp = tmp->nextX_); //fprintf(stdout,"Scanning the element addr %d X=%0.f, next addr %d X=%0.f\n", tmp, tmp->X(), tmp->nextX_, tmp->nextX_->X()); if(tmp->nextX_ == NULL) { //fprintf(stdout, "tmp->nextX_ is NULL\n"); tmp->nextX_ = mn; mn->prevX_ = tmp; mn->nextX_ = NULL; } else{ //fprintf(stdout, "tmp->nextX_ is not NULL, tmp->nextX_->X()=%0.f\n", tmp->nextX_->X()); mn->prevX_ = tmp->nextX_->prevX_; mn->nextX_ = tmp->nextX_; tmp->nextX_->prevX_ = mn; tmp->nextX_ = mn; } } else{ for(tmp = mn; tmp->prevX_ != NULL && tmp->prevX_->X() > X; tmp = tmp->prevX_); //fprintf(stdout,"Scanning the element addr %d X=%0.f, prev addr %d X=%0.f\n", tmp, tmp->X(), tmp->prevX_, tmp->prevX_->X()); if(tmp->prevX_ == NULL) { //fprintf(stdout, "tmp->prevX_ is NULL\n"); tmp->prevX_ = mn; mn->nextX_ = tmp; mn->prevX_ = NULL; xListHead_ = mn; } else{ //fprintf(stdout, "tmp->prevX_ is not NULL, tmp->prevX_->X()=%0.f\n", tmp->prevX_->X()); mn->nextX_ = tmp->prevX_->nextX_; mn->prevX_ = tmp->prevX_; tmp->prevX_->nextX_ = mn; tmp->prevX_ = mn; } } }}MobileNode **WirelessChannel::getAffectedNodes(MobileNode *mn, double radius, int *numAffectedNodes){ double xmin, xmax, ymin, ymax; int n = 0; MobileNode *tmp, **list, **tmpList; if (xListHead_ == NULL) { *numAffectedNodes=-1; fprintf(stderr, "xListHead_ is NULL when trying to send!!!\n"); return NULL; } xmin = mn->X() - radius; xmax = mn->X() + radius; ymin = mn->Y() - radius; ymax = mn->Y() + radius; // First allocate as much as possibly needed tmpList = new MobileNode*[numNodes_]; for(tmp = xListHead_; tmp != NULL; tmp = tmp->nextX_) tmpList[n++] = tmp; for(int i = 0; i < n; ++i) if(tmpList[i]->speed()!=0.0 && (Scheduler::instance().clock() - tmpList[i]->getUpdateTime()) > XLIST_POSITION_UPDATE_INTERVAL ) tmpList[i]->update_position(); n=0; for(tmp = mn; tmp != NULL && tmp->X() >= xmin; tmp=tmp->prevX_) if(tmp->Y() >= ymin && tmp->Y() <= ymax){ tmpList[n++] = tmp; } for(tmp = mn->nextX_; tmp != NULL && tmp->X() <= xmax; tmp=tmp->nextX_){ if(tmp->Y() >= ymin && tmp->Y() <= ymax){ tmpList[n++] = tmp; } } list = new MobileNode*[n]; memcpy(list, tmpList, n * sizeof(MobileNode *)); delete [] tmpList; *numAffectedNodes = n; return list;} /* Only to be used with mobile nodes (WirelessPhy). * NS-2 at its current state support only a flat (non 3D) movement of nodes, * so we assume antenna heights do not change for the dureation of * a simulation. * Another assumption - all nodes have the same wireless interface, so that * the maximum distance, corresponding to CST (at max transmission power * level) stays the same for all nodes. */voidWirelessChannel::calcHighestAntennaZ(Phy *tifp){ double highestZ = 0; Phy *n; for(n = ifhead_.lh_first; n; n = n->nextchnl()) { if(((WirelessPhy *)n)->getAntennaZ() > highestZ) highestZ = ((WirelessPhy *)n)->getAntennaZ(); } highestAntennaZ_ = highestZ; WirelessPhy *wifp = (WirelessPhy *)tifp; distCST_ = wifp->getDist(wifp->getCSThresh(), wifp->getPt(), 1.0, 1.0, highestZ , highestZ, wifp->getL(), wifp->getLambda()); } doubleWirelessChannel::get_pdelay(Node* tnode, Node* rnode){ // Scheduler &s = Scheduler::instance(); MobileNode* tmnode = (MobileNode*)tnode; MobileNode* rmnode = (MobileNode*)rnode; double propdelay = 0; propdelay = tmnode->propdelay(rmnode); assert(propdelay >= 0.0); if (propdelay == 0.0) { /* if the propdelay is 0 b/c two nodes are on top of each other, move them slightly apart -dam 7/28/98 */ propdelay = 2 * DBL_EPSILON; //printf ("propdelay 0: %d->%d at %f\n", // tmnode->address(), rmnode->address(), s.clock()); } return propdelay;}// begin RPI FSO Extensions//////// FSOWirelessChannel //////// double FSOWirelessChannel::highestAntennaZ_ = -1; // i.e., uninitializeddouble FSOWirelessChannel::distCST_ = -1;FSOWirelessChannel::FSOWirelessChannel(void) : WirelessChannel(), numNodes_(0), xListHead_(NULL), sorted_(0) {}int FSOWirelessChannel::command(int argc, const char*const* argv){ if (argc == 3) { TclObject *obj; if( (obj = TclObject::lookup(argv[2])) == 0) { fprintf(stderr, "%s lookup failed\n", argv[1]); return TCL_ERROR; } if (strcmp(argv[1], "add-node") == 0) { addNodeToList((MobileNode*) obj); return TCL_OK; } else if (strcmp(argv[1], "remove-node") == 0) { removeNodeFromList((MobileNode*) obj); return TCL_OK; } } return Channel::command(argc, argv);}voidFSOWirelessChannel::sendUp(Packet* p, Phy *tifp){ Scheduler &s = Scheduler::instance(); Phy *rifp = ifhead_.lh_first; Node *tnode = tifp->node(); Node *rnode = 0; Packet *newp; double propdelay = 0.0; struct hdr_cmn *hdr = HDR_CMN(p); /* list-based improvement */ if(highestAntennaZ_ == -1) { fprintf(stderr, "channel.cc:sendUp - Calc highestAntennaZ_ and distCST_\n"); calcHighestAntennaZ(tifp); fprintf(stderr, "highestAntennaZ_ = %0.1f, distCST_ = %0.1f\n", highestAntennaZ_, distCST_); } hdr->direction() = hdr_cmn::UP; // still keep grid-keeper around ?? if (GridKeeper::instance()) { int i; GridKeeper* gk = GridKeeper::instance(); int size = gk->size_; MobileNode **outlist = new MobileNode *[size]; int out_index = gk->get_neighbors((MobileNode*)tnode, outlist); for (i=0; i < out_index; i ++) { newp = p->copy(); rnode = outlist[i]; propdelay = get_pdelay(tnode, rnode); rifp = (rnode->ifhead()).lh_first; for(; rifp; rifp = rifp->nextnode()){ if (rifp->channel() == this){ s.schedule(rifp, newp, propdelay); break; } } } delete [] outlist; } else { // use list-based improvement //MobileNode * mtnode = (MobileNode *) tnode; MobileNode **affectedNodes;// **aN; int numAffectedNodes = -1, i; if(!sorted_){ sortLists(); } affectedNodes = getAffectedNodes(tifp, &numAffectedNodes); //affectedNodes = getAffectedNodes(mtnode, distCST_ + 5, &numAffectedNodes); for (i=0; i < numAffectedNodes; i++) { rnode = affectedNodes[i]; if(rnode == tnode) continue; rifp = (rnode->ifhead()).lh_first; for(; rifp; rifp = rifp->nextnode()) { newp = p->copy(); propdelay = get_pdelay(tnode, rnode); s.schedule(rifp, newp, propdelay); } } delete [] affectedNodes; } Packet::free(p);}voidFSOWirelessChannel::addNodeToList(MobileNode *mn){ MobileNode *tmp; // create list of mobilenodes for this channel if (xListHead_ == NULL) { fprintf(stderr, "INITIALIZE THE LIST xListHead\n"); xListHead_ = mn; xListHead_->nextX_ = NULL; xListHead_->prevX_ = NULL; } else { for (tmp = xListHead_; tmp->nextX_ != NULL; tmp=tmp->nextX_) { if (tmp == mn) { return; } } if (tmp == mn) { return; } tmp->nextX_ = mn; mn->prevX_ = tmp; mn->nextX_ = NULL; } numNodes_++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -