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.28 2005/07/13 03:51:25 tomh 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()
00053 : dynamic_(0),
00054 latest_time_(0),
00055 itq_(0)
00056 {
00057 bind_bw("bandwidth_", &bandwidth_);
00058 bind_time("delay_", &delay_);
00059 bind_bool("avoidReordering_", &avoidReordering_);
00060 }
00061
00062 int LinkDelay::command(int argc, const char*const* argv)
00063 {
00064 if (argc == 2) {
00065 if (strcmp(argv[1], "isDynamic") == 0) {
00066 dynamic_ = 1;
00067 itq_ = new PacketQueue();
00068 return TCL_OK;
00069 }
00070 } else if (argc == 6) {
00071 if (strcmp(argv[1], "pktintran") == 0) {
00072 int src = atoi(argv[2]);
00073 int grp = atoi(argv[3]);
00074 int from = atoi(argv[4]);
00075 int to = atoi(argv[5]);
00076 pktintran (src, grp);
00077 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);
00078 return TCL_OK;
00079 }
00080 }
00081
00082 return Connector::command(argc, argv);
00083 }
00084
00085 void LinkDelay::recv(Packet* p, Handler* h)
00086 {
00087 double txt = txtime(p);
00088 Scheduler& s = Scheduler::instance();
00089 if (dynamic_) {
00090 Event* e = (Event*)p;
00091 e->time_= txt + delay_;
00092 itq_->enque(p);
00093 s.schedule(this, p, txt + delay_);
00094 } else if (avoidReordering_) {
00095
00096
00097 double now_ = Scheduler::instance().clock();
00098 if (txt + delay_ < latest_time_ - now_ && latest_time_ > 0) {
00099 latest_time_+=txt;
00100 s.schedule(target_, p, latest_time_ - now_ );
00101 } else {
00102 latest_time_ = now_ + txt + delay_;
00103 s.schedule(target_, p, txt + delay_);
00104 }
00105
00106 } else {
00107 s.schedule(target_, p, txt + delay_);
00108 }
00109 s.schedule(h, &intr_, txt);
00110 }
00111
00112 void LinkDelay::send(Packet* p, Handler*)
00113 {
00114 target_->recv(p, (Handler*) NULL);
00115 }
00116
00117 void LinkDelay::reset()
00118 {
00119 Scheduler& s= Scheduler::instance();
00120
00121 if (itq_ && itq_->length()) {
00122 Packet *np;
00123
00124 while ((np = itq_->deque()) != 0) {
00125 s.cancel(np);
00126 drop(np);
00127 }
00128 }
00129 }
00130
00131 void LinkDelay::handle(Event* e)
00132 {
00133 Packet *p = itq_->deque();
00134 assert(p->time_ == e->time_);
00135 send(p, (Handler*) NULL);
00136 }
00137
00138 void LinkDelay::pktintran(int src, int group)
00139 {
00140 int reg = 1;
00141 int prune = 30;
00142 int graft = 31;
00143 int data = 0;
00144 for (int i=0; i<4; i++) {
00145 total_[i] = 0;
00146 }
00147
00148 if (! dynamic_)
00149 return;
00150
00151 int len = itq_->length();
00152 while (len) {
00153 len--;
00154 Packet* p = itq_->lookup(len);
00155 hdr_ip* iph = hdr_ip::access(p);
00156 if (iph->flowid() == prune) {
00157 if (iph->saddr() == src && iph->daddr() == group) {
00158 total_[0]++;
00159 }
00160 } else if (iph->flowid() == graft) {
00161 if (iph->saddr() == src && iph->daddr() == group) {
00162 total_[1]++;
00163 }
00164 } else if (iph->flowid() == reg) {
00165 hdr_CtrMcast* ch = hdr_CtrMcast::access(p);
00166 if (ch->src() == src+1 && ch->group() == group) {
00167 total_[2]++;
00168 }
00169 } else if (iph->flowid() == data) {
00170 if (iph->saddr() == src+1 && iph->daddr() == group) {
00171 total_[3]++;
00172 }
00173 }
00174 }
00175
00176 }