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
> 

Reply via email to