Modification of AODV protocol source code of NS2 in Cognitive radio networks
Hi,
I would like to modify NS2 source code of AODV routing protocol to check remaining energy at each node, available bandwidth at each node, degree of a node and spectrum opportunity at each node should be checked during route construction process. Hence, please help to me to modify the source code of AODV route request packet to check the above information at each node and if the intermediate node satisfies above all requirements then that node would be considered as relay node to reach source to destination. Thank you in advance. |
We'll be glad to HELP....so post what YOU have written, and where you're stuck. But don't ask people to write your code for you....this isn't the place to come for handouts. Google has plenty of sample code sources to get you started.
|
the AODV code part for checking residual energy at each node during route construction process
Dear sir,
Thank you for your advice. I did some modifications to the aodv protocol of ns2.35 as specified below. so please kindly help me. Recently I did following changes to AODV protocol to work out residual energy metric during route selection: below changes made at aodv_packet.h: step-1: added #include<mobilenode.h> step-2: in the route request structure below changes are made: struct hdr_aodv_request { u_int8_t rq_type; // Packet Type u_int8_t reserved[2]; u_int8_t rq_hop_count; // Hop Count u_int32_t rq_bcast_id; // Broadcast ID nsaddr_t rq_dst; // Destination IP Address u_int32_t rq_dst_seqno; // Destination Sequence Number nsaddr_t rq_src; // Source IP Address u_int32_t rq_src_seqno; // Source Sequence Number double rq_timestamp; // when REQUEST sent; // used to compute route discovery latency /************************added by me**********************************************************/ double iEnergy; //used to get the remaining energy at each node MobileNode *iNode; //to capture the node object for getting energy at node. /************************end of my code**********************************************************/ // This define turns on gratuitous replies- see aodv.cc for implementation contributed by // Anant Utgikar, 09/16/02. //#define RREQ_GRAT_RREP 0x80 inline int size() { int sz = 0; /* sz = sizeof(u_int8_t) // rq_type + 2*sizeof(u_int8_t) // reserved + sizeof(u_int8_t) // rq_hop_count + sizeof(double) // rq_timestamp + sizeof(u_int32_t) // rq_bcast_id + sizeof(nsaddr_t) // rq_dst + sizeof(u_int32_t) // rq_dst_seqno + sizeof(nsaddr_t) // rq_src + sizeof(u_int32_t); // rq_src_seqno */ sz = 7*sizeof(u_int32_t); assert (sz >= 0); return sz; } }; Step-3: the below changes made to route reply struct hdr_aodv_reply { u_int8_t rp_type; // Packet Type u_int8_t reserved[2]; u_int8_t rp_hop_count; // Hop Count nsaddr_t rp_dst; // Destination IP Address u_int32_t rp_dst_seqno; // Destination Sequence Number nsaddr_t rp_src; // Source IP Address double rp_lifetime; // Lifetime double rp_timestamp; // when corresponding REQ sent; // used to compute route discovery latency /*********************The code added by me to check the energy while relpy*********************/ double rEnergy; //MobileNode *rNode; /*********************END OF code added by me to check the energy while relpy*********************/ inline int size() { int sz = 0; /* sz = sizeof(u_int8_t) // rp_type + 2*sizeof(u_int8_t) // rp_flags + reserved + sizeof(u_int8_t) // rp_hop_count + sizeof(double) // rp_timestamp + sizeof(nsaddr_t) // rp_dst + sizeof(u_int32_t) // rp_dst_seqno + sizeof(nsaddr_t) // rp_src + sizeof(u_int32_t); // rp_lifetime */ sz = 6*sizeof(u_int32_t); assert (sz >= 0); return sz; } }; The below changes are mode to the aodv.cc Step-4: rq->iEnergy=10.0;//required energy at each node added by me. void AODV::sendRequest(nsaddr_t dst) { // Allocate a RREQ packet Packet *p = Packet::alloc(); struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p); aodv_rt_entry *rt = rtable.rt_lookup(dst); assert(rt); /* * Rate limit sending of Route Requests. We are very conservative * about sending out route requests. */ if (rt->rt_flags == RTF_UP) { assert(rt->rt_hops != INFINITY2); Packet::free((Packet *)p); return; } if (rt->rt_req_timeout > CURRENT_TIME) { Packet::free((Packet *)p); return; } // rt_req_cnt is the no. of times we did network-wide broadcast // RREQ_RETRIES is the maximum number we will allow before // going to a long timeout. if (rt->rt_req_cnt > RREQ_RETRIES) { rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT; rt->rt_req_cnt = 0; Packet *buf_pkt; while ((buf_pkt = rqueue.deque(rt->rt_dst))) { drop(buf_pkt, DROP_RTR_NO_ROUTE); } Packet::free((Packet *)p); return; } #ifdef DEBUG fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %d\n", ++route_request, index, rt->rt_dst); #endif // DEBUG // Determine the TTL to be used this time. // Dynamic TTL evaluation - SRD rt->rt_req_last_ttl = max(rt->rt_req_last_ttl,rt->rt_last_hop_count); if (0 == rt->rt_req_last_ttl) { // first time query broadcast ih->ttl_ = TTL_START; } else { // Expanding ring search. if (rt->rt_req_last_ttl < TTL_THRESHOLD) ih->ttl_ = rt->rt_req_last_ttl + TTL_INCREMENT; else { // network-wide broadcast ih->ttl_ = NETWORK_DIAMETER; rt->rt_req_cnt += 1; } } // remember the TTL used for the next time rt->rt_req_last_ttl = ih->ttl_; // PerHopTime is the roundtrip time per hop for route requests. // The factor 2.0 is just to be safe .. SRD 5/22/99 // Also note that we are making timeouts to be larger if we have // done network wide broadcast before. rt->rt_req_timeout = 2.0 * (double) ih->ttl_ * PerHopTime(rt); if (rt->rt_req_cnt > 0) rt->rt_req_timeout *= rt->rt_req_cnt; rt->rt_req_timeout += CURRENT_TIME; // Don't let the timeout to be too large, however .. SRD 6/8/99 if (rt->rt_req_timeout > CURRENT_TIME + MAX_RREQ_TIMEOUT) rt->rt_req_timeout = CURRENT_TIME + MAX_RREQ_TIMEOUT; rt->rt_expire = 0; #ifdef DEBUG fprintf(stderr, "(%2d) - %2d sending Route Request, dst: %d, tout %f ms\n", ++route_request, index, rt->rt_dst, rt->rt_req_timeout - CURRENT_TIME); #endif // DEBUG // Fill out the RREQ packet // ch->uid() = 0; ch->ptype() = PT_AODV; ch->size() = IP_HDR_LEN + rq->size(); ch->iface() = -2; ch->error() = 0; ch->addr_type() = NS_AF_NONE; ch->prev_hop_ = index; // AODV hack ih->saddr() = index; ih->daddr() = IP_BROADCAST; ih->sport() = RT_PORT; ih->dport() = RT_PORT; // Fill up some more fields. rq->rq_type = AODVTYPE_RREQ; rq->rq_hop_count = 1; rq->rq_bcast_id = bid++; rq->rq_dst = dst; rq->rq_dst_seqno = (rt ? rt->rt_seqno : 0); rq->rq_src = index; seqno += 2; assert ((seqno%2) == 0); rq->rq_src_seqno = seqno; rq->rq_timestamp = CURRENT_TIME; rq->iEnergy=10.0;//required energy at each node added by me. Scheduler::instance().schedule(target_, p, 0.); } Step-5: the below code added at sendReply method of ADOV.cc MobileNode *rNode; rNode=(MobileNode *)(Node::get_node_by_address(index)); rp->rEnergy=rNode->energy_model()->energy(); void AODV::sendReply(nsaddr_t ipdst, u_int32_t hop_count, nsaddr_t rpdst, u_int32_t rpseq, u_int32_t lifetime, double timestamp) { Packet *p = Packet::alloc(); struct hdr_cmn *ch = HDR_CMN(p); struct hdr_ip *ih = HDR_IP(p); struct hdr_aodv_reply *rp = HDR_AODV_REPLY(p); aodv_rt_entry *rt = rtable.rt_lookup(ipdst); #ifdef DEBUG fprintf(stderr, "sending Reply from %d at %.2f\n", index, Scheduler::instance().clock()); #endif // DEBUG assert(rt); rp->rp_type = AODVTYPE_RREP; //rp->rp_flags = 0x00; rp->rp_hop_count = hop_count; rp->rp_dst = rpdst; rp->rp_dst_seqno = rpseq; rp->rp_src = index; rp->rp_lifetime = lifetime; rp->rp_timestamp = timestamp; //here write the code regarding available energy at this node while sending reply MobileNode *rNode; rNode=(MobileNode *)(Node::get_node_by_address(index)); rp->rEnergy=rNode->energy_model()->energy(); //the end of my code // ch->uid() = 0; ch->ptype() = PT_AODV; ch->size() = IP_HDR_LEN + rp->size(); ch->iface() = -2; ch->error() = 0; ch->addr_type() = NS_AF_INET; ch->next_hop_ = rt->rt_nexthop; ch->prev_hop_ = index; // AODV hack ch->direction() = hdr_cmn::DOWN; ih->saddr() = index; ih->daddr() = ipdst; ih->sport() = RT_PORT; ih->dport() = RT_PORT; ih->ttl_ = NETWORK_DIAMETER; Scheduler::instance().schedule(target_, p, 0.); } Step-6: the following changes are made to AODV::recvReply method of aodv.cc the double variable en added for collecting energy at the relay node and checking residual energy at the relay node before sending reply in the below block: // I am not the destination, but I may have a fresh enough route. else if (rt && (rt->rt_hops != INFINITY2) && (rt->rt_seqno >= rq->rq_dst_seqno) && rq->iEnergy<=en) the below is a total code part of the "recvRequest" function. void AODV::recvRequest(Packet *p) { struct hdr_ip *ih = HDR_IP(p); struct hdr_aodv_request *rq = HDR_AODV_REQUEST(p); aodv_rt_entry *rt; //code added by me for checking residual energy at the relay node with the energy specified in received packet. double en; MobileNode *relayNode; relayNode=(MobileNode *)(Node::get_node_by_address(index)); en=relayNode->energy_model()->energy(); /* * Drop if: * - I'm the source * - I recently heard this request. */ if(rq->rq_src == index) { #ifdef DEBUG fprintf(stderr, "%s: got my own REQUEST\n", __FUNCTION__); #endif // DEBUG Packet::free(p); return; } if (id_lookup(rq->rq_src, rq->rq_bcast_id)) { #ifdef DEBUG fprintf(stderr, "%s: discarding request\n", __FUNCTION__); #endif // DEBUG Packet::free(p); return; } /* * Cache the broadcast ID */ id_insert(rq->rq_src, rq->rq_bcast_id); /* * We are either going to forward the REQUEST or generate a * REPLY. Before we do anything, we make sure that the REVERSE * route is in the route table. */ aodv_rt_entry *rt0; // rt0 is the reverse route rt0 = rtable.rt_lookup(rq->rq_src); if(rt0 == 0) { /* if not in the route table */ // create an entry for the reverse route. rt0 = rtable.rt_add(rq->rq_src); } rt0->rt_expire = max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE)); if ( (rq->rq_src_seqno > rt0->rt_seqno ) || ((rq->rq_src_seqno == rt0->rt_seqno) && (rq->rq_hop_count < rt0->rt_hops)) ) { // If we have a fresher seq no. or lesser #hops for the // same seq no., update the rt entry. Else don't bother. rt_update(rt0, rq->rq_src_seqno, rq->rq_hop_count, ih->saddr(), max(rt0->rt_expire, (CURRENT_TIME + REV_ROUTE_LIFE)) ); if (rt0->rt_req_timeout > 0.0) { // Reset the soft state and // Set expiry time to CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT // This is because route is used in the forward direction, // but only sources get benefited by this change rt0->rt_req_cnt = 0; rt0->rt_req_timeout = 0.0; rt0->rt_req_last_ttl = rq->rq_hop_count; rt0->rt_expire = CURRENT_TIME + ACTIVE_ROUTE_TIMEOUT; } /* Find out whether any buffered packet can benefit from the * reverse route. * May need some change in the following code - Mahesh 09/11/99 */ assert (rt0->rt_flags == RTF_UP); Packet *buffered_pkt; while ((buffered_pkt = rqueue.deque(rt0->rt_dst))) { if (rt0 && (rt0->rt_flags == RTF_UP)) { assert(rt0->rt_hops != INFINITY2); forward(rt0, buffered_pkt, NO_DELAY); } } } // End for putting reverse route in rt table /* * We have taken care of the reverse route stuff. * Now see whether we can send a route reply. */ rt = rtable.rt_lookup(rq->rq_dst); // First check if I am the destination .. if(rq->rq_dst == index) { #ifdef DEBUG fprintf(stderr, "%d - %s: destination sending reply\n", index, __FUNCTION__); #endif // DEBUG // Just to be safe, I use the max. Somebody may have // incremented the dst seqno. seqno = max(seqno, rq->rq_dst_seqno)+1; if (seqno%2) seqno++; sendReply(rq->rq_src, // IP Destination 1, // Hop Count index, // Dest IP Address seqno, // Dest Sequence Num MY_ROUTE_TIMEOUT, // Lifetime rq->rq_timestamp); // timestamp Packet::free(p); } // I am not the destination, but I may have a fresh enough route. else if (rt && (rt->rt_hops != INFINITY2) && (rt->rt_seqno >= rq->rq_dst_seqno) && rq->iEnergy<=en) { //assert (rt->rt_flags == RTF_UP); assert(rq->rq_dst == rt->rt_dst); //assert ((rt->rt_seqno%2) == 0); // is the seqno even? sendReply(rq->rq_src, rt->rt_hops + 1, rq->rq_dst, rt->rt_seqno, (u_int32_t) (rt->rt_expire - CURRENT_TIME), // rt->rt_expire - CURRENT_TIME, rq->rq_timestamp); // Insert nexthops to RREQ source and RREQ destination in the // precursor lists of destination and source respectively rt->pc_insert(rt0->rt_nexthop); // nexthop to RREQ source rt0->pc_insert(rt->rt_nexthop); // nexthop to RREQ destination #ifdef RREQ_GRAT_RREP sendReply(rq->rq_dst, rq->rq_hop_count, rq->rq_src, rq->rq_src_seqno, (u_int32_t) (rt->rt_expire - CURRENT_TIME), // rt->rt_expire - CURRENT_TIME, rq->rq_timestamp); #endif // TODO: send grat RREP to dst if G flag set in RREQ using rq->rq_src_seqno, rq->rq_hop_counT // DONE: Included gratuitous replies to be sent as per IETF aodv draft specification. As of now, G flag has not been dynamically used and is always set or reset in aodv-packet.h --- Anant Utgikar, 09/16/02. Packet::free(p); } /* * Can't reply. So forward the Route Request */ else { ih->saddr() = index; ih->daddr() = IP_BROADCAST; rq->rq_hop_count += 1; // Maximum sequence number seen en route if (rt) rq->rq_dst_seqno = max(rt->rt_seqno, rq->rq_dst_seqno); forward((aodv_rt_entry*) 0, p, DELAY); } } Unfortunately I got below error while debugging ns with gdb klr@klr-HP:~$ gdb ns GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04 Copyright (C) 2012 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i686-linux-gnu". For bug reporting instructions, please see: <http://bugs.launchpad.net/gdb-linaro/>... Reading symbols from /usr/local/ns-allinone-2.35/bin/ns...done. (gdb) run simple-wireless.tcl Starting program: /usr/local/ns-allinone-2.35/bin/ns simple-wireless.tcl num_nodes is set 2 INITIALIZE THE LIST xListHead Starting Simulation... 0 - command: calling set_destination() 0 - set_destination: calling log_movement() ( 1) - 0 sending Route Request, dst: 1 ( 2) - 0 sending Route Request, dst: 1, tout 1.800000 ms channel.cc:sendUp - Calc highestAntennaZ_ and distCST_ highestAntennaZ_ = 1.5, distCST_ = 550.0 SORTING LISTS ...DONE! ( 3) - 0 sending Route Request, dst: 1 ( 4) - 0 sending Route Request, dst: 1, tout 3.600000 ms ( 5) - 0 sending Route Request, dst: 1 ( 6) - 0 sending Route Request, dst: 1, tout 5.400000 ms ( 7) - 0 sending Route Request, dst: 1 ( 8) - 0 sending Route Request, dst: 1, tout 7.200000 ms ( 9) - 0 sending Route Request, dst: 1 (10) - 0 sending Route Request, dst: 1, tout 1.800000 ms (11) - 0 sending Route Request, dst: 1 (12) - 0 sending Route Request, dst: 1, tout 3.600000 ms (13) - 0 sending Route Request, dst: 1 (14) - 0 sending Route Request, dst: 1, tout 5.400000 ms 1 - command: calling set_destination() 1 - set_destination: calling log_movement() (15) - 0 sending Route Request, dst: 1 (16) - 0 sending Route Request, dst: 1, tout 7.200000 ms 1 - command: calling set_destination() 1 - set_destination: calling log_movement() (17) - 0 sending Route Request, dst: 1 (18) - 0 sending Route Request, dst: 1, tout 1.800000 ms Program received signal SIGSEGV, Segmentation fault. 0x082a2562 in EnergyModel::energy (this=0x0) at ./mobile/energy-model.h:103 103 inline double energy() const { return energy_; } (gdb) the below is TCl code: # simple-wireless.tcl # A simple example for wireless simulation # ====================================================================== # Define options # ====================================================================== set val(chan) Channel/WirelessChannel ;# channel type set val(prop) Propagation/TwoRayGround ;# radio-propagation model set val(netif) Phy/WirelessPhy ;# network interface type set val(mac) Mac/802_11 ;# MAC type set val(ifq) Queue/DropTail/PriQueue ;# interface queue type set val(ll) LL ;# link layer type set val(ant) Antenna/OmniAntenna ;# antenna model set val(ifqlen) 50 ;# max packet in ifq set val(nn) 2 ;# number of mobilenodes set val(rp) AODV ;# AODV routing protocol set val(energymodel) EnergyModel ;# Energy Model set val(initialenergy) 100.00 ;#initial energy in jouls # ====================================================================== # Main Program # ====================================================================== # # Initialize Global Variables # set ns_ [new Simulator] set tracefd [open simple.tr w] $ns_ trace-all $tracefd # set up topography object set topo [new Topography] $topo load_flatgrid 500 500 # # Create God # create-god $val(nn) # # Create the specified number of mobilenodes [$val(nn)] and "attach" them # to the channel. # Here two nodes are created : node(0) and node(1) #allocation/creation of channel set chan_1_ [new $val(chan)] # configure node $ns_ node-config -adhocRouting $val(rp) \ -llType $val(ll) \ -macType $val(mac) \ -ifqType $val(ifq) \ -ifqLen $val(ifqlen) \ -antType $val(ant) \ -propType $val(prop) \ -phyType $val(netif) \ #-channelType $chan_1_ \ -channel $chan_1_ \ -topoInstance $topo \ -agentTrace ON \ -routerTrace ON \ -macTrace OFF \ -movementTrace OFF #-energyModel $val(energymodel) \ #-rxPower 32.28 \ #-txPower 31.32 \ #-idlePower 0.01 \ #-sleepPower 0.01 \ #-initialEnergy $val(initialenergy) for {set i 0} {$i < $val(nn) } {incr i} { set node_($i) [$ns_ node] $node_($i) random-motion 0 ;# disable random motion } # # Provide initial (X,Y, for now Z=0) co-ordinates for mobilenodes # $node_(0) set X_ 5.0 $node_(0) set Y_ 2.0 $node_(0) set Z_ 0.0 $node_(1) set X_ 390.0 $node_(1) set Y_ 385.0 $node_(1) set Z_ 0.0 # # Now produce some simple node movements # Node_(1) starts to move towards node_(0) # $ns_ at 50.0 "$node_(1) setdest 25.0 20.0 15.0" $ns_ at 10.0 "$node_(0) setdest 20.0 18.0 1.0" # Node_(1) then starts to move away from node_(0) $ns_ at 100.0 "$node_(1) setdest 490.0 480.0 15.0" # Setup traffic flow between nodes # TCP connections between node_(0) and node_(1) set tcp [new Agent/TCP] $tcp set class_ 2 set sink [new Agent/TCPSink] $ns_ attach-agent $node_(0) $tcp $ns_ attach-agent $node_(1) $sink $ns_ connect $tcp $sink set ftp [new Application/FTP] $ftp attach-agent $tcp $ns_ at 10.0 "$ftp start" # # Tell nodes when the simulation ends # for {set i 0} {$i < $val(nn) } {incr i} { $ns_ at 150.0 "$node_($i) reset"; } $ns_ at 150.0 "stop" $ns_ at 150.01 "puts \"NS EXITING...\" ; $ns_ halt" proc stop {} { global ns_ tracefd $ns_ flush-trace close $tracefd } puts "Starting Simulation..." $ns_ run |
Did you solve the problem or not yet?
|
All times are GMT -5. The time now is 10:49 AM. |