00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef lint
00039 static const char rcsid[] =
00040 "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/mac/channel.cc,v 1.45 2005/02/03 20:15:00 haldar Exp $ (UCB)";
00041 #endif
00042
00043
00044
00045 #define XLIST_POSITION_UPDATE_INTERVAL 1.0 //seconds
00046
00047
00048
00049
00050 #include <float.h>
00051
00052 #include "trace.h"
00053 #include "delay.h"
00054 #include "object.h"
00055 #include "packet.h"
00056 #include "mac.h"
00057 #include "channel.h"
00058 #include "lib/bsd-list.h"
00059 #include "phy.h"
00060 #include "wireless-phy.h"
00061 #include "mobilenode.h"
00062 #include "ip.h"
00063 #include "dsr/hdr_sr.h"
00064 #include "gridkeeper.h"
00065 #include "tworayground.h"
00066
00067 static class ChannelClass : public TclClass {
00068 public:
00069 ChannelClass() : TclClass("Channel") {}
00070 TclObject* create(int, const char*const*) {
00071 return (new Channel);
00072 }
00073 } class_channel;
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 static class WirelessChannelClass : public TclClass {
00084 public:
00085 WirelessChannelClass() : TclClass("Channel/WirelessChannel") {}
00086 TclObject* create(int, const char*const*) {
00087 return (new WirelessChannel);
00088 }
00089 } class_Wireless_channel;
00090
00091
00092
00093
00094
00095
00096 static int ChannelIndex = 0;
00097 Channel::Channel() : TclObject()
00098 {
00099 index_ = ChannelIndex++;
00100 LIST_INIT(&ifhead_);
00101 bind_time("delay_", &delay_);
00102 }
00103
00104 int Channel::command(int argc, const char*const* argv)
00105 {
00106
00107 if (argc == 3) {
00108 TclObject *obj;
00109
00110 if( (obj = TclObject::lookup(argv[2])) == 0) {
00111 fprintf(stderr, "%s lookup failed\n", argv[1]);
00112 return TCL_ERROR;
00113 }
00114 if (strcmp(argv[1], "trace-target") == 0) {
00115 trace_ = (Trace*) obj;
00116 return (TCL_OK);
00117 }
00118 else if(strcmp(argv[1], "addif") == 0) {
00119 ((Phy*) obj)->insertchnl(&ifhead_);
00120 ((Phy*) obj)->setchnl(this);
00121 return TCL_OK;
00122 }
00123
00124
00125
00126
00127
00128
00129 } else if (argc == 2) {
00130 Tcl& tcl = Tcl::instance();
00131 if (strcmp(argv[1], "trace-target") == 0) {
00132 tcl.resultf("%s", trace_->name());
00133 return (TCL_OK);
00134 }
00135 else if(strcmp(argv[1], "id") == 0) {
00136 tcl.resultf("%d", index_);
00137 return TCL_OK;
00138 }
00139 }
00140 return TclObject::command(argc, argv);
00141 }
00142
00143
00144 void Channel::recv(Packet* p, Handler* h)
00145 {
00146 sendUp(p, (Phy*)h);
00147 }
00148
00149
00150
00151 void
00152 Channel::sendUp(Packet* p, Phy *tifp)
00153 {
00154 Scheduler &s = Scheduler::instance();
00155 Phy *rifp = ifhead_.lh_first;
00156 Node *tnode = tifp->node();
00157 Node *rnode = 0;
00158 Packet *newp;
00159 double propdelay = 0.0;
00160 struct hdr_cmn *hdr = HDR_CMN(p);
00161
00162 hdr->direction() = hdr_cmn::UP;
00163 for( ; rifp; rifp = rifp->nextchnl()) {
00164 rnode = rifp->node();
00165 if(rnode == tnode)
00166 continue;
00167
00168
00169
00170
00171
00172
00173
00174 newp = p->copy();
00175 propdelay = get_pdelay(tnode, rnode);
00176
00177
00178
00179
00180
00181
00182
00183 s.schedule(rifp, newp, propdelay);
00184 }
00185
00186 Packet::free(p);
00187 }
00188
00189
00190
00191
00192 double
00193 Channel::get_pdelay(Node* , Node* )
00194 {
00195
00196 return delay_;
00197 }
00198
00199
00200 void
00201 Channel::dump(void)
00202 {
00203 Phy *n;
00204
00205 fprintf(stdout, "Network Interface List\n");
00206 for(n = ifhead_.lh_first; n; n = n->nextchnl() )
00207 n->dump();
00208 fprintf(stdout, "--------------------------------------------------\n");
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 struct ChannelDelayEvent : public Event {
00231 public:
00232 ChannelDelayEvent(Packet *p, Phy *txphy) : p_(p), txphy_(txphy) {};
00233 Packet *p_;
00234 Phy *txphy_;
00235 };
00236
00237 class NoDupChannel : public Channel, public Handler {
00238 public:
00239 void recv(Packet* p, Handler*);
00240 void handle(Event*);
00241 protected:
00242 int phy_counter_;
00243 private:
00244 void sendUp(Packet *p, Phy *txif);
00245
00246 };
00247
00248 void NoDupChannel::recv(Packet* p, Handler* h) {
00249 assert(hdr_cmn::access(p)->direction() == hdr_cmn::DOWN);
00250
00251 Scheduler &s = Scheduler::instance();
00252 ChannelDelayEvent *de = new ChannelDelayEvent(p, (Phy *)h);
00253 s.schedule(this, de, delay_);
00254 }
00255 void NoDupChannel::handle(Event *e) {
00256 ChannelDelayEvent *cde = (ChannelDelayEvent *)e;
00257 sendUp(cde->p_, cde->txphy_);
00258 delete cde;
00259 }
00260
00261 void NoDupChannel::sendUp(Packet *p, Phy *txif) {
00262 struct hdr_cmn *hdr = HDR_CMN(p);
00263 hdr->direction() = hdr_cmn::UP;
00264
00265 for(Phy *rifp = ifhead_.lh_first; rifp; rifp = rifp->nextchnl()) {
00266 if(rifp == txif)
00267 continue;
00268 rifp->recv(p->refcopy(), 0);
00269 }
00270 Packet::free(p);
00271 }
00272
00273 static class NoDupChannelClass : public TclClass {
00274 public:
00275 NoDupChannelClass() : TclClass("Channel/NoDup") {}
00276 TclObject* create(int, const char*const*) {
00277 return (new NoDupChannel);
00278 }
00279 } class_nodupchannel;
00280
00281
00282
00283
00284 class MobileNode;
00285
00286 double WirelessChannel::highestAntennaZ_ = -1;
00287 double WirelessChannel::distCST_ = -1;
00288
00289 WirelessChannel::WirelessChannel(void) : Channel(), numNodes_(0),
00290 xListHead_(NULL), sorted_(0) {}
00291
00292 int WirelessChannel::command(int argc, const char*const* argv)
00293 {
00294
00295 if (argc == 3) {
00296 TclObject *obj;
00297
00298 if( (obj = TclObject::lookup(argv[2])) == 0) {
00299 fprintf(stderr, "%s lookup failed\n", argv[1]);
00300 return TCL_ERROR;
00301 }
00302 if (strcmp(argv[1], "add-node") == 0) {
00303 addNodeToList((MobileNode*) obj);
00304 return TCL_OK;
00305 }
00306 else if (strcmp(argv[1], "remove-node") == 0) {
00307 removeNodeFromList((MobileNode*) obj);
00308 return TCL_OK;
00309 }
00310 }
00311 return Channel::command(argc, argv);
00312 }
00313
00314
00315 void
00316 WirelessChannel::sendUp(Packet* p, Phy *tifp)
00317 {
00318 Scheduler &s = Scheduler::instance();
00319 Phy *rifp = ifhead_.lh_first;
00320 Node *tnode = tifp->node();
00321 Node *rnode = 0;
00322 Packet *newp;
00323 double propdelay = 0.0;
00324 struct hdr_cmn *hdr = HDR_CMN(p);
00325
00326
00327 if(highestAntennaZ_ == -1) {
00328 fprintf(stdout, "channel.cc:sendUp - Calc highestAntennaZ_ and distCST_\n");
00329 calcHighestAntennaZ(tifp);
00330 fprintf(stdout, "highestAntennaZ_ = %0.1f, distCST_ = %0.1f\n", highestAntennaZ_, distCST_);
00331 }
00332
00333 hdr->direction() = hdr_cmn::UP;
00334
00335
00336 if (GridKeeper::instance()) {
00337 int i;
00338 GridKeeper* gk = GridKeeper::instance();
00339 int size = gk->size_;
00340
00341 MobileNode **outlist = new MobileNode *[size];
00342
00343 int out_index = gk->get_neighbors((MobileNode*)tnode,
00344 outlist);
00345 for (i=0; i < out_index; i ++) {
00346
00347 newp = p->copy();
00348 rnode = outlist[i];
00349 propdelay = get_pdelay(tnode, rnode);
00350
00351 rifp = (rnode->ifhead()).lh_first;
00352 for(; rifp; rifp = rifp->nextnode()){
00353 if (rifp->channel() == this){
00354 s.schedule(rifp, newp, propdelay);
00355 break;
00356 }
00357 }
00358 }
00359 delete [] outlist;
00360
00361 } else {
00362
00363 MobileNode *mtnode = (MobileNode *) tnode;
00364 MobileNode **affectedNodes;
00365 int numAffectedNodes = -1, i;
00366
00367 if(!sorted_){
00368 sortLists();
00369 }
00370
00371 affectedNodes = getAffectedNodes(mtnode, distCST_ + 5, &numAffectedNodes);
00372 for (i=0; i < numAffectedNodes; i++) {
00373 rnode = affectedNodes[i];
00374
00375 if(rnode == tnode)
00376 continue;
00377
00378 newp = p->copy();
00379
00380 propdelay = get_pdelay(tnode, rnode);
00381
00382 rifp = (rnode->ifhead()).lh_first;
00383 for(; rifp; rifp = rifp->nextnode()){
00384 s.schedule(rifp, newp, propdelay);
00385 }
00386 }
00387 delete [] affectedNodes;
00388 }
00389 Packet::free(p);
00390 }
00391
00392
00393 void
00394 WirelessChannel::addNodeToList(MobileNode *mn)
00395 {
00396 MobileNode *tmp;
00397
00398
00399 if (xListHead_ == NULL) {
00400 fprintf(stderr, "INITIALIZE THE LIST xListHead\n");
00401 xListHead_ = mn;
00402 xListHead_->nextX_ = NULL;
00403 xListHead_->prevX_ = NULL;
00404 } else {
00405 for (tmp = xListHead_; tmp->nextX_ != NULL; tmp=tmp->nextX_);
00406 tmp->nextX_ = mn;
00407 mn->prevX_ = tmp;
00408 mn->nextX_ = NULL;
00409 }
00410 numNodes_++;
00411 }
00412
00413 void
00414 WirelessChannel::removeNodeFromList(MobileNode *mn) {
00415
00416 MobileNode *tmp;
00417
00418 for (tmp = xListHead_; tmp->nextX_ != NULL; tmp=tmp->nextX_) {
00419 if (tmp == mn) {
00420 if (tmp == xListHead_) {
00421 xListHead_ = tmp->nextX_;
00422 if (tmp->nextX_ != NULL)
00423 tmp->nextX_->prevX_ = NULL;
00424 } else if (tmp->nextX_ == NULL)
00425 tmp->prevX_->nextX_ = NULL;
00426 else {
00427 tmp->prevX_->nextX_ = tmp->nextX_;
00428 tmp->nextX_->prevX_ = tmp->prevX_;
00429 }
00430 numNodes_--;
00431 return;
00432 }
00433 }
00434 fprintf(stderr, "Channel: node not found in list\n");
00435 }
00436
00437 void
00438 WirelessChannel::sortLists(void) {
00439 bool flag = true;
00440 MobileNode *m, *q;
00441
00442 sorted_ = true;
00443
00444 fprintf(stderr, "SORTING LISTS ...");
00445
00446
00447 while(flag) {
00448 flag = false;
00449 m = xListHead_;
00450 while (m != NULL){
00451 if(m->nextX_ != NULL)
00452 if ( m->X() > m->nextX_->X() ){
00453 flag = true;
00454
00455 q = m->nextX_;
00456 m->nextX_ = q->nextX_;
00457 if (q->nextX_ != NULL)
00458 q->nextX_->prevX_ = m;
00459
00460
00461 q->nextX_ = m;
00462 q->prevX_ = m->prevX_;
00463 m->prevX_ = q;
00464 if (q->prevX_ != NULL)
00465 q->prevX_->nextX_ = q;
00466
00467
00468 if(m == xListHead_)
00469 xListHead_ = m->prevX_;
00470 }
00471 m = m -> nextX_;
00472 }
00473 }
00474
00475 fprintf(stderr, "DONE!\n");
00476 }
00477
00478 void
00479 WirelessChannel::updateNodesList(class MobileNode *mn, double oldX) {
00480
00481 MobileNode* tmp;
00482 double X = mn->X();
00483 bool skipX=false;
00484
00485 if(!sorted_) {
00486 sortLists();
00487 return;
00488 }
00489
00490
00491
00492
00493
00494 if(mn->nextX_ != NULL) {
00495 if(mn->prevX_ != NULL){
00496 if((mn->nextX_->X() >= X) && (mn->prevX_->X() <= X)) skipX = true;
00497 else{
00498 mn->nextX_->prevX_ = mn->prevX_;
00499 mn->prevX_->nextX_ = mn->nextX_;
00500 }
00501 }
00502
00503 else{
00504 if(mn->nextX_->X() >= X) skipX = true;
00505 else{
00506 mn->nextX_->prevX_ = NULL;
00507 xListHead_ = mn->nextX_;
00508 }
00509 }
00510 }
00511
00512 else if(mn->prevX_ !=NULL){
00513 if(mn->prevX_->X() <= X) skipX = true;
00514 else mn->prevX_->nextX_ = NULL;
00515 }
00516
00517 if ((mn->prevX_ == NULL) && (mn->nextX_ == NULL)) skipX = true;
00518
00519
00520
00521 if(!skipX){
00522 if(X > oldX){
00523 for(tmp = mn; tmp->nextX_ != NULL && tmp->nextX_->X() < X; tmp = tmp->nextX_);
00524
00525 if(tmp->nextX_ == NULL) {
00526
00527 tmp->nextX_ = mn;
00528 mn->prevX_ = tmp;
00529 mn->nextX_ = NULL;
00530 }
00531 else{
00532
00533 mn->prevX_ = tmp->nextX_->prevX_;
00534 mn->nextX_ = tmp->nextX_;
00535 tmp->nextX_->prevX_ = mn;
00536 tmp->nextX_ = mn;
00537 }
00538 }
00539 else{
00540 for(tmp = mn; tmp->prevX_ != NULL && tmp->prevX_->X() > X; tmp = tmp->prevX_);
00541
00542 if(tmp->prevX_ == NULL) {
00543
00544 tmp->prevX_ = mn;
00545 mn->nextX_ = tmp;
00546 mn->prevX_ = NULL;
00547 xListHead_ = mn;
00548 }
00549 else{
00550
00551 mn->nextX_ = tmp->prevX_->nextX_;
00552 mn->prevX_ = tmp->prevX_;
00553 tmp->prevX_->nextX_ = mn;
00554 tmp->prevX_ = mn;
00555 }
00556 }
00557 }
00558 }
00559
00560
00561 MobileNode **
00562 WirelessChannel::getAffectedNodes(MobileNode *mn, double radius,
00563 int *numAffectedNodes)
00564 {
00565 double xmin, xmax, ymin, ymax;
00566 int n = 0;
00567 MobileNode *tmp, **list, **tmpList;
00568
00569 if (xListHead_ == NULL) {
00570 *numAffectedNodes=-1;
00571 fprintf(stderr, "xListHead_ is NULL when trying to send!!!\n");
00572 return NULL;
00573 }
00574
00575 xmin = mn->X() - radius;
00576 xmax = mn->X() + radius;
00577 ymin = mn->Y() - radius;
00578 ymax = mn->Y() + radius;
00579
00580
00581 tmpList = new MobileNode*[numNodes_];
00582
00583 for(tmp = xListHead_; tmp != NULL; tmp = tmp->nextX_) tmpList[n++] = tmp;
00584 for(int i = 0; i < n; ++i)
00585 if(tmpList[i]->speed()!=0.0 && (Scheduler::instance().clock() -
00586 tmpList[i]->getUpdateTime()) > XLIST_POSITION_UPDATE_INTERVAL )
00587 tmpList[i]->update_position();
00588 n=0;
00589
00590 for(tmp = mn; tmp != NULL && tmp->X() >= xmin; tmp=tmp->prevX_)
00591 if(tmp->Y() >= ymin && tmp->Y() <= ymax){
00592 tmpList[n++] = tmp;
00593 }
00594 for(tmp = mn->nextX_; tmp != NULL && tmp->X() <= xmax; tmp=tmp->nextX_){
00595 if(tmp->Y() >= ymin && tmp->Y() <= ymax){
00596 tmpList[n++] = tmp;
00597 }
00598 }
00599
00600 list = new MobileNode*[n];
00601 memcpy(list, tmpList, n * sizeof(MobileNode *));
00602 delete [] tmpList;
00603
00604 *numAffectedNodes = n;
00605 return list;
00606 }
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618 void
00619 WirelessChannel::calcHighestAntennaZ(Phy *tifp)
00620 {
00621 double highestZ = 0;
00622 Phy *n;
00623
00624 for(n = ifhead_.lh_first; n; n = n->nextchnl()) {
00625 if(((WirelessPhy *)n)->getAntennaZ() > highestZ)
00626 highestZ = ((WirelessPhy *)n)->getAntennaZ();
00627 }
00628
00629 highestAntennaZ_ = highestZ;
00630
00631 WirelessPhy *wifp = (WirelessPhy *)tifp;
00632 distCST_ = wifp->getDist(wifp->getCSThresh(), wifp->getPt(), 1.0, 1.0,
00633 highestZ , highestZ, wifp->getL(),
00634 wifp->getLambda());
00635 }
00636
00637
00638 double
00639 WirelessChannel::get_pdelay(Node* tnode, Node* rnode)
00640 {
00641
00642 MobileNode* tmnode = (MobileNode*)tnode;
00643 MobileNode* rmnode = (MobileNode*)rnode;
00644 double propdelay = 0;
00645
00646 propdelay = tmnode->propdelay(rmnode);
00647
00648 assert(propdelay >= 0.0);
00649 if (propdelay == 0.0) {
00650
00651
00652 propdelay = 2 * DBL_EPSILON;
00653
00654
00655 }
00656 return propdelay;
00657 }
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761