HI Richard, So, what is the question?
Best Wishes, Teerawat Issariyakul http://www.ns2ultimate.com/ http://www.facebook.com/pages/Teerawat-Issariyakul/358240861417 http://twitter.com/T_Bear http://www.t-issariyakul.blogspot.com http://www.ece.ubc.ca/~teerawat On Mar 19, 2012, at 11:43 PM, Ricard Alegre wrote: > > Dear all, > > I wanted to implement a Round Robin packet scheduler just following the > process in the book Introduction to Network Simulator ns2 from Ekran > Hossain: > > According to the process I have created the following *.cc and *.h files: > > *//classifier-flow.h* > > #ifndef ns_gw_flow_classifier_h > #define ns_gw_flow_classifier_h > > #include "packet.h" > #include "ip.h" > #include "classifier.h" > > class FlowClassifier : public Classifier { > protected: > int classify(Packet *p); > }; > > #endif > > > *//classifier-flow.cc* > #include "gw_flow_classifier.h" > #include <stdlib.h> > > > static class FlowClassifierClass : public TclClass { > public: > FlowClassifierClass() : TclClass("Classifier/Flow") {} > TclObject* create(int, const char*const*) { > return (new FlowClassifier()); > } > } class_flow_classifier; > > > > int FlowClassifier::classify(Packet *p) { > return hdr_ip::access(p)->flowid(); > } > > > *//pkt-sched.h* > > #ifndef ns_gw_pkt_sch_h > #define ns_gw_pkt_sch_h > > #include "packet.h" > #include "ip.h" > #include "connector.h" > #include "queue.h" > > #define NS 10 > > > class PktScheduler : public Connector { > public: > PktScheduler(); > virtual void handle(Event*); > virtual void recv(Packet*, Handler*); > protected: > void send(int fid, Handler* h); > virtual void resume(); > int getFlowID(Packet* p) {return hdr_ip::access(p)->flowid();}; > virtual int nextID() = 0; > Handler* qh_[NS]; > Packet* pkt_[NS]; > int blocked_; > int active_flow_id_; > }; > > //RR > class RRScheduler : public PktScheduler { > public: > RRScheduler(); > private: > virtual int nextID(); > int current_id_; > }; > > #endif > > > *//pkt-sched.cc* > #include "gw_pkt_sch.h" > > PktScheduler::PktScheduler() > { > int i; > for (i=0;i<NS ;i++) { > pkt_[i] = 0; > qh_[i]=0; > } > blocked_ = 0;active_flow_id_ = -1; > } > > void PktScheduler::recv(Packet* p, Handler* h) > { > int fid = getFlowID(p); > pkt_[fid] = p;qh_[fid] = h; > if (!blocked_) { > send(fid,this); > blocked_ = 1; > active_flow_id_ = fid; > } > } > > > void PktScheduler::send(int fid_idx, Handler* h) > { > Connector::send(pkt_[fid_idx],h); > pkt_[fid_idx] = 0; > } > > > void PktScheduler::handle(Event*) { resume(); } > > void PktScheduler::resume() > { > qh_[active_flow_id_]->handle(0); > int index = nextID(); > blocked_ = 0; > if (index >= 0) { > send(index,this); > blocked_ = 1; > active_flow_id_ = index; > } > } > > //RR > RRScheduler::RRScheduler() > { > current_id_ = -1; > } > static class RRSchedulerClass: public TclClass { > public: > RRSchedulerClass() : TclClass("PktScheduler/RR") {} > TclObject* create(int, const char*const*) { > return (new RRScheduler()); > } > } class_rr_scheduler; > > int RRScheduler::nextID() > { > int count = 0; > current_id_++;current_id_ %= NS; > while((pkt_[current_id_] == 0)&&(count < NS)){ > current_id_++;current_id_ %= NS; > count++; > } > if (count == NS) > return -1; > else{ > return current_id_; > } > } > > *And the following Otcl file:* > > *#ns-link.tcl* > > Class LinkSch -superclass Link > > LinkSch instproc init {src dst bw delay num_queues} { > $self next $src $dst > $self instvar link_ queue_ head_ toNode_ ttl_ > $self instvar drophead_ > $self instvar num_queues_ sch_ flow_clsfr_ > set ns [Simulator instance] > set head_ [new Connector] > set drophead_ [new Connector] > set link_ [new DelayLink] > set ttl_ [new TTLChecker] > set flow_clsfr_ [new Classifier/Flow] > set sch_ [new PktScheduler/RR] > set num_queues_ $num_queues > $head_ set link_ $self > $drophead_ target [$ns set nullAgent_] > $head_ target $flow_clsfr_ > for {set i 0} {$i < $num_queues_} {incr i} { > set queue_($i) [new Queue/DropTail] > $queue_($i) target $sch_ > $queue_($i) drop-target $drophead_ > } > $sch_ target $link_ > $link_ target $ttl_ > $link_ drop-target $drophead_ > $link_ set bandwidth_ $bw > $link_ set delay_ $delay > $ttl_ target [$dst entry] > $ttl_ drop-target $drophead_ > } > > LinkSch instproc add-flow { fid } { > $self instvar queue_ flow_clsfr_ > $flow_clsfr_ install $fid $queue_($fid) > } > > Simulator instproc sch-link { n1 n2 bw delay num_queues} { > $self instvar link_ queueMap_ nullAgent_ useasim_ > set sid [$n1 id] > set did [$n2 id] > set link_($sid:$did) [new LinkSch $n1 $n2 $bw $delay $num_queues] > set pushback 0 > $n1 add-neighbor $n2 $pushback > } > > Simulator instproc add-flow { n1 n2 prio } { > $self instvar link_ > set sid [$n1 id] > set did [$n2 id] > $link_($sid:$did) add-flow $prio > } > > *The output of the compilation is correct. However, when I try to simulate > this tcl script:* > > set num_queues [lindex $argv 0] > set ns [new Simulator] > set f [open book.tr w] > $ns trace-all $f > set n1 [$ns node] > set n2 [$ns node] > set n3 [$ns node] > $ns duplex-link $n1 $n2 5Mb 2ms DropTail > $ns duplex-link $n2 $n3 5Mb 2ms DropTail > $ns sch-link $n1 $n3 5Mb 2ms 10 > $ns simplex-link $n3 $n1 5Mb 2ms DropTail > for {set i 0} {$i < $num_queues} {incr i} { > $ns add-flow $n1 $n3 $i > set tcp($i) [new Agent/TCP] > set sink($i) [new Agent/TCPSink] > set ftp($i) [new Application/FTP] > $tcp($i) set fid_ $i > $ns attach-agent $n1 $tcp($i) > $ns attach-agent $n3 $sink($i) > $ftp($i) attach-agent $tcp($i) > $ns connect $tcp($i) $sink($i) > $ns at 0.0 "$ftp($i) start" > } > proc show_tcp_seqno {} { > global tcp num_queues > for {set i 0} {$i < $num_queues} {incr i} { > puts "The final tcp($i) sequence number is > [$tcp($i) set t_seqno_]" > } > } > $ns at 10.0 "show_tcp_seqno" > $ns at 10.1 "$ns halt" > $ns run > > *I get the following error:* > * > * > can't read "queue_": variable is array > while executing > "return $queue_" > (procedure "_o59" line 3) > (Link queue line 3) > invoked from within > "$link_($qn) queue" > (procedure "_o3" line 20) > (Simulator run line 20) > invoked from within > "$ns run" > (file "book.tcl" line 34) > > I have notice that when I comment the following lines in ns-link.tcl file > the error disappear but I do not know if it is correct or not to do it, or > there is a smoother way to fix the problem: > > # > # Also reset every queue > # > > foreach qn [array names link_] { > set q [$link_($qn) queue] > $q reset > } > > > I use ns2 v2.34 on Ubuntu 10.04 64 bits OS. > yes, I've read the FAQ, ns-problems page, and manual and I couldn't find > the answer there. > > Thanks, > -- > Ricard Alegre > http://wirelessatcom.uab.es/ricardalegre.htm > > > > > -- > Ricard Alegre > http://wirelessatcom.uab.es/ricardalegre.htm >