Presentation is loading. Please wait.

Presentation is loading. Please wait.

NS2Work1 LAB 5 Adding New Components High level scripting in otcl Linking otcl and C++ Low level in C++

Similar presentations


Presentation on theme: "NS2Work1 LAB 5 Adding New Components High level scripting in otcl Linking otcl and C++ Low level in C++"— Presentation transcript:

1 NS2Work1 LAB 5 Adding New Components High level scripting in otcl Linking otcl and C++ Low level in C++

2 NS2Work2 Adding New Component using otcl Additional.tcl file source.tcl Adding new files –change Makefile (NS_TCL_LIB), tcl/lib/ns- lib.tcl –recompile

3 NS2Work3 Example: Agent/Message n0 n1 n4 n5 n2 n3 128Kb, 50ms 10Mb, 1ms CC cross traffic SR msg agent http://nslab.ee.ntu.edu.tw/courses/ns-tutorial/ftw-tutorial.html

4 NS2Work4 Agent/Message A UDP agent (without UDP header) Up to 64 bytes user message Good for fast prototyping a simple idea Usage requires extending ns functionality SR string message Receiver-side processing

5 NS2Work5 Agent/Message: Step 1 Define sender class Sender –superclass Agent/Message # Message format: “Addr Op SeqNo” Sender instproc send-next {} { $self instvar seq_ agent_addr_ $self send “$agent_addr_ send $seq_” incr seq_ global ns $ns at [expr [$ns now]+0.1] "$self send-next" }

6 NS2Work6 Agent/Message: Step 2 Define sender packet processing Sender instproc recv msg { $self instvar agent_addr_ set sdr [lindex $msg 0] set seq [lindex $msg 2] puts "Sender gets ack $seq from $sdr" }

7 NS2Work7 Agent/Message: Step 3 Define receiver packet processing Class Receiver –superclass Agent/Message Receiver instproc recv msg { $self instvar agent_addr_ set sdr [lindex $msg 0] set seq [lindex $msg 2] puts “Receiver gets seq $seq from $sdr” $self send “$addr_ ack $seq” }

8 NS2Work8 Agent/Message: Step 4 Scheduler and tracing # Create scheduler set ns [new Simulator] # Turn on Tracing set fd [new “message.nam” w] $ns namtrace-all $fd

9 NS2Work9 Agent/Message: Step 5 Topology for {set i 0} {$i < 6} {incr i} { set n($i) [$ns node] } $ns duplex-link $n(0) $n(1) 128kb 50ms DropTail $ns duplex-link $n(1) $n(4) 10Mb 1ms DropTail $ns duplex-link $n(1) $n(5) 10Mb 1ms DropTail $ns duplex-link $n(0) $n(2) 10Mb 1ms DropTail $ns duplex-link $n(0) $n(3) 10Mb 1ms DropTail $ns queue-limit $n(0) $n(1) 5 $ns queue-limit $n(1) $n(0) 5

10 NS2Work10 Agent/Message: Step 6 Routing # Packet loss produced by queueing # Routing protocol: let’s run distance vector $ns rtproto DV

11 NS2Work11 Agent/Message: Step 7 Cross traffic set udp0 [new Agent/UDP] $ns attach-agent $n(2) $udp0 set null0 [new Agent/NULL] $ns attach-agent $n(4) $null0 $ns connect $udp0 $null0 set exp0 [new Application/Traffic/Exponential] $exp0 set rate_ 128k $exp0 attach-agent $udp0 $ns at 1.0 “$exp0 start”

12 NS2Work12 Agent/Message: Step 8 Message agents set sdr [new Sender] $sdr set packetSize_ 1000 set rcvr [new Receiver] $rcvr set packetSize_ 40 $ns attach $n(3) $sdr $ns attach $n(5) $rcvr $ns connect $sdr $rcvr $ns connect $rcvr $sdr $ns at 1.1 “$sdr send-next”

13 NS2Work13 Agent/Message: Step 9 End-of-simulation wrapper (as usual) $ns at 2.0 finish proc finish {} { global ns fd $ns flush-trace close $fd exit 0 }

14 NS2Work14 Agent/Message: Result Example output >./ns msg.tcl Receiver gets seq 0 from 0 Sender gets ack 0 from 1 Receiver gets seq 1 from 0 Sender gets ack 1 from 1 Receiver gets seq 2 from 0 Sender gets ack 2 from 1 Receiver gets seq 3 from 0 Sender gets ack 3 from 1 Receiver gets seq 4 from 0 Sender gets ack 4 from 1 Receiver gets seq 5 from 0

15 NS2Work15 Add Your Change into ns tcl/lib/ns-lib.tcl Class Simulator … source../mysrc/msg.tcl Makefile NS_TCL_LIB = \ tcl/mysrc/msg.tcl \ … make distclean./configure --enable-debug –Or: change Makefile.in, make distclean, then./configure --enable-debug

16 NS2Work16 Extending ns in C++ Adding code in.{cc,h} files –Change Makefile –make depend –recompile

17 NS2Work17 Guidelines Decide position in class hierarchy –i.e., which class to derive from? Create new packet header (if necessary) Create C++ class, fill in methods Define otcl linkage Write otcl code (if required) Build

18 NS2Work18 Class Hierarchy TclObject NsObject Connector Classifier DelayAddrClassifierAgentMcastClasifierQueueTrace DropTailREDTCPEnqDeqDrop RenoSACK

19 NS2Work19 C++/otcl Linkage

20 NS2Work20 TclObject: Hierarchy and Shadowing TclObject Agent Agent/TCP Agent/TCP otcl shadow object _o123 Agent/TCP C++ object *tcp TclObject Agent TcpAgent otcl class hierarchy C++ class hierarchy

21 NS2Work21 TclObject::bind() Link C++ member variables to otcl object variables C++ TcpAgent::TcpAgent() { bind(“window_”, &wnd_); … } –bind_time(), bind_bool(), bind_bw() otcl set tcp [new Agent/TCP] $tcp set window_ 200

22 NS2Work22 Initialization of Bound Variables Initialization through otcl class variables Agent/TCP set window_ 50 Do all initialization of bound variables in ~ns/lib/ns-default.tcl –Otherwise a warning will be issued when the shadow object is created

23 NS2Work23 TclObject::command() Implement otcl methods in C++ Trap point: otcl method cmd{} Send all arguments after cmd{} call to TclObject::command()

24 NS2Work24 TclObject::command() $tcp send TclObject::unknown{}$tcp cmd send no such procedure TcpAgent::command() match “send”? Invoke parent: return Agent::command() process and return Yes No OTcl space C++ space

25 NS2Work25 TclObject::command() otcl set tcp [new Agent/TCP] $tcp advance 10 C++ int TcpAgent::command(int argc, const char*const* argv) { if (argc == 3) { if (strcmp(argv[1], “advance”) == 0) { int newseq = atoi(argv[2]); …… return(TCL_OK); } return (Agent::command(argc, argv); }

26 NS2Work26 TclClass TclObject Agent Agent/TCP TclObject Agent TcpAgent NsObject ?? OTcl C++ mirroring Static class TcpClass : public TclClass { public: TcpClass() : TclClass(“Agent/TCP”) {} TclObject* create(int, const char*const*) { return (new TcpAgent()); } } class_tcp; Static class TcpClass : public TclClass { public: TcpClass() : TclClass(“Agent/TCP”) {} TclObject* create(int, const char*const*) { return (new TcpAgent()); } } class_tcp;

27 NS2Work27 Class Tcl Singleton class with a handle to Tcl interpreter Usage –Invoke otcl procedure –Obtain otcl evaluation results –Pass a result string to otcl –Return success/failure code to otcl

28 NS2Work28 Class Tcl Tcl& tcl = Tcl::instance(); if (argc == 2) { if (strcmp(argv[1], “now”) == 0) { tcl.resultf(“%g”, clock()); return TCL_OK; } tcl.error(“command not found”); return TCL_ERROR; } else if (argc == 3) { tcl.eval(argv[2]); clock_ = atof(tcl.result()); return TCL_OK; }

29 NS2Work29 Creating New Components new agent, no headers new agent, new packet header

30 NS2Work30 DtopTail Round Robin (DTRR) – Step 1 TclObject NsObject Connector Classifier DelayAddrClassifierAgentMcastClasifierQueueTrace DropTailREDTCPEnqDeqDrop RenoSACK DTRR

31 NS2Work31 Adding New Queue (DropTail Round Robin) using C++ //dtrr-queue.h class DtRrQueue : public Queue { public: DtRrQueue() { q1_ = new PacketQueue; q2_ = new PacketQueue; pq_ = q1_; deq_turn_ = 1; } protected: void enque(Packet*); Packet* deque(); PacketQueue *q1_; // First FIFO queue PacketQueue *q2_; // Second FIFO queue int deq_turn_; // 1 for First queue 2 for Second };

32 NS2Work32 Creating Object //dtrr-queue.cc #include "dtrr-queue.h" static class DtRrQueueClass : public TclClass { public: DtRrQueueClass() : TclClass("Queue/DTRR") {} TclObject* create(int, const char*const*) { return (new DtRrQueue); } } class_dropt_tail_round_robin; void DtRrQueue::enque(Packet* p) { … } Packet* DtRrQueue::deque(){ … }

33 NS2Work33 New Agent, New Header for Example MANET Unicast Routing (EMUR) Example: Agent/Message –New packet header for 64-byte message –New transport agent to process this new header

34 NS2Work34 New Packet Header Create new header structure Enable tracing support of new header Create static class for otcl linkage (packet.h) Enable new header in otcl (tcl/lib/ns- packet.tcl) This does not apply when you add a new field into an existing header!

35 NS2Work35 How Packet Header Works Packet next_ hdrlen_ bits_ size determined at compile time size determined at compile time size determined at compile time …… hdr_cmn hdr_ip hdr_tcp size determined at simulator startup time (PacketHeaderManager) PacketHeader/Common PacketHeader/IP PacketHeader/TCP

36 NS2Work36 EMUR Header – Step 1 //emur_pkt.h struct hdr_emur_pkt { nsaddr_t pkt_src_; // Node which originated this packet u_int16_t pkt_len_; // Packet length (in bytes) u_int8_t pkt_seq_num_; // Packet sequence number inline nsaddr_t& pkt_src() { return pkt_src_; } inline u_int16_t& pkt_len() { return pkt_len_; } inline u_int8_t& pkt_seq_num() { return pkt_seq_num_; } static int offset_; inline static int& offset() { return offset_; } inline static hdr_emur_pkt* access(const Packet* p) { return (hdr_emur_pkt*)p->access(offset_); }}; #define HDR_EMUR_PKT(p) hdr_emur_pkt::access(p)

37 NS2Work37 EMUR Header – Step 2 //emur.cc #include int Emur_pkt::offset_; static class EmurHeaderClass : public HeaderClass { public: EmurHeaderClass() : PacketHeaderClass("PacketHeader/EMUR", sizeof(hdr_emur_pkt)) { bind_offset(&hdr_emur_pkt::offset_); } } class_rtEMUR_hdr;

38 NS2Work38 EMUR Header – Step 3 Enable tracing (packet.h): enum packet_t { PT_TCP,…,PT_EMUR, PT_NTYPE // This MUST be the LAST one }; class p_info { …… name_[PT_EMUR] = “EMUR”; name_[PT_NTYPE]= "undefined"; ……};

39 NS2Work39 EMUR Timer – Step 1 //emur.h class Emur; // forward declaration /* Timers */ class Emur_PktTimer : public TimerHandler { public: Emur_PktTimer(Emur* agent) : TimerHandler() { agent_ = agent; } protected: Emur* agent_; virtual void expire(Event* e); };

40 NS2Work40 EMUR Class – Step 2 //emur.h class Emur : public Agent { /* Friends */ friend class Emur_PktTimer; /* Private members */ … Emur_PktTimer pkt_timer_; // Timer for sending packets. public: Emur(nsaddr_t); int command(int, const char*const*); void recv(Packet*, Handler*); };

41 NS2Work41 EMUR Binding – Step 3 //Emur/Emur.cc static class EmurClass : public TclClass { public: EmurClass() : TclClass("Agent/EMUR") {} TclObject* create(int argc, const char*const* argv) { assert(argc == 5); return (new Emur((nsaddr_t)Address::instance().str2add r(argv[4]))); } } class_rtEmur;

42 NS2Work42 EMUR Constructor – Step 4 //Emur/Emur.cc Emur::Emur(nsaddr_t id) : Agent(PT_EMUR), pkt_timer_(this) { bind(“tcl_var_", &cc_var_); ra_addr_ = id; } In Simulation script Agent/Emur set tcl_var_ 100

43 NS2Work43 EMUR Command – Step 5 Int Emur::command(int argc, const char*const* argv) { if (argc == 2) { if (strcasecmp(argv[1], "start") == 0) { Start(); //pkt_timer_.resched(0.0); return TCL_OK; } else if (strcasecmp(argv[1], “some_other_func") == 0) { … } else if (argc == 3) { // Obtains corresponding dmux to carry packets to upper layers if (strcmp(argv[1], “some_var") == 0) { loc_var_ = atoi (strcmp(argv[2]) return TCL_OK; } … // Pass the command to the base class return Agent::command(argc, argv); }

44 NS2Work44 Emur Packet Receive – Step 6 Void Emur::recv(Packet* p, Handler* h) { struct hdr_cmn* ch = HDR_CMN(p); struct hdr_ip* ih = HDR_IP(p); if (ih->saddr() == ra_addr()) { // If there exists a loop, must drop the packet if (ch->num_forwards() > 0) { drop(p, DROP_RTR_ROUTE_LOOP); return; } // else if this is a packet I am originating, must add IP header else if (ch->num_forwards() == 0) ch->size() += IP_HDR_LEN; } // If it is a Emur packet, must process it if (ch->ptype() == PT_EMUR) recv_emur_pkt(p); // Otherwise, must forward the packet (unless TTL has reached zero) else { ih->ttl_--; if (ih->ttl_ == 0) { drop(p, DROP_RTR_TTL); return; } forward_data(p); }

45 NS2Work45 Emur Send Packet – Step - 7 Void Emur::send_emur_pkt() { Packet* p = allocpkt(); struct hdr_cmn* ch = HDR_CMN(p); struct hdr_ip* ih = HDR_IP(p); struct hdr_Emur_pkt* ph = HDR_Emur_PKT(p); ph->pkt_src() = ra_addr(); ph->pkt_len() = 7; ph->pkt_seq_num() = seq_num_++; ch->ptype() = PT_Emur; ch->direction() = hdr_cmn::DOWN; ch->size() = IP_HDR_LEN + ph->pkt_len(); ch->error() = 0; ch->next_hop() = IP_BROADCAST; ch->addr_type() = NS_AF_INET; ih->saddr() = ra_addr(); ih->daddr() = IP_BROADCAST; ih->sport() = RT_PORT; ih->dport() = RT_PORT; ih->ttl() = IP_DEF_TTL; Scheduler::instance().schedule(target_, p, JITTER); }

46 NS2Work46 Emur Scheduling Packets – Step 8 void Emur_PktTimer::expire(Event* e) { agent_->send_emur_pkt(); resched((double)5.0); }

47 NS2Work47 Emur Tracing – Step 9 //trace/cmu-trace.h trace/cmu-trace.h class CMUTrace : public Trace { /*... definitions... */ private: /*... */ void format_aodv(Packet *p, int offset); void format_emur(Packet *p, int offset); }; //trace/cmu-trace.cc Void CMUTrace::format_emur(Packet *p, int offset) { struct hdr_emur_pkt* ph = HDR_EMUR_PKT(p); … }

48 NS2Work48 Add Method to TCL library – Step 10 //tcl/lib/ns-lib.tcl Simulator instproc create-Emur-agent { node } { # Create Emur routing agent set ragent [new Agent/Emur [$node node- addr]] $self at 0.0 "$ragent start" $node set ragent_ $ragent return $ragent }

49 NS2Work49 EMUR Final Step Change Makefile.in to add your source files Run Configure Run make

50 NS2Work50 Summary Internals of NS2 How to add new component in ns2 –Queue –Routing


Download ppt "NS2Work1 LAB 5 Adding New Components High level scripting in otcl Linking otcl and C++ Low level in C++"

Similar presentations


Ads by Google