1 / 50

LAB 5

LAB 5. Adding New Components High level scripting in otcl Linking otcl and C++ Low level in C++. Adding New Component using otcl. Additional <new_stuff>.tcl file source <new_stuff>.tcl Adding new files change Makefile (NS_TCL_LIB), tcl/lib/ns- lib.tcl recompile. C. S. C. R. cross

mcclary
Download Presentation

LAB 5

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  2. Adding New Component using otcl • Additional <new_stuff>.tcl file • source <new_stuff>.tcl • Adding new files • change Makefile (NS_TCL_LIB), tcl/lib/ns- lib.tcl • recompile NS2Work

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

  4. 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 Receiver-side processing string message S R NS2Work

  5. 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" } NS2Work

  6. 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" } NS2Work

  7. 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” } NS2Work

  8. 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 NS2Work

  9. 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 NS2Work

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

  11. 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” NS2Work

  12. 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” NS2Work

  13. 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 } NS2Work

  14. 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 NS2Work

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

  16. Extending ns in C++ • Adding code in <new_stuff>.{cc,h} files • Change Makefile • make depend • recompile NS2Work

  17. 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 NS2Work

  18. Class Hierarchy TclObject NsObject Connector Classifier Queue Delay Agent Trace AddrClassifier McastClasifier DropTail RED TCP Enq Deq Drop Reno SACK NS2Work

  19. C++/otcl Linkage NS2Work

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

  21. 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 NS2Work

  22. 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 NS2Work

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

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

  25. 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); } NS2Work

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

  27. 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 NS2Work

  28. 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; } NS2Work

  29. Creating New Components • new agent, no headers • new agent, new packet header NS2Work

  30. DtopTail Round Robin (DTRR) – Step 1 TclObject NsObject Connector Classifier Queue Delay Agent Trace AddrClassifier McastClasifier DropTail RED TCP Enq Deq Drop Reno SACK DTRR NS2Work

  31. 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 }; NS2Work

  32. 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(){ … } NS2Work

  33. 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 NS2Work

  34. 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! NS2Work

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

  36. 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) NS2Work

  37. EMUR Header – Step 2 //emur.cc #include <emur_pkt.h> 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; NS2Work

  38. 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"; …… }; NS2Work

  39. 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); }; NS2Work

  40. 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*); }; NS2Work

  41. 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().str2addr(argv[4]))); } } class_rtEmur; NS2Work

  42. 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 NS2Work

  43. 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); } NS2Work

  44. 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); } NS2Work

  45. 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); } NS2Work

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

  47. 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); … } NS2Work

  48. 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 } NS2Work

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

  50. Summary • Internals of NS2 • How to add new component in ns2 • Queue • Routing NS2Work

More Related