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

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 1991,1993 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  * This product includes software developed by the Computer Systems
  16.  * Engineering Group at Lawrence Berkeley Laboratory.
  17.  * 4. Neither the name of the University nor of the Laboratory may be used
  18.  *    to endorse or promote products derived from this software without
  19.  *    specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  * @(#) $Header: /cvsroot/nsnam/nam-1/packet.cc,v 1.33 2005/01/24 23:30:41 haldar Exp $ (LBL)
  34.  */
  35. #ifdef WIN32
  36. #include <windows.h>
  37. #endif
  38. #include "transform.h"
  39. #include "view.h"
  40. #include "netview.h"
  41. #include "psview.h"
  42. #include "edge.h"
  43. #include "node.h"
  44. #include "packet.h"
  45. //<zheng: +++>
  46. #include "parser.h"
  47. #define MIN_RANGE_WPAN 3
  48. //</zheng: +++>
  49. int Packet::count_ = 0;
  50. BPacket::BPacket(double  x, double y ,const PacketAttr& p , double now, 
  51.  long offset, int direction, double duration, double radius )
  52. : Animation(now, offset) 
  53. {
  54. x_ = x ;
  55. y_ = y ;
  56. pkt_ = p ;
  57. if (direction == FORWARDS ) {
  58. //radius_ = MIN_RANGE ; //zheng: ---
  59. radius_ = (ParseTable::nam4wpan)?MIN_RANGE_WPAN:MIN_RANGE ; //zheng: +++
  60. start_ = now ;
  61. if (ParseTable::wpan_bradius < 0) 
  62. ParseTable::wpan_bradius = (int)radius; //zheng: +++
  63. } else {
  64. radius_ = MAX_RANGE ; // BACKWARD
  65. if (ParseTable::nam4wpan) //zheng: +++
  66. if (ParseTable::wpan_bradius > 0) radius_ = ParseTable::wpan_bradius; //zheng: +++
  67. start_ = now - duration;
  68. }
  69. direction_ = direction;
  70. aType_ = BPACKET;
  71. duration_ = duration;
  72. max_radius_ = radius;
  73. if (ParseTable::nam4wpan) //zheng: +++
  74. if (ParseTable::wpan_bradius > 0) max_radius_ = ParseTable::wpan_bradius; //zheng: +++
  75. }
  76. void BPacket::draw(View* nv, double now) {
  77. nv->circle(x_, y_,radius_,paint_);
  78. }
  79. void BPacket::update(double now)
  80. {
  81. curTime_ = now;
  82. update_bb();
  83. if (now < start_ || now > start_ + duration_)
  84. delete this;
  85. }
  86. void BPacket::update_bb()
  87. {
  88. // radius_ starts at MIN_RANGE, moves to MAX_RANGE over duration_
  89. //radius_ = ((curTime_ - start_) / duration_) * (max_radius_-MIN_RANGE) //zheng: ---
  90. // + MIN_RANGE; //zheng: ---
  91. radius_ = ((curTime_ - start_) / duration_) * (max_radius_-((ParseTable::nam4wpan)?MIN_RANGE_WPAN:MIN_RANGE)) + ((ParseTable::nam4wpan)?MIN_RANGE_WPAN:MIN_RANGE); //zheng: +++
  92. }
  93. const char* BPacket::info() const
  94. {
  95. static char text[128];
  96. sprintf(text, "%s %d: %sn  Sent at %.6fn  %d bytesn",
  97. pkt_.type, pkt_.id, pkt_.convid, start_, pkt_.size);
  98. return (text);
  99. }
  100. const char* BPacket::getname() const
  101. {
  102. static char text[128];
  103. sprintf(text, "p");
  104. return (text);
  105. }
  106. void BPacket::monitor(Monitor *m, double , char *result, int )
  107. {
  108. if (((direction_ == FORWARDS) && (radius_ > MAX_RANGE)) ||
  109. //    ((direction_ == BACKWARDS) && (radius_ < MIN_RANGE)) ) { //zheng: ---
  110.     ((direction_ == BACKWARDS) && (radius_ < ((ParseTable::nam4wpan)?MIN_RANGE_WPAN:MIN_RANGE))) ) { //zheng: +++
  111. result[0] = '' ; 
  112. return ;
  113. }
  114. monitor_=m;
  115. sprintf(result, "%s %d: %sn Sent at %.6fn %d bytes",
  116. pkt_.type, pkt_.id, pkt_.convid, start_, pkt_.size);
  117. }
  118. MonState *BPacket::monitor_state()
  119. {
  120. /*return any state we wish the monitor to remember after we're gone*/
  121. MonState * ms = new MonState;
  122. ms->type = MON_PACKET;
  123. ms->pkt.id = pkt_.id;
  124. return ms;
  125. }
  126. int BPacket::inside(float px, float py) const
  127. {
  128. double dx =  ((double) px - x_ ) ;
  129. double dy =  ((double) py - y_ ) ;
  130. double d = sqrt(dx*dx + dy*dy) ;
  131. double dev = 1 ;
  132. if ((d <= (radius_ + dev)) && (d >= (radius_ - dev))) 
  133. return 1 ;
  134. else 
  135. return 0;
  136. }
  137. /*
  138.  * Compute the start and end points of the packet in the one dimensional
  139.  * time space [0, link delay].
  140.  */
  141. inline int Packet::EndPoints(double now, double& tail, double& head) const
  142. {
  143. int doarrow;
  144. if (now < ta_) {
  145. head = now - ts_;
  146. doarrow = 1;
  147. } else {
  148. head = edge_->delay();
  149. doarrow = 0;
  150. }
  151. double t = now - tx_;
  152. tail = (t <= ts_) ? 0. : t - ts_;
  153. tail = tail * edge_->reallength() / edge_->delay();
  154. head = head * edge_->reallength() / edge_->delay();
  155. return (doarrow);
  156. }
  157. Packet::Packet(Edge *e, const PacketAttr& p, double s, double txtime,
  158.        long offset ) : Animation(s, offset)
  159. {
  160. edge_ = e;
  161. e->AddPacket(this);
  162. pkt_ = p;
  163. ts_ = s;
  164. ta_ = s + e->delay();
  165. tx_ = txtime;
  166. arriving_ = 0;
  167. curTime_ = s;
  168. update_bb(); // Initial setup
  169. count_++;
  170. }
  171. Packet::~Packet()
  172. {
  173.   if (monitor_!=NULL) {
  174.     monitor_->delete_monitor_object(this);
  175.   }
  176.   count_--;
  177. }
  178. float Packet::distance(float /*x*/, float /*y*/) const 
  179. {
  180. // TODO
  181. return HUGE_VAL;
  182. }
  183. /*
  184.  * Compute the unit-space points for the packet polygon.
  185.  * Return number of points in polygon.
  186.  */
  187. int Packet::ComputePolygon(double now, float ax[5], float ay[5]) const
  188. {
  189. double tail, head;
  190. int doarrow = EndPoints(now, tail, head);
  191. double deltap = head - tail;
  192. const Transform& m = edge_->transform();
  193. double height = edge_->PacketHeight();
  194. //<zheng: +++>
  195. //not too large
  196. if (ParseTable::nam4wpan) {
  197. float tx,ty,tx2,ty2,td;
  198. tx = head;
  199. ty = 0.2 * height;
  200. m.imap(tx,ty);
  201. tx2 = head;
  202. ty2 = 0.2 * height + 1;
  203. m.imap(tx2,ty2);
  204. td = (tx2 - tx) * (tx2 - tx) + (ty2 - ty) * (ty2 - ty);
  205. td = pow(td, 0.5);
  206. if (height > td)
  207. height = td;
  208. }
  209. //</zheng: +++>
  210. float bot = 0.2 * height;
  211. float top = 1.2 * height;
  212. float mid = 0.7 * height;
  213. /*XXX put some air between packet and link */
  214. bot += 0.5 * height;
  215. top += 0.5 * height;
  216. mid += 0.5 * height;
  217. if (doarrow && deltap >= height) {
  218. /* packet with arrowhead */
  219. m.map(tail, bot, ax[0], ay[0]);
  220. m.map(tail, top, ax[1], ay[1]);
  221. m.map(head - 0.75 * height, top, ax[2], ay[2]);
  222. m.map(head, mid, ax[3], ay[3]);
  223. m.map(head - 0.75 * height, bot, ax[4], ay[4]);
  224. return (5);
  225. } else {
  226. /* packet without arrowhead */
  227. m.map(tail, bot, ax[0], ay[0]);
  228. m.map(tail, top, ax[1], ay[1]);
  229. m.map(head, top, ax[2], ay[2]);
  230. m.map(head, bot, ax[3], ay[3]);
  231. return (4);
  232. }
  233. }
  234. // Assuming that curTime_ is set correctly. This can be guaranteed since
  235. // the only way to adjust current time is through Packet::update().
  236. void Packet::update_bb()
  237. {
  238. int npts;
  239. float x[5], y[5];
  240. npts = ComputePolygon(curTime_, x, y);
  241. bb_.xmin = bb_.xmax = x[0];
  242. bb_.ymin = bb_.ymax = y[0];
  243. while (--npts > 0) {
  244. if (x[npts] < bb_.xmin)
  245. bb_.xmin = x[npts];
  246. if (x[npts] > bb_.xmax)
  247. bb_.xmax = x[npts];
  248. if (y[npts] < bb_.ymin)
  249. bb_.ymin = y[npts];
  250. if (y[npts] > bb_.ymax)
  251. bb_.ymax = y[npts];
  252. }
  253. }
  254. int Packet::inside(double now, float px, float py) const
  255. {
  256. int npts;
  257. float x[5], y[5];
  258. BBox bb;
  259. if (now < ts_ || now > ta_ + tx_)
  260. return (0);
  261. npts = ComputePolygon(now, x, y);
  262. bb.xmin = bb.xmax = x[0];
  263. bb.ymin = bb.ymax = y[0];
  264. while (--npts > 0) {
  265. if (x[npts] < bb.xmin)
  266. bb.xmin = x[npts];
  267. if (x[npts] > bb.xmax)
  268. bb.xmax = x[npts];
  269. if (y[npts] < bb.ymin)
  270. bb.ymin = y[npts];
  271. if (y[npts] > bb.ymax)
  272. bb.ymax = y[npts];
  273. }
  274. return bb.inside(px, py);
  275. }
  276. const char* Packet::info() const
  277. {
  278. static char text[128];
  279. sprintf(text, "%s %d: %sn  Sent at %.6fn  %d bytesn",
  280. pkt_.type, pkt_.id, pkt_.convid, ts_, pkt_.size);
  281. return (text);
  282. }
  283. const char* Packet::gettype() const
  284. {
  285. static char text[128];
  286. sprintf(text, "%s", pkt_.type);
  287. return (text);
  288. }
  289. const char* Packet::getfid() const
  290. {
  291. static char text[128];
  292. sprintf(text, "%s", pkt_.convid);
  293. return (text);
  294. }
  295. const char* Packet::getesrc() const
  296. {
  297. static char text[128];
  298. sprintf(text, "%d", pkt_.esrc);
  299. return (text);
  300. }
  301. const char* Packet::getedst() const
  302. {
  303. static char text[128];
  304. sprintf(text, "%d", pkt_.edst);
  305. return (text);
  306. }
  307. const char* Packet::getname() const
  308. {
  309. static char text[128];
  310. sprintf(text, "p");
  311. return (text);
  312. }
  313. void Packet::monitor(Monitor *m, double , char *result, int )
  314. {
  315.   monitor_=m;
  316.   sprintf(result, "%s %d: %sn Sent at %.6fn %d bytes",
  317.   pkt_.type, pkt_.id, pkt_.convid, ts_, pkt_.size);
  318. }
  319. MonState *Packet::monitor_state()
  320. {
  321.   /*return any state we wish the monitor to remember after we're gone*/
  322.   MonState *ms=new MonState;
  323.   ms->type=MON_PACKET;
  324.   ms->pkt.id=pkt_.id;
  325.   return ms;
  326. }
  327. void Packet::RearrangePoints(View *v, int npts, float x[5], float y[5]) const
  328. {
  329. x[4] = (int) x[0] + 1;
  330. v->map(x[2], y[2]);
  331. v->map(x[1], y[1]);
  332. x[2] = (int) x[1] + 1;
  333. if (npts == 5) {
  334. v->map(x[3], y[3]);
  335. x[3] = x[2];
  336. v->imap(x[3], y[3]);
  337. }
  338. v->imap(x[4], y[4]);
  339. v->imap(x[2], y[2]);
  340. }
  341. void Packet::CheckPolygon(View *v, int npts, float ax[5], float ay[5]) const
  342. {
  343. float x[5], y[5];
  344. memcpy((char *)x, (char *)ax, npts * sizeof(float));
  345. memcpy((char *)y, (char *)ay, npts * sizeof(float));
  346. v->map(x[4], y[4]);
  347. v->map(x[0], y[0]);
  348. if ((x[4] > x[0]) && ((int)x[4] - (int)x[0] < 1)) {
  349. RearrangePoints(v, npts, x, y);
  350. memcpy((char *)ax, (char *)x, npts * sizeof(float));
  351. memcpy((char *)ay, (char *)y, npts * sizeof(float));
  352. } else if ((x[0] > x[4]) && (x[0] - x[4] < 1)) {
  353. float tmp;
  354. tmp = x[0], x[0] = x[4], x[4] = tmp;
  355. tmp = x[1], x[1] = x[2], x[2] = tmp;
  356. RearrangePoints(v, npts, x, y);
  357. tmp = x[0], x[0] = x[4], x[4] = tmp;
  358. tmp = x[1], x[1] = x[2], x[2] = tmp;
  359. memcpy((char *)ax, (char *)x, npts * sizeof(float));
  360. memcpy((char *)ay, (char *)y, npts * sizeof(float));
  361. }
  362. }
  363. void Packet::draw(View* nv, double now) {
  364. /* XXX */
  365. if (now < ts_ || now > ta_ + tx_)
  366. return;
  367. float x[5], y[5];
  368. int npts;
  369. npts = ComputePolygon(now, x, y);
  370. //CheckPolygon(nv, npts, x, y);
  371. // Stupid way to decide fill/unfilled!
  372. //   if ((pkt_.attr & 0x100) == 0)
  373. //   nv->fill(x, y, npts, paint_);
  374. //   else 
  375. //   nv->polygon(x, y, npts, paint_);
  376. nv->fill(x, y, npts, paint_);
  377. /*XXX stupid way to get size!*/
  378. if (monitor_!=NULL)
  379.   monitor_->draw(nv, x[0], y[0]);
  380. }
  381. /*
  382. void Packet::draw(PSView* nv, double now) const
  383. {
  384. if (now < ts_ || now > ta_ + tx_)
  385. return;
  386. float x[5], y[5];
  387. int npts;
  388. npts = ComputePolygon(now, x, y);
  389. nv->fill(x, y, npts, paint_);
  390. }
  391. */
  392. void Packet::update(double now)
  393. {
  394.   if ((now > ta_)&&(arriving_==0))
  395.     {
  396.       /*If the packet has started to arrive, trigger any arrival event
  397. for the edge*/
  398.       edge_->arrive_packet(this, ta_);
  399.       arriving_=1;
  400.     }
  401.   if (now > ta_ + tx_ || now < ts_)
  402.     {
  403. /* XXX this does not belong here */
  404. #ifdef DEBUG
  405.       printf("packet %d arrived from %d at %dn", pkt_.id, edge_->src(), edge_->dst());
  406. #endif
  407.       /*remove this packet from the edge packet list*/
  408.       edge_->DeletePacket(this);
  409.       delete this;
  410.     } else {
  411.     // Current time has changed, update its bounding box
  412.     // XXX No clean way to keep its bb_ up-to-date. :(
  413.     curTime_ = now;
  414.     update_bb();
  415.     }
  416. }
  417. void Packet::position(float& x, float& y, double now) const
  418. {
  419.   float xs[5], ys[5];
  420.   int npts;
  421.   int i;
  422.   /*XXX using ComputePolygon is overkill*/
  423.   npts = ComputePolygon(now, xs, ys);
  424.   x=0;y=0;
  425.   for(i=0;i<npts;i++)
  426.     {
  427.       x+=xs[i];
  428.       y+=ys[i];
  429.     }
  430.   x/=npts;
  431.   y/=npts;
  432. }