00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef lint
00036 static const char rcsid[] =
00037 "@(#) $Header: /nfs/jade/vint/CVSROOT/ns-2/link/delay.cc,v 1.26 1999/09/09 03:22:36 salehi Exp $ (LBL)";
00038 #endif
00039
00040 #include "delay.h"
00041 #include "mcast_ctrl.h"
00042 #include "ctrMcast.h"
00043
00044 static class LinkDelayClass : public TclClass {
00045 public:
00046 LinkDelayClass() : TclClass("DelayLink") {}
00047 TclObject* create(int , const char*const* ) {
00048 return (new LinkDelay);
00049 }
00050 } class_delay_link;
00051
00052 LinkDelay::LinkDelay() : dynamic_(0), itq_(0)
00053 {
00054 bind_bw("bandwidth_", &bandwidth_);
00055 bind_time("delay_", &delay_);
00056 }
00057
00058 int LinkDelay::command(int argc, const char*const* argv)
00059 {
00060 if (argc == 2) {
00061 if (strcmp(argv[1], "isDynamic") == 0) {
00062 dynamic_ = 1;
00063 itq_ = new PacketQueue();
00064 return TCL_OK;
00065 }
00066 } else if (argc == 6) {
00067 if (strcmp(argv[1], "pktintran") == 0) {
00068 int src = atoi(argv[2]);
00069 int grp = atoi(argv[3]);
00070 int from = atoi(argv[4]);
00071 int to = atoi(argv[5]);
00072 pktintran (src, grp);
00073 Tcl::instance().evalf("%s puttrace %d %d %d %d %d %d %d %d", name(), total_[0], total_[1], total_[2], total_[3], src, grp, from, to);
00074 return TCL_OK;
00075 }
00076 }
00077
00078 return Connector::command(argc, argv);
00079 }
00080
00081 void LinkDelay::recv(Packet* p, Handler* h)
00082 {
00083 double txt = txtime(p);
00084 Scheduler& s = Scheduler::instance();
00085 if (dynamic_) {
00086 Event* e = (Event*)p;
00087 e->time_= txt + delay_;
00088 itq_->enque(p);
00089 s.schedule(this, p, txt + delay_);
00090 } else {
00091 s.schedule(target_, p, txt + delay_);
00092 }
00093 s.schedule(h, &intr_, txt);
00094 }
00095
00096 void LinkDelay::send(Packet* p, Handler*)
00097 {
00098 target_->recv(p, (Handler*) NULL);
00099 }
00100
00101 void LinkDelay::reset()
00102 {
00103 Scheduler& s= Scheduler::instance();
00104
00105 if (itq_ && itq_->length()) {
00106 Packet *np;
00107
00108 while ((np = itq_->deque()) != 0) {
00109 s.cancel(np);
00110 drop(np);
00111 }
00112 }
00113 }
00114
00115 void LinkDelay::handle(Event* e)
00116 {
00117 Packet *p = itq_->deque();
00118 assert(p->time_ == e->time_);
00119 send(p, (Handler*) NULL);
00120 }
00121
00122 void LinkDelay::pktintran(int src, int group)
00123 {
00124 int reg = 1;
00125 int prune = 30;
00126 int graft = 31;
00127 int data = 0;
00128 for (int i=0; i<4; i++) {
00129 total_[i] = 0;
00130 }
00131
00132 if (! dynamic_)
00133 return;
00134
00135 int len = itq_->length();
00136 while (len) {
00137 len--;
00138 Packet* p = itq_->lookup(len);
00139 hdr_ip* iph = hdr_ip::access(p);
00140 if (iph->flowid() == prune) {
00141 if (iph->saddr() == src && iph->daddr() == group) {
00142 total_[0]++;
00143 }
00144 } else if (iph->flowid() == graft) {
00145 if (iph->saddr() == src && iph->daddr() == group) {
00146 total_[1]++;
00147 }
00148 } else if (iph->flowid() == reg) {
00149 hdr_CtrMcast* ch = hdr_CtrMcast::access(p);
00150 if (ch->src() == src+1 && ch->group() == group) {
00151 total_[2]++;
00152 }
00153 } else if (iph->flowid() == data) {
00154 if (iph->saddr() == src+1 && iph->daddr() == group) {
00155 total_[3]++;
00156 }
00157 }
00158 }
00159
00160 }