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

通讯编程

开发平台:

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.  * Ported 2006 from ns-2.29 
  38.  * by Federico Maguolo, Nicola Baldo and Simone Merlin 
  39.  * (SIGNET lab, University of Padova, Department of Information Engineering)
  40.  *
  41.  */
  42. #include <float.h>
  43. #include "wireless-channelpa.h"
  44. #include "wireless-phymr.h"
  45. // Wireless extensions
  46. // Time interval for updating a position of a node in the X-List
  47. // (can be adjusted by the user, depending on the nodes mobility). /* VAL NAUMOV */
  48. #define XLIST_POSITION_UPDATE_INTERVAL 1.0 //seconds
  49. static class PAWirelessChannelClass : public TclClass {
  50. public:
  51.         PAWirelessChannelClass() : TclClass("Channel/WirelessChannel/PowerAware") {}
  52.         TclObject* create(int, const char*const*) {
  53.                 return (new PAWirelessChannel);
  54.         }
  55. } class_pa_Wireless_channel;
  56. class MobileNode;
  57. // double PAWirelessChannel::highestAntennaZ_ = -1; // i.e., uninitialized
  58. // double PAWirelessChannel::distCST_ = -1;
  59. PAWirelessChannel::PAWirelessChannel() 
  60. : Channel(), numNodes_(0), 
  61.   xListHead_(NULL), sorted_(0) 
  62. {
  63. bind("distInterference_", &distInterference_);
  64. }
  65. int PAWirelessChannel::command(int argc, const char*const* argv)
  66. {
  67. if (argc == 3) {
  68. TclObject *obj;
  69. if( (obj = TclObject::lookup(argv[2])) == 0) {
  70. fprintf(stderr, "%s lookup failedn", argv[1]);
  71. return TCL_ERROR;
  72. }
  73. if (strcmp(argv[1], "add-node") == 0) {
  74. addNodeToList((MobileNode*) obj);
  75. return TCL_OK;
  76. }
  77. else if (strcmp(argv[1], "remove-node") == 0) {
  78. removeNodeFromList((MobileNode*) obj);
  79. return TCL_OK;
  80. }
  81. }
  82. return Channel::command(argc, argv);
  83. }
  84. void
  85. PAWirelessChannel::sendUp(Packet* p, Phy *tifp)
  86. {
  87. Scheduler &s = Scheduler::instance();
  88. Phy *rifp = ifhead_.lh_first;
  89. Node *tnode = tifp->node();
  90. Node *rnode = 0;
  91. Packet *newp;
  92. double propdelay = 0.0;
  93. struct hdr_cmn *hdr = HDR_CMN(p);
  94. // Unused - see comments in wireless-channelpa.h
  95. //       /* list-based improvement */
  96. //          if(highestAntennaZ_ == -1) {
  97. //                  fprintf(stdout, "channel.cc:sendUp - Calc highestAntennaZ_ and distCST_n");
  98. //                  calcHighestAntennaZ(tifp);
  99. //                  fprintf(stdout, "highestAntennaZ_ = %0.1f,  distCST_ = %0.1fn", highestAntennaZ_, distCST_);
  100. //          }
  101.  hdr->direction() = hdr_cmn::UP;
  102.  // still keep grid-keeper around ??
  103.  if (GridKeeper::instance()) {
  104.     int i;
  105.     GridKeeper* gk = GridKeeper::instance();
  106.     int size = gk->size_; 
  107.     
  108.     MobileNode **outlist = new MobileNode *[size];
  109.  
  110.             int out_index = gk->get_neighbors((MobileNode*)tnode,
  111.          outlist);
  112.     for (i=0; i < out_index; i ++) {
  113.   newp = p->copy();
  114.   rnode = outlist[i];
  115.   propdelay = get_pdelay(tnode, rnode);
  116.   rifp = (rnode->ifhead()).lh_first; 
  117.   for(; rifp; rifp = rifp->nextnode()){
  118.   if (rifp->channel() == this){
  119.  s.schedule(rifp, newp, propdelay); 
  120.  break;
  121.   }
  122.   }
  123.       }
  124.     delete [] outlist; 
  125.  
  126.  } else { // use list-based improvement
  127.  
  128.  MobileNode *mtnode = (MobileNode *) tnode;
  129.  MobileNode **affectedNodes;// **aN;
  130.  int numAffectedNodes = -1;
  131.  int i;
  132.  
  133.  if(!sorted_){
  134.  sortLists();
  135.  }
  136.  
  137.  affectedNodes = getAffectedNodes(mtnode, distInterference_, &numAffectedNodes);
  138.  for (i=0; i < numAffectedNodes; i++) {
  139.  rnode = affectedNodes[i];
  140.  
  141.  if(rnode == tnode)
  142.  continue;
  143.  
  144.  newp = p->copy();
  145.  
  146.  propdelay = get_pdelay(tnode, rnode);
  147.  
  148.  rifp = (rnode->ifhead()).lh_first;
  149.  for(; rifp; rifp = rifp->nextnode()){
  150.  s.schedule(rifp, newp, propdelay);
  151.  }
  152.  }
  153.  delete [] affectedNodes;
  154.  }
  155.  Packet::free(p);
  156. }
  157. void
  158. PAWirelessChannel::addNodeToList(MobileNode *mn)
  159. {
  160. MobileNode *tmp;
  161. // create list of mobilenodes for this channel
  162. if (xListHead_ == NULL) {
  163. fprintf(stderr, "INITIALIZE THE LIST xListHeadn");
  164. xListHead_ = mn;
  165. xListHead_->nextX_ = NULL;
  166. xListHead_->prevX_ = NULL;
  167. } else {
  168. for (tmp = xListHead_; tmp->nextX_ != NULL; tmp=tmp->nextX_);
  169. tmp->nextX_ = mn;
  170. mn->prevX_ = tmp;
  171. mn->nextX_ = NULL;
  172. }
  173. numNodes_++;
  174. }
  175. void
  176. PAWirelessChannel::removeNodeFromList(MobileNode *mn) {
  177. MobileNode *tmp;
  178. // Find node in list
  179. for (tmp = xListHead_; tmp->nextX_ != NULL; tmp=tmp->nextX_) {
  180. if (tmp == mn) {
  181. if (tmp == xListHead_) {
  182. xListHead_ = tmp->nextX_;
  183. if (tmp->nextX_ != NULL)
  184. tmp->nextX_->prevX_ = NULL;
  185. } else if (tmp->nextX_ == NULL) 
  186. tmp->prevX_->nextX_ = NULL;
  187. else {
  188. tmp->prevX_->nextX_ = tmp->nextX_;
  189. tmp->nextX_->prevX_ = tmp->prevX_;
  190. }
  191. numNodes_--;
  192. return;
  193. }
  194. }
  195. fprintf(stderr, "Channel: node not found in listn");
  196. }
  197. void
  198. PAWirelessChannel::sortLists(void) {
  199. bool flag = true;
  200. MobileNode *m, *q;
  201. sorted_ = true;
  202. fprintf(stderr, "SORTING LISTS ...");
  203. /* Buble sort algorithm */
  204. // SORT x-list
  205. while(flag) {
  206. flag = false;
  207. m = xListHead_;
  208. while (m != NULL){
  209. if(m->nextX_ != NULL)
  210. if ( m->X() > m->nextX_->X() ){
  211. flag = true;
  212. //delete_after m;
  213. q = m->nextX_;
  214. m->nextX_ = q->nextX_;
  215. if (q->nextX_ != NULL)
  216. q->nextX_->prevX_ = m;
  217.     
  218. //insert_before m;
  219. q->nextX_ = m;
  220. q->prevX_ = m->prevX_;
  221. m->prevX_ = q;
  222. if (q->prevX_ != NULL)
  223. q->prevX_->nextX_ = q;
  224. // adjust Head of List
  225. if(m == xListHead_) 
  226. xListHead_ = m->prevX_;
  227. }
  228. m = m -> nextX_;
  229. }
  230. }
  231. fprintf(stderr, "DONE!n");
  232. }
  233. void
  234. PAWirelessChannel::updateNodesList(class MobileNode *mn, double oldX) {
  235. MobileNode* tmp;
  236. double X = mn->X();
  237. bool skipX=false;
  238. if(!sorted_) {
  239. sortLists();
  240. return;
  241. }
  242. /* xListHead cannot be NULL here (they are created during creation of mobilenode) */
  243. /***  DELETE ***/
  244. // deleting mn from x-list
  245. if(mn->nextX_ != NULL) {
  246. if(mn->prevX_ != NULL){
  247. if((mn->nextX_->X() >= X) && (mn->prevX_->X() <= X)) skipX = true; // the node doesn't change its position in the list
  248. else{
  249. mn->nextX_->prevX_ = mn->prevX_;
  250. mn->prevX_->nextX_ = mn->nextX_;
  251. }
  252. }
  253. else{
  254. if(mn->nextX_->X() >= X) skipX = true; // skip updating the first element
  255. else{
  256. mn->nextX_->prevX_ = NULL;
  257. xListHead_ = mn->nextX_;
  258. }
  259. }
  260. }
  261. else if(mn->prevX_ !=NULL){
  262. if(mn->prevX_->X() <= X) skipX = true; // skip updating the last element
  263. else mn->prevX_->nextX_ = NULL;
  264. }
  265. if ((mn->prevX_ == NULL) && (mn->nextX_ == NULL)) skipX = true; //skip updating if only one element in list
  266. /*** INSERT ***/
  267. //inserting mn in x-list
  268. if(!skipX){
  269. if(X > oldX){
  270. for(tmp = mn; tmp->nextX_ != NULL && tmp->nextX_->X() < X; tmp = tmp->nextX_);
  271. //fprintf(stdout,"Scanning the element addr %d X=%0.f, next addr %d X=%0.fn", tmp, tmp->X(), tmp->nextX_, tmp->nextX_->X());
  272. if(tmp->nextX_ == NULL) { 
  273. //fprintf(stdout, "tmp->nextX_ is NULLn");
  274. tmp->nextX_ = mn;
  275. mn->prevX_ = tmp;
  276. mn->nextX_ = NULL;
  277. else{ 
  278. //fprintf(stdout, "tmp->nextX_ is not NULL, tmp->nextX_->X()=%0.fn", tmp->nextX_->X());
  279. mn->prevX_ = tmp->nextX_->prevX_;
  280. mn->nextX_ = tmp->nextX_;
  281. tmp->nextX_->prevX_ = mn;  
  282. tmp->nextX_ = mn;
  283. }
  284. else{
  285. for(tmp = mn; tmp->prevX_ != NULL && tmp->prevX_->X() > X; tmp = tmp->prevX_);
  286. //fprintf(stdout,"Scanning the element addr %d X=%0.f, prev addr %d X=%0.fn", tmp, tmp->X(), tmp->prevX_, tmp->prevX_->X());
  287. if(tmp->prevX_ == NULL) {
  288. //fprintf(stdout, "tmp->prevX_ is NULLn");
  289. tmp->prevX_ = mn;
  290. mn->nextX_ = tmp;
  291. mn->prevX_ = NULL;
  292. xListHead_ = mn;
  293. else{
  294. //fprintf(stdout, "tmp->prevX_ is not NULL, tmp->prevX_->X()=%0.fn", tmp->prevX_->X());
  295. mn->nextX_ = tmp->prevX_->nextX_;
  296. mn->prevX_ = tmp->prevX_;
  297. tmp->prevX_->nextX_ = mn;  
  298. tmp->prevX_ = mn;
  299. }
  300. }
  301. }
  302. }
  303. MobileNode **
  304. PAWirelessChannel::getAffectedNodes(MobileNode *mn, double radius,
  305.   int *numAffectedNodes)
  306. {
  307. double xmin, xmax, ymin, ymax;
  308. int n = 0;
  309. MobileNode *tmp, **list, **tmpList;
  310. if (xListHead_ == NULL) {
  311. *numAffectedNodes=-1;
  312. fprintf(stderr, "xListHead_ is NULL when trying to send!!!n");
  313. return NULL;
  314. }
  315. xmin = mn->X() - radius;
  316. xmax = mn->X() + radius;
  317. ymin = mn->Y() - radius;
  318. ymax = mn->Y() + radius;
  319. // First allocate as much as possibly needed
  320. tmpList = new MobileNode*[numNodes_];
  321. for(tmp = xListHead_; tmp != NULL; tmp = tmp->nextX_) tmpList[n++] = tmp;
  322. for(int i = 0; i < n; ++i)
  323. if(tmpList[i]->speed()!=0.0 && (Scheduler::instance().clock() -
  324. tmpList[i]->getUpdateTime()) > XLIST_POSITION_UPDATE_INTERVAL )
  325. tmpList[i]->update_position();
  326. n=0;
  327. for(tmp = mn; tmp != NULL && tmp->X() >= xmin; tmp=tmp->prevX_)
  328. if(tmp->Y() >= ymin && tmp->Y() <= ymax){
  329. tmpList[n++] = tmp;
  330. }
  331. for(tmp = mn->nextX_; tmp != NULL && tmp->X() <= xmax; tmp=tmp->nextX_){
  332. if(tmp->Y() >= ymin && tmp->Y() <= ymax){
  333. tmpList[n++] = tmp;
  334. }
  335. }
  336. list = new MobileNode*[n];
  337. memcpy(list, tmpList, n * sizeof(MobileNode *));
  338. delete [] tmpList;
  339.          
  340. *numAffectedNodes = n;
  341. return list;
  342. }
  343.  
  344. // Unused - see comments in wireless-channelpa.h
  345. //
  346. // /* Only to be used with mobile nodes (WirelessPhy).
  347. //  * NS-2 at its current state support only a flat (non 3D) movement of nodes,
  348. //  * so we assume antenna heights do not change for the dureation of
  349. //  * a simulation.
  350. //  * Another assumption - all nodes have the same wireless interface, so that
  351. //  * the maximum distance, corresponding to CST (at max transmission power 
  352. //  * level) stays the same for all nodes.
  353. //  */
  354. // void
  355. // PAWirelessChannel::calcHighestAntennaZ(Phy *tifp)
  356. // {
  357. //        double highestZ = 0;
  358. //        Phy *n;
  359.  
  360. //        for(n = ifhead_.lh_first; n; n = n->nextchnl()) {
  361. //                    if(((PAWirelessPhy *)n)->getAntennaZ() > highestZ)
  362. //                                highestZ = ((PAWirelessPhy *)n)->getAntennaZ();
  363. //        }
  364.  
  365. //        highestAntennaZ_ = highestZ;
  366. //        PAWirelessPhy *wifp = (PAWirelessPhy *)tifp;
  367. //        distCST_ = wifp->getDist(wifp->getCSThresh(), wifp->getPt(), 1.0, 1.0,
  368. //  highestZ , highestZ, wifp->getL(),
  369. //  wifp->getLambda());       
  370. // }
  371. double
  372. PAWirelessChannel::get_pdelay(Node* tnode, Node* rnode)
  373. {
  374. // Scheduler &s = Scheduler::instance();
  375. MobileNode* tmnode = (MobileNode*)tnode;
  376. MobileNode* rmnode = (MobileNode*)rnode;
  377. double propdelay = 0;
  378. propdelay = tmnode->propdelay(rmnode);
  379. assert(propdelay >= 0.0);
  380. if (propdelay == 0.0) {
  381. /* if the propdelay is 0 b/c two nodes are on top of 
  382.    each other, move them slightly apart -dam 7/28/98 */
  383. propdelay = 2 * DBL_EPSILON;
  384. //printf ("propdelay 0: %d->%d at %fn",
  385. // tmnode->address(), rmnode->address(), s.clock());
  386. }
  387. return propdelay;
  388. }