channel.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:20k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* -*- Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*- */
  2. /*
  3.  * Copyright (c) 1996 Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer.
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in the
  13.  *    documentation and/or other materials provided with the distribution.
  14.  * 3. All advertising materials mentioning features or use of this software
  15.  *    must display the following acknowledgement:
  16.  * This product includes software developed by the Computer Systems
  17.  * Engineering Group at Lawrence Berkeley Laboratory and the Daedalus
  18.  * research group at UC Berkeley.
  19.  * 4. Neither the name of the University nor of the Laboratory may be used
  20.  *    to endorse or promote products derived from this software without
  21.  *    specific prior written permission.
  22.  *
  23.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  24.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  27.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  28.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  29.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  30.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  32.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  33.  * SUCH DAMAGE.
  34.  *
  35.  * Contributed by Giao Nguyen, http://daedalus.cs.berkeley.edu/~gnguyen
  36.  */
  37. #ifndef lint
  38. static const char rcsid[] =
  39.     "@(#) $Header: /cvsroot/nsnam/ns-2/mac/channel.cc,v 1.46 2008/02/01 21:39:39 tom_henderson Exp $ (UCB)";
  40. #endif
  41. // Time interval for updating a position of a node in the X-List
  42. // (can be adjusted by the user, depending on the nodes mobility). /* VAL NAUMOV */
  43. #define XLIST_POSITION_UPDATE_INTERVAL 1.0 //seconds
  44. //#include "template.h"
  45. #include <float.h>
  46. #include "trace.h"
  47. #include "delay.h"
  48. #include "object.h"
  49. #include "packet.h"
  50. #include "mac.h"
  51. #include "channel.h"
  52. #include "lib/bsd-list.h"
  53. #include "phy.h"
  54. #include "wireless-phy.h"
  55. #include "mobilenode.h"
  56. #include "ip.h"
  57. #include "dsr/hdr_sr.h"
  58. #include "gridkeeper.h"
  59. #include "tworayground.h"
  60. #include "wireless-phyExt.h"
  61. static class ChannelClass : public TclClass {
  62. public:
  63. ChannelClass() : TclClass("Channel") {}
  64. TclObject* create(int, const char*const*) {
  65. return (new Channel);
  66. }
  67. } class_channel;
  68. /*static class DuplexChannelClass : public TclClass {
  69. public:
  70. DuplexChannelClass() : TclClass("Channel/Duplex") {}
  71. TclObject* create(int, const char*const*) {
  72. return (new DuplexChannel);
  73. }
  74. } class_channel_duplex; */
  75. static class WirelessChannelClass : public TclClass {
  76. public:
  77.         WirelessChannelClass() : TclClass("Channel/WirelessChannel") {}
  78.         TclObject* create(int, const char*const*) {
  79.                 return (new WirelessChannel);
  80.         }
  81. } class_Wireless_channel;
  82. /* ==================================================================
  83.    NS Initialization Functions
  84.    =================================================================*/
  85. static int ChannelIndex = 0;
  86. Channel::Channel() : TclObject()
  87. {
  88. index_ = ChannelIndex++;
  89. LIST_INIT(&ifhead_);
  90. bind_time("delay_", &delay_);
  91. }
  92. int Channel::command(int argc, const char*const* argv)
  93. {
  94. if (argc == 3) {
  95. TclObject *obj;
  96. if( (obj = TclObject::lookup(argv[2])) == 0) {
  97. fprintf(stderr, "%s lookup failedn", argv[1]);
  98. return TCL_ERROR;
  99. }
  100. if (strcmp(argv[1], "trace-target") == 0) {
  101. trace_ = (Trace*) obj;
  102. return (TCL_OK);
  103. }
  104. else if(strcmp(argv[1], "addif") == 0) {
  105. ((Phy*) obj)->insertchnl(&ifhead_);
  106. ((Phy*) obj)->setchnl(this);
  107. return TCL_OK;
  108. }
  109. // add interface for grid_keeper_
  110. /*else if(strncasecmp(argv[1], "grid_keeper", 5) == 0) {
  111. grid_keeper_ = (GridKeeper*)obj;
  112. return TCL_OK;
  113. }*/
  114. } else if (argc == 2) {
  115. Tcl& tcl = Tcl::instance();
  116. if (strcmp(argv[1], "trace-target") == 0) {
  117. tcl.resultf("%s", trace_->name());
  118. return (TCL_OK);
  119. }
  120. else if(strcmp(argv[1], "id") == 0) {
  121. tcl.resultf("%d", index_);
  122. return TCL_OK;
  123. }
  124. }
  125. return TclObject::command(argc, argv);
  126. }
  127. void Channel::recv(Packet* p, Handler* h)
  128. {
  129. sendUp(p, (Phy*)h);
  130. }
  131. void
  132. Channel::sendUp(Packet* p, Phy *tifp)
  133. {
  134. Scheduler &s = Scheduler::instance();
  135. Phy *rifp = ifhead_.lh_first;
  136. Node *tnode = tifp->node();
  137. Node *rnode = 0;
  138. Packet *newp;
  139. double propdelay = 0.0;
  140. struct hdr_cmn *hdr = HDR_CMN(p);
  141. hdr->direction() = hdr_cmn::UP;
  142. for( ; rifp; rifp = rifp->nextchnl()) {
  143. rnode = rifp->node();
  144. if(rnode == tnode)
  145. continue;
  146. /*
  147.  * Each node needs to get their own copy of this packet.
  148.  * Since collisions occur at the receiver, we can have
  149.  * two nodes canceling and freeing the *same* simulation
  150.  * event.
  151.  *
  152.  */
  153. newp = p->copy();
  154. propdelay = get_pdelay(tnode, rnode);
  155. /*
  156.  * Each node on the channel receives a copy of the
  157.  * packet.  The propagation delay determines exactly
  158.  * when the receiver's interface detects the first
  159.  * bit of this packet.
  160.  */
  161. s.schedule(rifp, newp, propdelay);
  162. }
  163. Packet::free(p);
  164. }
  165. double 
  166. Channel::get_pdelay(Node* /*tnode*/, Node* /*rnode*/)
  167. {
  168. // Dummy function
  169. return delay_;
  170. }
  171. void
  172. Channel::dump(void)
  173. {
  174. Phy *n;
  175. fprintf(stdout, "Network Interface Listn");
  176.   for(n = ifhead_.lh_first; n; n = n->nextchnl() )
  177. n->dump();
  178. fprintf(stdout, "--------------------------------------------------n");
  179. }
  180. /* NoDupChannel------------------------------------------------------------
  181.  * NoDupChannel is currently acting the same as Channel but with one
  182.  * important difference: it uses reference-copying of the packet,
  183.  * thus, a lot of time is saved (e.g. for 49 senders and 1 receiver
  184.  * overflowing mac802.3 and running for 10 seconds sim time, factors
  185.  * of 60 and more of savings in actual running time have been
  186.  * observed).
  187.  *
  188.  * DRAWBACKS: 
  189.  *
  190.  * - No propagation model supported (uses constant prop delay for 
  191.  *        all nodes), although it should be easy to change that.
  192.  * - Macs should be EXTREMELY careful handling these reference 
  193.  *        copies: essentially they all are expected not to modify them 
  194.  *   in any way (including scheduling!) while reference counter is
  195.  *        positive.  802.3 seems to work with it, other macs may need
  196.  *   some changes.
  197.  */
  198. struct ChannelDelayEvent : public Event {
  199. public:
  200. ChannelDelayEvent(Packet *p, Phy *txphy) : p_(p), txphy_(txphy) {};
  201. Packet *p_;
  202. Phy *txphy_;
  203. };
  204. class NoDupChannel : public Channel, public Handler {
  205. public:
  206. void recv(Packet* p, Handler*);
  207. void handle(Event*);
  208. protected:
  209. int phy_counter_;
  210. private:
  211. void sendUp(Packet *p, Phy *txif);
  212. };
  213. void NoDupChannel::recv(Packet* p, Handler* h) {
  214. assert(hdr_cmn::access(p)->direction() == hdr_cmn::DOWN);
  215. // Delay this packet
  216. Scheduler &s = Scheduler::instance();
  217. ChannelDelayEvent *de = new ChannelDelayEvent(p, (Phy *)h);
  218. s.schedule(this, de, delay_);
  219. }
  220. void NoDupChannel::handle(Event *e) {
  221. ChannelDelayEvent *cde = (ChannelDelayEvent *)e;
  222. sendUp(cde->p_, cde->txphy_);
  223. delete cde;
  224. }
  225. void NoDupChannel::sendUp(Packet *p, Phy *txif) {
  226. struct hdr_cmn *hdr = HDR_CMN(p);
  227. hdr->direction() = hdr_cmn::UP;
  228. for(Phy *rifp = ifhead_.lh_first; rifp; rifp = rifp->nextchnl()) {
  229. if(rifp == txif)
  230. continue;
  231. rifp->recv(p->refcopy(), 0);
  232. }
  233. Packet::free(p);
  234. }
  235. static class NoDupChannelClass : public TclClass {
  236. public:
  237. NoDupChannelClass() : TclClass("Channel/NoDup") {}
  238. TclObject* create(int, const char*const*) {
  239. return (new NoDupChannel);
  240. }
  241. } class_nodupchannel;
  242. // Wireless extensions
  243. class MobileNode;
  244. double WirelessChannel::highestAntennaZ_ = -1; // i.e., uninitialized
  245. double WirelessChannel::distCST_ = -1;
  246. WirelessChannel::WirelessChannel(void) : Channel(), numNodes_(0), 
  247.  xListHead_(NULL), sorted_(0) {}
  248. int WirelessChannel::command(int argc, const char*const* argv)
  249. {
  250. if (argc == 3) {
  251. TclObject *obj;
  252. if( (obj = TclObject::lookup(argv[2])) == 0) {
  253. fprintf(stderr, "%s lookup failedn", argv[1]);
  254. return TCL_ERROR;
  255. }
  256. if (strcmp(argv[1], "add-node") == 0) {
  257. addNodeToList((MobileNode*) obj);
  258. return TCL_OK;
  259. }
  260. else if (strcmp(argv[1], "remove-node") == 0) {
  261. removeNodeFromList((MobileNode*) obj);
  262. return TCL_OK;
  263. }
  264. }
  265. return Channel::command(argc, argv);
  266. }
  267. void
  268. WirelessChannel::sendUp(Packet* p, Phy *tifp)
  269. {
  270. Scheduler &s = Scheduler::instance();
  271. Phy *rifp = ifhead_.lh_first;
  272. Node *tnode = tifp->node();
  273. Node *rnode = 0;
  274. Packet *newp;
  275. double propdelay = 0.0;
  276. struct hdr_cmn *hdr = HDR_CMN(p);
  277.          /* list-based improvement */
  278.          if(highestAntennaZ_ == -1) {
  279.                  fprintf(stdout, "channel.cc:sendUp - Calc highestAntennaZ_ and distCST_n");
  280.                  calcHighestAntennaZ(tifp);
  281.                  fprintf(stdout, "highestAntennaZ_ = %0.1f,  distCST_ = %0.1fn", highestAntennaZ_, distCST_);
  282.          }
  283.  hdr->direction() = hdr_cmn::UP;
  284.  // still keep grid-keeper around ??
  285.  if (GridKeeper::instance()) {
  286.     int i;
  287.     GridKeeper* gk = GridKeeper::instance();
  288.     int size = gk->size_; 
  289.     
  290.     MobileNode **outlist = new MobileNode *[size];
  291.  
  292.             int out_index = gk->get_neighbors((MobileNode*)tnode,
  293.          outlist);
  294.     for (i=0; i < out_index; i ++) {
  295.   newp = p->copy();
  296.   rnode = outlist[i];
  297.   propdelay = get_pdelay(tnode, rnode);
  298.   rifp = (rnode->ifhead()).lh_first; 
  299.   for(; rifp; rifp = rifp->nextnode()){
  300.   if (rifp->channel() == this){
  301.  s.schedule(rifp, newp, propdelay); 
  302.  break;
  303.   }
  304.   }
  305.       }
  306.     delete [] outlist; 
  307.  
  308.  } else { // use list-based improvement
  309.  
  310.  MobileNode *mtnode = (MobileNode *) tnode;
  311.  MobileNode **affectedNodes;// **aN;
  312.  int numAffectedNodes = -1, i;
  313.  
  314.  if(!sorted_){
  315.  sortLists();
  316.  }
  317.  
  318.  affectedNodes = getAffectedNodes(mtnode, distCST_ + /* safety */ 5, &numAffectedNodes);
  319.  for (i=0; i < numAffectedNodes; i++) {
  320.  rnode = affectedNodes[i];
  321.  
  322.  if(rnode == tnode)
  323.  continue;
  324.  
  325.  newp = p->copy();
  326.  
  327.  propdelay = get_pdelay(tnode, rnode);
  328.  
  329.  rifp = (rnode->ifhead()).lh_first;
  330.  for(; rifp; rifp = rifp->nextnode()){
  331.  s.schedule(rifp, newp, propdelay);
  332.  }
  333.  }
  334.  delete [] affectedNodes;
  335.  }
  336.  Packet::free(p);
  337. }
  338. void
  339. WirelessChannel::addNodeToList(MobileNode *mn)
  340. {
  341. MobileNode *tmp;
  342. // create list of mobilenodes for this channel
  343. if (xListHead_ == NULL) {
  344. fprintf(stderr, "INITIALIZE THE LIST xListHeadn");
  345. xListHead_ = mn;
  346. xListHead_->nextX_ = NULL;
  347. xListHead_->prevX_ = NULL;
  348. } else {
  349. for (tmp = xListHead_; tmp->nextX_ != NULL; tmp=tmp->nextX_);
  350. tmp->nextX_ = mn;
  351. mn->prevX_ = tmp;
  352. mn->nextX_ = NULL;
  353. }
  354. numNodes_++;
  355. }
  356. void
  357. WirelessChannel::removeNodeFromList(MobileNode *mn) {
  358. MobileNode *tmp;
  359. // Find node in list
  360. for (tmp = xListHead_; tmp->nextX_ != NULL; tmp=tmp->nextX_) {
  361. if (tmp == mn) {
  362. if (tmp == xListHead_) {
  363. xListHead_ = tmp->nextX_;
  364. if (tmp->nextX_ != NULL)
  365. tmp->nextX_->prevX_ = NULL;
  366. } else if (tmp->nextX_ == NULL) 
  367. tmp->prevX_->nextX_ = NULL;
  368. else {
  369. tmp->prevX_->nextX_ = tmp->nextX_;
  370. tmp->nextX_->prevX_ = tmp->prevX_;
  371. }
  372. numNodes_--;
  373. return;
  374. }
  375. }
  376. fprintf(stderr, "Channel: node not found in listn");
  377. }
  378. void
  379. WirelessChannel::sortLists(void) {
  380. bool flag = true;
  381. MobileNode *m, *q;
  382. sorted_ = true;
  383. fprintf(stderr, "SORTING LISTS ...");
  384. /* Buble sort algorithm */
  385. // SORT x-list
  386. while(flag) {
  387. flag = false;
  388. m = xListHead_;
  389. while (m != NULL){
  390. if(m->nextX_ != NULL)
  391. if ( m->X() > m->nextX_->X() ){
  392. flag = true;
  393. //delete_after m;
  394. q = m->nextX_;
  395. m->nextX_ = q->nextX_;
  396. if (q->nextX_ != NULL)
  397. q->nextX_->prevX_ = m;
  398.     
  399. //insert_before m;
  400. q->nextX_ = m;
  401. q->prevX_ = m->prevX_;
  402. m->prevX_ = q;
  403. if (q->prevX_ != NULL)
  404. q->prevX_->nextX_ = q;
  405. // adjust Head of List
  406. if(m == xListHead_) 
  407. xListHead_ = m->prevX_;
  408. }
  409. m = m -> nextX_;
  410. }
  411. }
  412. fprintf(stderr, "DONE!n");
  413. }
  414. void
  415. WirelessChannel::updateNodesList(class MobileNode *mn, double oldX) {
  416. MobileNode* tmp;
  417. double X = mn->X();
  418. bool skipX=false;
  419. if(!sorted_) {
  420. sortLists();
  421. return;
  422. }
  423. /* xListHead cannot be NULL here (they are created during creation of mobilenode) */
  424. /***  DELETE ***/
  425. // deleting mn from x-list
  426. if(mn->nextX_ != NULL) {
  427. if(mn->prevX_ != NULL){
  428. if((mn->nextX_->X() >= X) && (mn->prevX_->X() <= X)) skipX = true; // the node doesn't change its position in the list
  429. else{
  430. mn->nextX_->prevX_ = mn->prevX_;
  431. mn->prevX_->nextX_ = mn->nextX_;
  432. }
  433. }
  434. else{
  435. if(mn->nextX_->X() >= X) skipX = true; // skip updating the first element
  436. else{
  437. mn->nextX_->prevX_ = NULL;
  438. xListHead_ = mn->nextX_;
  439. }
  440. }
  441. }
  442. else if(mn->prevX_ !=NULL){
  443. if(mn->prevX_->X() <= X) skipX = true; // skip updating the last element
  444. else mn->prevX_->nextX_ = NULL;
  445. }
  446. if ((mn->prevX_ == NULL) && (mn->nextX_ == NULL)) skipX = true; //skip updating if only one element in list
  447. /*** INSERT ***/
  448. //inserting mn in x-list
  449. if(!skipX){
  450. if(X > oldX){
  451. for(tmp = mn; tmp->nextX_ != NULL && tmp->nextX_->X() < X; tmp = tmp->nextX_);
  452. //fprintf(stdout,"Scanning the element addr %d X=%0.f, next addr %d X=%0.fn", tmp, tmp->X(), tmp->nextX_, tmp->nextX_->X());
  453. if(tmp->nextX_ == NULL) { 
  454. //fprintf(stdout, "tmp->nextX_ is NULLn");
  455. tmp->nextX_ = mn;
  456. mn->prevX_ = tmp;
  457. mn->nextX_ = NULL;
  458. else{ 
  459. //fprintf(stdout, "tmp->nextX_ is not NULL, tmp->nextX_->X()=%0.fn", tmp->nextX_->X());
  460. mn->prevX_ = tmp->nextX_->prevX_;
  461. mn->nextX_ = tmp->nextX_;
  462. tmp->nextX_->prevX_ = mn;  
  463. tmp->nextX_ = mn;
  464. }
  465. else{
  466. for(tmp = mn; tmp->prevX_ != NULL && tmp->prevX_->X() > X; tmp = tmp->prevX_);
  467. //fprintf(stdout,"Scanning the element addr %d X=%0.f, prev addr %d X=%0.fn", tmp, tmp->X(), tmp->prevX_, tmp->prevX_->X());
  468. if(tmp->prevX_ == NULL) {
  469. //fprintf(stdout, "tmp->prevX_ is NULLn");
  470. tmp->prevX_ = mn;
  471. mn->nextX_ = tmp;
  472. mn->prevX_ = NULL;
  473. xListHead_ = mn;
  474. else{
  475. //fprintf(stdout, "tmp->prevX_ is not NULL, tmp->prevX_->X()=%0.fn", tmp->prevX_->X());
  476. mn->nextX_ = tmp->prevX_->nextX_;
  477. mn->prevX_ = tmp->prevX_;
  478. tmp->prevX_->nextX_ = mn;  
  479. tmp->prevX_ = mn;
  480. }
  481. }
  482. }
  483. }
  484. MobileNode **
  485. WirelessChannel::getAffectedNodes(MobileNode *mn, double radius,
  486.   int *numAffectedNodes)
  487. {
  488. double xmin, xmax, ymin, ymax;
  489. int n = 0;
  490. MobileNode *tmp, **list, **tmpList;
  491. if (xListHead_ == NULL) {
  492. *numAffectedNodes=-1;
  493. fprintf(stderr, "xListHead_ is NULL when trying to send!!!n");
  494. return NULL;
  495. }
  496. xmin = mn->X() - radius;
  497. xmax = mn->X() + radius;
  498. ymin = mn->Y() - radius;
  499. ymax = mn->Y() + radius;
  500. // First allocate as much as possibly needed
  501. tmpList = new MobileNode*[numNodes_];
  502. for(tmp = xListHead_; tmp != NULL; tmp = tmp->nextX_) tmpList[n++] = tmp;
  503. for(int i = 0; i < n; ++i)
  504. if(tmpList[i]->speed()!=0.0 && (Scheduler::instance().clock() -
  505. tmpList[i]->getUpdateTime()) > XLIST_POSITION_UPDATE_INTERVAL )
  506. tmpList[i]->update_position();
  507. n=0;
  508. for(tmp = mn; tmp != NULL && tmp->X() >= xmin; tmp=tmp->prevX_)
  509. if(tmp->Y() >= ymin && tmp->Y() <= ymax){
  510. tmpList[n++] = tmp;
  511. }
  512. for(tmp = mn->nextX_; tmp != NULL && tmp->X() <= xmax; tmp=tmp->nextX_){
  513. if(tmp->Y() >= ymin && tmp->Y() <= ymax){
  514. tmpList[n++] = tmp;
  515. }
  516. }
  517. list = new MobileNode*[n];
  518. memcpy(list, tmpList, n * sizeof(MobileNode *));
  519. delete [] tmpList;
  520.          
  521. *numAffectedNodes = n;
  522. return list;
  523. }
  524.  
  525. /* Only to be used with mobile nodes (WirelessPhy).
  526.  * NS-2 at its current state support only a flat (non 3D) movement of nodes,
  527.  * so we assume antenna heights do not change for the dureation of
  528.  * a simulation.
  529.  * Another assumption - all nodes have the same wireless interface, so that
  530.  * the maximum distance, corresponding to CST (at max transmission power 
  531.  * level) stays the same for all nodes.
  532.  */
  533. void
  534. WirelessChannel::calcHighestAntennaZ(Phy *tifp)
  535. {
  536.        double highestZ = 0;
  537.        Phy *n;
  538.  
  539.        // HACK: the dynamic_cast is a workaround only!
  540.        for(n = ifhead_.lh_first; n; n = n->nextchnl()) {
  541.         if(dynamic_cast<WirelessPhyExt*>(n)) {
  542.         if(((WirelessPhyExt *)n)->getAntennaZ() > highestZ)
  543.         highestZ = ((WirelessPhyExt *)n)->getAntennaZ();
  544.         } else if (dynamic_cast<WirelessPhy*>(n)) {
  545.         if(((WirelessPhy *)n)->getAntennaZ() > highestZ)
  546.         highestZ = ((WirelessPhy *)n)->getAntennaZ();
  547.         } else highestZ = 0;
  548.        }
  549.  
  550.        highestAntennaZ_ = highestZ;
  551.        if (dynamic_cast<WirelessPhyExt*>(tifp)) {
  552.         WirelessPhyExt *wifp = (WirelessPhyExt *)tifp;
  553.         distCST_ = wifp->getDist(wifp->getCSThresh(), wifp->getPt(), 1.0, 1.0, 
  554.    highestZ , highestZ, wifp->getL(),
  555.    wifp->getLambda());
  556.        } else if (dynamic_cast<WirelessPhy*>(tifp)) {
  557.         WirelessPhy *wifp = (WirelessPhy *)tifp;
  558.         distCST_ = wifp->getDist(wifp->getCSThresh(), wifp->getPt(), 1.0, 1.0,
  559.         highestZ , highestZ, wifp->getL(),
  560.         wifp->getLambda());       
  561.        } else distCST_ = DBL_MAX;
  562. }
  563. double
  564. WirelessChannel::get_pdelay(Node* tnode, Node* rnode)
  565. {
  566. // Scheduler &s = Scheduler::instance();
  567. MobileNode* tmnode = (MobileNode*)tnode;
  568. MobileNode* rmnode = (MobileNode*)rnode;
  569. double propdelay = 0;
  570. propdelay = tmnode->propdelay(rmnode);
  571. assert(propdelay >= 0.0);
  572. if (propdelay == 0.0) {
  573. /* if the propdelay is 0 b/c two nodes are on top of 
  574.    each other, move them slightly apart -dam 7/28/98 */
  575. propdelay = 2 * DBL_EPSILON;
  576. //printf ("propdelay 0: %d->%d at %fn",
  577. // tmnode->address(), rmnode->address(), s.clock());
  578. }
  579. return propdelay;
  580. }
  581. // send():
  582. //  The packet occupies the channel for the transmission time, txtime
  583. //  If collision occur (>1 pkts overlap), corrupt all pkts involved
  584. // by setting the error bit or discard them
  585. // int Channel::send(Packet* p, Phy *tifp)
  586. // {
  587. //  // without collision, return 0
  588. //  Scheduler& s = Scheduler::instance();
  589. //  double now = s.clock();
  590. //  // busy = time when the channel are still busy with earlier tx
  591. //  double busy = max(txstop_, cwstop_);
  592. //  // txstop = when the channel is no longer busy from this tx
  593. //  txstop_ = max(busy, now + txtime);
  594. //  // now < busy => collision
  595. //  // mark the pkt error bit, EF_COLLISION
  596. //  // drop if there is a drop target, drop_
  597. //  if (now < busy) {
  598. //  // if still transmit earlier packet, pkt_, then corrupt it
  599. //  if (pkt_ && pkt_->time_ > now) {
  600. //  hdr_cmn::access(pkt_)->error() |= EF_COLLISION;
  601. //  if (drop_) {
  602. //  s.cancel(pkt_);
  603. //  drop(pkt_);
  604. //  pkt_ = 0;
  605. //  }
  606. //  }
  607. //  // corrupts the current packet p, and drop if drop_ exists
  608. //  hdr_cmn::access(p)->error() |= EF_COLLISION;
  609. //  if (drop_) {
  610. //  drop(p);
  611. //  return 1;
  612. //  }
  613. //  }
  614. //  // if p was not dropped, call recv() or hand it to trace_ if present
  615. //  pkt_ = p;
  616. //  trace_ ? trace_->recv(p, 0) : recv(p, 0);
  617. //  return 0;
  618. // }
  619. // contention():
  620. //  The MAC calls this Channel::contention() to enter contention period
  621. //  It determines when the contention window is over, cwstop_,
  622. // and schedule a callback to the MAC for the actual send()
  623. // void Channel::contention(Packet* p, Handler* h)
  624. // {
  625. //  Scheduler& s = Scheduler::instance();
  626. //  double now = s.clock();
  627. //  if (now > cwstop_) {
  628. //  cwstop_ = now + delay_;
  629. //  numtx_ = 0;
  630. //  }
  631. //  numtx_++;
  632. //  s.schedule(h, p, cwstop_ - now);
  633. // }
  634. // jam():
  635. //  Jam the channel for a period txtime
  636. //  Some MAC protocols use this to let other MAC detect collisions
  637. // int Channel::jam(double txtime)
  638. // {
  639. //  // without collision, return 0
  640. //  double now = Scheduler::instance().clock();
  641. //  if (txstop_ > now) {
  642. //  txstop_ = max(txstop_, now + txtime);
  643. //  return 1;
  644. //  }
  645. //  txstop_ = now + txtime;
  646. //  return (now < cwstop_);
  647. // }
  648. // int DuplexChannel::send(Packet* p, double txtime)
  649. // {
  650. //  double now = Scheduler::instance().clock();
  651. //  txstop_ = now + txtime;
  652. //  trace_ ? trace_->recv(p, 0) : recv(p, 0);
  653. //  return 0;
  654. // }
  655. // void DuplexChannel::contention(Packet* p, Handler* h)
  656. // {
  657. //  Scheduler::instance().schedule(h, p, delay_);
  658. //  numtx_ = 1;
  659. // }