packet.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:12k
- /*
- * Copyright (c) 1991,1993 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: /cvsroot/nsnam/nam-1/packet.cc,v 1.33 2005/01/24 23:30:41 haldar Exp $ (LBL)
- */
- #ifdef WIN32
- #include <windows.h>
- #endif
- #include "transform.h"
- #include "view.h"
- #include "netview.h"
- #include "psview.h"
- #include "edge.h"
- #include "node.h"
- #include "packet.h"
- //<zheng: +++>
- #include "parser.h"
- #define MIN_RANGE_WPAN 3
- //</zheng: +++>
- int Packet::count_ = 0;
- BPacket::BPacket(double x, double y ,const PacketAttr& p , double now,
- long offset, int direction, double duration, double radius )
- : Animation(now, offset)
- {
- x_ = x ;
- y_ = y ;
- pkt_ = p ;
- if (direction == FORWARDS ) {
- //radius_ = MIN_RANGE ; //zheng: ---
- radius_ = (ParseTable::nam4wpan)?MIN_RANGE_WPAN:MIN_RANGE ; //zheng: +++
- start_ = now ;
- if (ParseTable::wpan_bradius < 0)
- ParseTable::wpan_bradius = (int)radius; //zheng: +++
- } else {
- radius_ = MAX_RANGE ; // BACKWARD
- if (ParseTable::nam4wpan) //zheng: +++
- if (ParseTable::wpan_bradius > 0) radius_ = ParseTable::wpan_bradius; //zheng: +++
- start_ = now - duration;
- }
- direction_ = direction;
- aType_ = BPACKET;
- duration_ = duration;
- max_radius_ = radius;
- if (ParseTable::nam4wpan) //zheng: +++
- if (ParseTable::wpan_bradius > 0) max_radius_ = ParseTable::wpan_bradius; //zheng: +++
- }
- void BPacket::draw(View* nv, double now) {
- nv->circle(x_, y_,radius_,paint_);
- }
- void BPacket::update(double now)
- {
- curTime_ = now;
- update_bb();
- if (now < start_ || now > start_ + duration_)
- delete this;
- }
- void BPacket::update_bb()
- {
- // radius_ starts at MIN_RANGE, moves to MAX_RANGE over duration_
- //radius_ = ((curTime_ - start_) / duration_) * (max_radius_-MIN_RANGE) //zheng: ---
- // + MIN_RANGE; //zheng: ---
- radius_ = ((curTime_ - start_) / duration_) * (max_radius_-((ParseTable::nam4wpan)?MIN_RANGE_WPAN:MIN_RANGE)) + ((ParseTable::nam4wpan)?MIN_RANGE_WPAN:MIN_RANGE); //zheng: +++
- }
- const char* BPacket::info() const
- {
- static char text[128];
- sprintf(text, "%s %d: %sn Sent at %.6fn %d bytesn",
- pkt_.type, pkt_.id, pkt_.convid, start_, pkt_.size);
- return (text);
- }
- const char* BPacket::getname() const
- {
- static char text[128];
- sprintf(text, "p");
- return (text);
- }
- void BPacket::monitor(Monitor *m, double , char *result, int )
- {
- if (((direction_ == FORWARDS) && (radius_ > MAX_RANGE)) ||
- // ((direction_ == BACKWARDS) && (radius_ < MIN_RANGE)) ) { //zheng: ---
- ((direction_ == BACKWARDS) && (radius_ < ((ParseTable::nam4wpan)?MIN_RANGE_WPAN:MIN_RANGE))) ) { //zheng: +++
- result[0] = ' ' ;
- return ;
- }
-
- monitor_=m;
- sprintf(result, "%s %d: %sn Sent at %.6fn %d bytes",
- pkt_.type, pkt_.id, pkt_.convid, start_, pkt_.size);
- }
- MonState *BPacket::monitor_state()
- {
- /*return any state we wish the monitor to remember after we're gone*/
- MonState * ms = new MonState;
- ms->type = MON_PACKET;
- ms->pkt.id = pkt_.id;
- return ms;
- }
- int BPacket::inside(float px, float py) const
- {
- double dx = ((double) px - x_ ) ;
- double dy = ((double) py - y_ ) ;
- double d = sqrt(dx*dx + dy*dy) ;
- double dev = 1 ;
-
- if ((d <= (radius_ + dev)) && (d >= (radius_ - dev)))
- return 1 ;
- else
- return 0;
- }
- /*
- * Compute the start and end points of the packet in the one dimensional
- * time space [0, link delay].
- */
- inline int Packet::EndPoints(double now, double& tail, double& head) const
- {
- int doarrow;
- if (now < ta_) {
- head = now - ts_;
- doarrow = 1;
- } else {
- head = edge_->delay();
- doarrow = 0;
- }
- double t = now - tx_;
- tail = (t <= ts_) ? 0. : t - ts_;
- tail = tail * edge_->reallength() / edge_->delay();
- head = head * edge_->reallength() / edge_->delay();
- return (doarrow);
- }
- Packet::Packet(Edge *e, const PacketAttr& p, double s, double txtime,
- long offset ) : Animation(s, offset)
- {
- edge_ = e;
- e->AddPacket(this);
- pkt_ = p;
- ts_ = s;
- ta_ = s + e->delay();
- tx_ = txtime;
- arriving_ = 0;
- curTime_ = s;
- update_bb(); // Initial setup
- count_++;
- }
- Packet::~Packet()
- {
- if (monitor_!=NULL) {
- monitor_->delete_monitor_object(this);
- }
- count_--;
- }
- float Packet::distance(float /*x*/, float /*y*/) const
- {
- // TODO
- return HUGE_VAL;
- }
- /*
- * Compute the unit-space points for the packet polygon.
- * Return number of points in polygon.
- */
- int Packet::ComputePolygon(double now, float ax[5], float ay[5]) const
- {
- double tail, head;
- int doarrow = EndPoints(now, tail, head);
- double deltap = head - tail;
- const Transform& m = edge_->transform();
- double height = edge_->PacketHeight();
- //<zheng: +++>
- //not too large
- if (ParseTable::nam4wpan) {
- float tx,ty,tx2,ty2,td;
- tx = head;
- ty = 0.2 * height;
- m.imap(tx,ty);
- tx2 = head;
- ty2 = 0.2 * height + 1;
- m.imap(tx2,ty2);
- td = (tx2 - tx) * (tx2 - tx) + (ty2 - ty) * (ty2 - ty);
- td = pow(td, 0.5);
- if (height > td)
- height = td;
- }
- //</zheng: +++>
-
- float bot = 0.2 * height;
- float top = 1.2 * height;
- float mid = 0.7 * height;
- /*XXX put some air between packet and link */
- bot += 0.5 * height;
- top += 0.5 * height;
- mid += 0.5 * height;
-
- if (doarrow && deltap >= height) {
- /* packet with arrowhead */
- m.map(tail, bot, ax[0], ay[0]);
- m.map(tail, top, ax[1], ay[1]);
- m.map(head - 0.75 * height, top, ax[2], ay[2]);
- m.map(head, mid, ax[3], ay[3]);
- m.map(head - 0.75 * height, bot, ax[4], ay[4]);
- return (5);
- } else {
- /* packet without arrowhead */
- m.map(tail, bot, ax[0], ay[0]);
- m.map(tail, top, ax[1], ay[1]);
- m.map(head, top, ax[2], ay[2]);
- m.map(head, bot, ax[3], ay[3]);
- return (4);
- }
- }
- // Assuming that curTime_ is set correctly. This can be guaranteed since
- // the only way to adjust current time is through Packet::update().
- void Packet::update_bb()
- {
- int npts;
- float x[5], y[5];
- npts = ComputePolygon(curTime_, x, y);
- bb_.xmin = bb_.xmax = x[0];
- bb_.ymin = bb_.ymax = y[0];
- while (--npts > 0) {
- if (x[npts] < bb_.xmin)
- bb_.xmin = x[npts];
- if (x[npts] > bb_.xmax)
- bb_.xmax = x[npts];
- if (y[npts] < bb_.ymin)
- bb_.ymin = y[npts];
- if (y[npts] > bb_.ymax)
- bb_.ymax = y[npts];
- }
- }
- int Packet::inside(double now, float px, float py) const
- {
- int npts;
- float x[5], y[5];
- BBox bb;
- if (now < ts_ || now > ta_ + tx_)
- return (0);
- npts = ComputePolygon(now, x, y);
- bb.xmin = bb.xmax = x[0];
- bb.ymin = bb.ymax = y[0];
- while (--npts > 0) {
- if (x[npts] < bb.xmin)
- bb.xmin = x[npts];
- if (x[npts] > bb.xmax)
- bb.xmax = x[npts];
- if (y[npts] < bb.ymin)
- bb.ymin = y[npts];
- if (y[npts] > bb.ymax)
- bb.ymax = y[npts];
- }
- return bb.inside(px, py);
- }
- const char* Packet::info() const
- {
- static char text[128];
- sprintf(text, "%s %d: %sn Sent at %.6fn %d bytesn",
- pkt_.type, pkt_.id, pkt_.convid, ts_, pkt_.size);
- return (text);
- }
- const char* Packet::gettype() const
- {
- static char text[128];
- sprintf(text, "%s", pkt_.type);
- return (text);
- }
- const char* Packet::getfid() const
- {
- static char text[128];
- sprintf(text, "%s", pkt_.convid);
- return (text);
- }
- const char* Packet::getesrc() const
- {
- static char text[128];
- sprintf(text, "%d", pkt_.esrc);
- return (text);
- }
- const char* Packet::getedst() const
- {
- static char text[128];
- sprintf(text, "%d", pkt_.edst);
- return (text);
- }
- const char* Packet::getname() const
- {
- static char text[128];
- sprintf(text, "p");
- return (text);
- }
- void Packet::monitor(Monitor *m, double , char *result, int )
- {
- monitor_=m;
- sprintf(result, "%s %d: %sn Sent at %.6fn %d bytes",
- pkt_.type, pkt_.id, pkt_.convid, ts_, pkt_.size);
- }
- MonState *Packet::monitor_state()
- {
- /*return any state we wish the monitor to remember after we're gone*/
- MonState *ms=new MonState;
- ms->type=MON_PACKET;
- ms->pkt.id=pkt_.id;
- return ms;
- }
- void Packet::RearrangePoints(View *v, int npts, float x[5], float y[5]) const
- {
- x[4] = (int) x[0] + 1;
- v->map(x[2], y[2]);
- v->map(x[1], y[1]);
- x[2] = (int) x[1] + 1;
- if (npts == 5) {
- v->map(x[3], y[3]);
- x[3] = x[2];
- v->imap(x[3], y[3]);
- }
- v->imap(x[4], y[4]);
- v->imap(x[2], y[2]);
- }
- void Packet::CheckPolygon(View *v, int npts, float ax[5], float ay[5]) const
- {
- float x[5], y[5];
- memcpy((char *)x, (char *)ax, npts * sizeof(float));
- memcpy((char *)y, (char *)ay, npts * sizeof(float));
- v->map(x[4], y[4]);
- v->map(x[0], y[0]);
- if ((x[4] > x[0]) && ((int)x[4] - (int)x[0] < 1)) {
- RearrangePoints(v, npts, x, y);
- memcpy((char *)ax, (char *)x, npts * sizeof(float));
- memcpy((char *)ay, (char *)y, npts * sizeof(float));
- } else if ((x[0] > x[4]) && (x[0] - x[4] < 1)) {
- float tmp;
- tmp = x[0], x[0] = x[4], x[4] = tmp;
- tmp = x[1], x[1] = x[2], x[2] = tmp;
- RearrangePoints(v, npts, x, y);
- tmp = x[0], x[0] = x[4], x[4] = tmp;
- tmp = x[1], x[1] = x[2], x[2] = tmp;
- memcpy((char *)ax, (char *)x, npts * sizeof(float));
- memcpy((char *)ay, (char *)y, npts * sizeof(float));
- }
- }
- void Packet::draw(View* nv, double now) {
- /* XXX */
- if (now < ts_ || now > ta_ + tx_)
- return;
- float x[5], y[5];
- int npts;
- npts = ComputePolygon(now, x, y);
- //CheckPolygon(nv, npts, x, y);
- // Stupid way to decide fill/unfilled!
- // if ((pkt_.attr & 0x100) == 0)
- // nv->fill(x, y, npts, paint_);
- // else
- // nv->polygon(x, y, npts, paint_);
- nv->fill(x, y, npts, paint_);
- /*XXX stupid way to get size!*/
- if (monitor_!=NULL)
- monitor_->draw(nv, x[0], y[0]);
- }
- /*
- void Packet::draw(PSView* nv, double now) const
- {
- if (now < ts_ || now > ta_ + tx_)
- return;
- float x[5], y[5];
- int npts;
- npts = ComputePolygon(now, x, y);
- nv->fill(x, y, npts, paint_);
- }
- */
- void Packet::update(double now)
- {
- if ((now > ta_)&&(arriving_==0))
- {
- /*If the packet has started to arrive, trigger any arrival event
- for the edge*/
- edge_->arrive_packet(this, ta_);
- arriving_=1;
- }
- if (now > ta_ + tx_ || now < ts_)
- {
- /* XXX this does not belong here */
- #ifdef DEBUG
- printf("packet %d arrived from %d at %dn", pkt_.id, edge_->src(), edge_->dst());
- #endif
- /*remove this packet from the edge packet list*/
- edge_->DeletePacket(this);
- delete this;
- } else {
- // Current time has changed, update its bounding box
- // XXX No clean way to keep its bb_ up-to-date. :(
- curTime_ = now;
- update_bb();
- }
- }
- void Packet::position(float& x, float& y, double now) const
- {
- float xs[5], ys[5];
- int npts;
- int i;
- /*XXX using ComputePolygon is overkill*/
- npts = ComputePolygon(now, xs, ys);
- x=0;y=0;
- for(i=0;i<npts;i++)
- {
- x+=xs[i];
- y+=ys[i];
- }
- x/=npts;
- y/=npts;
- }