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

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Network model with Wireless layout
  3.  *
  4.  */
  5. #include <stdlib.h>
  6. #include <math.h>
  7. #include <float.h>
  8. #include "random.h"
  9. #include "view.h"
  10. #include "netview.h"
  11. #include "animation.h"
  12. #include "queue.h"
  13. #include "edge.h"
  14. #include "node.h"
  15. #include "agent.h"
  16. #include "sincos.h"
  17. #include "state.h"
  18. #include "packet.h"
  19. #include "wnetmodel.h"
  20. class WirelessNetworkModelClass : public TclClass {
  21. public:
  22.   WirelessNetworkModelClass() : TclClass("NetworkModel/Wireless") {}
  23.   TclObject* create(int argc, const char*const* argv) {
  24.     if (argc < 5) 
  25.       return 0;
  26.     return (new WirelessNetModel(argv[4]));
  27.   }
  28. } wirelessnetworkmodel_class;
  29. WirelessNetModel::WirelessNetModel(const char *animator) :
  30.   NetModel(animator), edges_(0) {
  31.   bind("Wpxmax_", &pxmax_);
  32.   bind("Wpymax_", &pymax_);
  33. }
  34. WirelessNetModel::~WirelessNetModel() {
  35. }
  36. int WirelessNetModel::command(int argc, const char *const *argv) {
  37. if (argc == 2) {
  38. if (strcmp(argv[1], "layout") == 0) {
  39. /*
  40.  * <net> layout
  41.  */
  42. layout();
  43. NetModel::set_wireless();
  44. return (TCL_OK);
  45. }
  46. if (argc == 5) {
  47. if (strcmp(argv[1], "select-pkt") == 0) {
  48. NetModel::selectPkt(atoi(argv[2]), atoi(argv[3]), atoi(argv[4]));
  49. return (TCL_OK);
  50. }
  51. return (NetModel::command(argc, argv));
  52. }
  53. void WirelessNetModel::layout()
  54. {
  55. Node *n;
  56. for (n = nodes_; n != 0; n = n->next_)
  57.                 for (Edge* e = n->links(); e != 0; e = e->next_)  
  58.                         placeEdge(e, n); 
  59. nymax_ = pymax_ ;
  60. nymin_ = 0 ;
  61. }
  62. void WirelessNetModel::BoundingBox(BBox& bb)
  63. {                       
  64.         bb.xmin = bb.ymin = 0;
  65. bb.xmax = pxmax_;
  66. bb.ymax = pymax_;
  67.         for (Animation* a = drawables_; a != 0; a = a->next())
  68.                 a->merge(bb);
  69. }
  70. void WirelessNetModel::update(double now)
  71. {               
  72.         Animation *a, *n;
  73.         for (a = animations_; a != 0; a = n) {
  74.                 n = a->next();
  75.                 a->update(now);
  76.         }
  77. for (Node* x = nodes_; x != 0; x = x->next_) {
  78. x->update(now);
  79. moveNode(x);
  80. }
  81.         
  82.         /*
  83.          * Draw all animations and drawables on display to reflect
  84.          * current time.
  85.          */
  86.         now_ = now;
  87.         for (View* p = views_; p != 0; p = p->next_) {
  88.                 p->draw(); 
  89.         }               
  90. }       
  91. void WirelessNetModel::moveNode(Node *n)
  92. {
  93.         for (Edge *e = n->links(); e != 0; e = e->next_) {
  94.                 e->unmark();
  95.                 placeEdge(e, n);
  96.                 Node *dst = e->neighbor();
  97.                 // Should place reverse edges too
  98.                 Edge *p = dst->find_edge(n->num());
  99.                 if (p != NULL) {
  100.                         p->unmark();
  101.                         placeEdge(p, dst);
  102.                 }
  103.         }
  104.         for (Agent *a = n->agents(); a != NULL; a = a->next()) {
  105.                 a->mark(0), a->angle(NO_ANGLE);
  106.                 placeAgent(a, n);
  107.         }
  108. }
  109. // we need to place edge using the edge's real angle, instead of the
  110. // given one
  111. void WirelessNetModel::placeEdge(Edge* e, Node* src) const
  112. {
  113.         if (e->marked() == 0) {
  114.                 double hyp, dx, dy;
  115.                 Node *dst = e->neighbor();
  116.                 dx=dst->x()-src->x();
  117.                 dy=dst->y()-src->y();
  118.                 hyp=sqrt(dx*dx + dy*dy);
  119.            //   e->setAngle(atan2(dy,dx));
  120.                 double x0 = src->x() + src->size() * (dx/hyp) * .75;
  121.                 double y0 = src->y() + src->size() * (dy/hyp) * .75;
  122.                 double x1 = dst->x() - dst->size() * (dx/hyp) * .75;
  123.                 double y1 = dst->y() - dst->size() * (dy/hyp) * .75;
  124.                 e->place(x0, y0, x1, y1);
  125.                 /* Place the queue here too.  */
  126.                 EdgeHashNode *h = lookupEdgeHashNode(e->src(), e->dst());
  127. if (h != 0) {
  128.                     if (h->queue != 0)
  129.                         h->queue->place(e->size(), e->x0(), e->y0());
  130. }
  131.                 e->mark();
  132.         }
  133. }
  134. //----------------------------------------------------------------------
  135. // void 
  136. // WirelessNetModel::handle(const TraceEvent& e, double now, int direction)
  137. //   - packet handling stuff. use new packet
  138. //   - Given a trace event parses the event type and adds wireless
  139. //     extensions
  140. //----------------------------------------------------------------------
  141. void 
  142. WirelessNetModel::handle(const TraceEvent& e, double now, int direction) {
  143.   EdgeHashNode *ehn;
  144.   Edge* newEdge ;
  145.   Node *src, *dst, * n;
  146.   View * v;
  147.   switch (e.tt) {
  148.     case 'a': // Agent
  149.       NetModel::handle(e, now, direction);
  150.       // recalculate bounding box so that all agents will 
  151.       // be within view
  152.       for (v = views_; v != 0; v = v->next_) {
  153.         v->redrawModel();
  154.       }
  155.       break;
  156.     case 'n': // Node
  157.       NetModel::handle(e, now, direction);
  158.       // no need to reposition node if the node event
  159.       // is only for color change or label change
  160.       if ((strncmp(e.ne.node.state, "COLOR", 5) == 0) ||
  161.           (strncmp(e.ne.node.state, "DLABEL", 6) == 0)) {
  162.         return;
  163.       }
  164.       // placing the node position
  165.       n = lookupNode(e.ne.src);
  166.       if (n == 0)
  167.         return;
  168.       n->place(e.ne.x,e.ne.y);
  169.       n->placeorig(e.ne.x,e.ne.y);
  170.       n->setstart(now);
  171.       n->setend(e.ne.stoptime+now);
  172.       n->setvelocity(e.ne.x_vel_, e.ne.y_vel_);
  173.       moveNode(n);
  174.       break;
  175.   
  176.     case 'd':
  177.     case 'r':
  178.       src = lookupNode(e.pe.src);
  179.       if  (!src) {
  180.         fprintf(stderr,"node %d is not defined... ", e.pe.src);
  181.         break;
  182.       }
  183.       if (!(dst = lookupNode(e.pe.dst))) {
  184.         if (e.pe.dst != -1) { // broadcasting address
  185.           fprintf(stderr,"node %d is not defined... ", e.pe.dst);
  186.           break;
  187.         }
  188.       }
  189.       // Set node color based upon energy levels
  190.       /*
  191.       switch (e.pe.pkt.energy) {
  192.         case 3:
  193.           src->color("green");
  194.           break; 
  195.         case 2:
  196.           src->color("yellow");
  197.           break; 
  198.         case 1:
  199.           src->color("red");
  200.           break;
  201.         case 0:
  202.         src->color("black");
  203.         break;
  204.       } 
  205.       */
  206.       NetModel::handle(e, now, direction);
  207.       break;
  208.     case 'h':
  209.     case '+':
  210.     case '_':
  211.       if ( !(src= lookupNode(e.pe.src)) ) {
  212.         fprintf(stderr, "node %d is not defined... ", e.pe.src);
  213.         break;
  214.       } else { 
  215.         src->size(src->nsize());
  216.       }
  217.       if ( !(dst= lookupNode(e.pe.dst)) ) {
  218.         if (e.pe.dst != -1) { //broadcasting address
  219.           fprintf(stderr,"node %d is not defined... ", e.pe.dst);
  220.           break;
  221.         } else {
  222.           /*
  223.           if (e.pe.pkt.energy == 3) src->color("green");
  224.           if (e.pe.pkt.energy == 2) src->color("yellow");
  225.           if (e.pe.pkt.energy == 1) src->color("red");
  226.           if (e.pe.pkt.energy == 0) src->color("black");
  227.           */
  228.           NetModel::handle(e, now, direction);
  229.           break; 
  230.         }
  231.       } else {
  232.         dst->size(dst->nsize());
  233.       }
  234.       /*
  235.       if (e.pe.pkt.energy == 3) src->color("green");
  236.       if (e.pe.pkt.energy == 2) src->color("yellow");
  237.       if (e.pe.pkt.energy == 1) src->color("red");
  238.       if (e.pe.pkt.energy == 0) src->color("black");
  239.       */
  240.       // When a wireless packet is transferred then
  241.       // lookup to see if an edge has been created for that destination
  242.       ehn = lookupEdgeHashNode(e.pe.src, e.pe.dst);
  243.       if (ehn == 0 ) {
  244.         // if not then create one dynamically
  245.         //double bw = 1000000;
  246.         //double delay = 1.0000000000000008e-02;
  247.         double bw = 10.0;
  248.         double delay = 10.0;
  249.         double length = 0;
  250. // why it is 3? 
  251.         double dsize = 3;
  252.         double angle = 8.275783586691418e-313;
  253.         newEdge = new Edge(src, dst, dsize, bw, delay, length, angle, 1);
  254.         newEdge->init_color("black");
  255.         newEdge->visible(0);
  256.         enterEdge(newEdge);
  257.         newEdge->Animation::insert(&drawables_);
  258.         src->add_link(newEdge);
  259.       }
  260.       NetModel::handle(e, now, direction);
  261.       break;  
  262.     case 'l':
  263.       if ((strncmp(e.le.link.state, "in", 2) == 0) || 
  264.           (strncmp(e.le.link.state, "out", 3) == 0)) {
  265.         
  266.          // wireless process: dynamic link
  267.         if (strncmp(e.le.link.state, "in", 2)==0) {
  268.           if (direction==FORWARDS) {
  269.             Tcl& tcl = Tcl::instance();
  270.             tcl.evalf("%s add_link {%s}", name(), e.image);
  271.           } else {
  272.             // remove the link
  273.             removeLink(e);
  274.           } 
  275.         } 
  276.         if (strncmp(e.le.link.state, "out", 3)==0) {
  277.           if (direction==FORWARDS) {
  278.             removeLink(e);
  279.           } else {
  280.             Tcl& tcl = Tcl::instance();
  281.             tcl.evalf("%s add_link {%s}", name(), e.image);
  282.           }
  283.         }
  284.       } else {
  285.         NetModel::handle(e, now, direction);
  286.       }      
  287.       break;
  288.     default:
  289.       NetModel::handle(e, now, direction);
  290.       break;
  291.   }
  292. }
  293. void WirelessNetModel::addToEdgePool(Edge* e)
  294. {
  295.     WEdgeList* p = new WEdgeList;
  296.     p->wEdge = e;
  297.     p->next = edges_ ;
  298.     edges_ = p;
  299. }
  300. Edge* WirelessNetModel::removeFromEdgePool()
  301. {
  302.     if (edges_) {
  303.         WEdgeList* p = edges_ ;
  304.         edges_ = p->next;
  305. Edge* w = p->wEdge ;
  306.         delete p ;
  307. return w ;
  308.     }
  309.     else return (Edge*) 0 ;
  310. }
  311. //----------------------------------------------------------------------
  312. // void 
  313. // WirelessNetModel::removeLink(const TraceEvent& e)
  314. //----------------------------------------------------------------------
  315. void WirelessNetModel::removeLink(const TraceEvent& e) {
  316.   int src = e.le.src;
  317.   int dst = e.le.dst;
  318.   EdgeHashNode * h = lookupEdgeHashNode(src, dst);
  319.   EdgeHashNode * g = lookupEdgeHashNode(dst, src);
  320.   if (h == 0 || g == 0) {
  321.     // h,g = 0 or h,g !=0
  322.     return;
  323.   }
  324.                 
  325.   Edge * e1 = h->edge; 
  326.   Edge * e2 = g->edge;
  327.            
  328.   removeEdge(e1);
  329.   removeEdge(e2);
  330.   e1->detach();
  331.   e2->detach();
  332.  
  333.   Node* srcnode = e1->start();
  334.   Node* dstnode = e2->start();
  335.   // it is a duplex by default
  336.   srcnode->delete_link(e1);
  337.   dstnode->delete_link(e2);
  338.                         
  339.   delete e1;
  340.   delete e2;
  341. }
  342. void WirelessNetModel::removeLink(int src, int dst)
  343. {
  344.                     EdgeHashNode *h = lookupEdgeHashNode(src, dst);
  345.                     if (h == 0 ) return;
  346.                
  347.                     Edge* e1 = h->edge; 
  348.     if (e1 == 0) return ;
  349.            
  350.     e1->dec_usage();
  351.     if (e1->used() != 0) return;
  352.                     removeEdge(e1);
  353.                     e1->detach();
  354.  
  355.                     Node* srcnode = e1->start();
  356.                     srcnode->delete_link(e1);
  357.                         
  358.                     delete e1;
  359. }