📄 aodvi.h
字号:
/*Copyright 2003 Joel Branch, Gilbert (Gang) Chen, Boleslaw K. Szymanski and Rensselaer Polytechnic Institute. All worldwide rights reserved. A license to use, copy, modify and distribute this software for non-commercial research purposes only is hereby granted, provided that this copyright notice and accompanying disclaimer is not modified or removed from the software.DISCLAIMER: The software is distributed "AS IS" without anyexpress or implied warranty, including but not limited to, anyimplied warranties of merchantability or fitness for a particularpurpose or any warranty of non-infringement of any current orpending patent rights. The authors of the software make norepresentations about the suitability of this software for anyparticular purpose. The entire risk as to the quality andperformance of the software is with the user. Should the softwareprove defective, the user assumes the cost of all necessaryservicing, repair or correction. In particular, neither RensselaerPolytechnic Institute, nor the authors of the software are liablefor any indirect, special, consequential, or incidental damagesrelated to the software, to the maximum extent the lawpermits.*/#include <map>#include <list>#ifndef AODVI_H#define AODVI_Htemplate <class PLD>struct AODVI_Struct { public: enum { RREQ=0,RREP,RERR,RACK,HELLO,DATA,RTABLE}; enum { JOIN=0, REPAIR=1, GRATUITOUS=2, DESTINATION=3, UNKNOWN=4}; enum { RREQ_SIZE=24, RREP_SIZE=20, RERR_SIZE=5, RACK_SIZE=2, DATA_SIZE=12}; // used for control packet flags struct flag_struct { unsigned int join:1; unsigned int repair:1; unsigned int gratuitous:1; unsigned int destination:1; unsigned int unknown:1; unsigned int acknowledgement:1; unsigned int nodelete:1; }; struct rreq_tuple_t { int rreq_id; simtime_t rreq_time; }; struct route_entry_t { int dst_seq_num; bool valid_dst_seq; int hop_count; ether_addr_t next_hop; double lifetime; }; struct hdr_struct { int type; int TTL; flag_struct flags; int hop_count; int rreq_id; ether_addr_t dst_addr; int dst_seq_num; ether_addr_t src_addr; ether_addr_t prev_hop_addr; int src_seq_num; double lifetime; int prefix_size; unsigned int size; bool dump(std::string& str) const ; }; typedef smart_packet_t<hdr_struct, PLD> packet_t; typedef PLD payload_t; static const int TimeToLive; static const simtime_t PathDiscoveryTime; static const simtime_t NetTraversalTime; static const simtime_t NodeTraversalTime; static const simtime_t ActiveRouteTimeout; static const simtime_t MyRouteTimeout;};template <class PLD> const int AODVI_Struct<PLD>::TimeToLive = 10;template <class PLD> const simtime_t AODVI_Struct<PLD>::ActiveRouteTimeout = 3;template <class PLD> const simtime_t AODVI_Struct<PLD>::NodeTraversalTime = 40;template <class PLD> const simtime_t AODVI_Struct<PLD>::NetTraversalTime = 2 * NodeTraversalTime * 35;template <class PLD> const simtime_t AODVI_Struct<PLD>::PathDiscoveryTime = 2 * NetTraversalTime;template <class PLD> const simtime_t AODVI_Struct<PLD>::MyRouteTimeout = 2 * ActiveRouteTimeout; template <class PLD>component AODVI : public TypeII, public AODVI_Struct<PLD>{public: inport inline void from_transport( payload_t& pld, ether_addr_t& dst, unsigned int size); inport inline void from_mac_data (packet_t* pkt, ether_addr_t& dst); inport inline void from_mac_ack (bool errflag); InfiTimer<pair<AODVI_Struct<PLD>::packet_t*,ether_addr_t> > to_mac_delay; outport void to_transport ( payload_t& pld ); outport void to_mac (packet_t* pkt, ether_addr_t& dst, unsigned int size); inport inline void to_mac_depart(const pair<packet_t*,ether_addr_t>& p, unsigned int i); AODVI() { connect to_mac_delay.to_component, to_mac_depart; } virtual ~AODVI() {}; void Start(); // called when simulation starts void Stop(); // called when simulation stops simtime_t ForwardDelay; bool DumpPackets; ether_addr_t MyEtherAddr; int SentPackets, RecvPackets; protected: void init_rreq(ether_addr_t); // node initiates a route request void receive_rreq(packet_t*); // node receives a rreq packet void forward_rreq(packet_t*,int); void receive_rrep(packet_t*); void receive_data(packet_t*); typedef std::multimap<ether_addr_t, rreq_tuple_t, ether_addr_t::compare> rreq_cache_t; typedef std::map<ether_addr_t, route_entry_t, ether_addr_t::compare> routing_table_t; typedef std::list<packet_t*> packet_buffer_t; routing_table_t m_routing_table; packet_buffer_t m_packet_buffer; rreq_cache_t m_rreq_cache; // for tracking received rreq's int m_seq_num; // node's current sequence number int m_req_id;};template <class PLD>void AODVI<PLD>::Start(){ m_seq_num = 0; m_req_id = 0; SentPackets=RecvPackets=0;}template <class PLD>void AODVI<PLD>::Stop(){ packet_buffer_t::iterator iter=m_packet_buffer.begin(); for(;iter!=m_packet_buffer.end();iter++) (*iter)->free();}template <class PLD>void AODVI<PLD>::from_transport( payload_t& pld, ether_addr_t& dst_addr, unsigned int size){ packet_t* new_p = packet_t::alloc(); new_p->hdr.type = DATA; new_p->hdr.src_addr = MyEtherAddr; new_p->hdr.prev_hop_addr = MyEtherAddr; new_p->hdr.dst_addr = dst_addr; new_p->hdr.size = DATA_SIZE + size; new_p->pld=pld; Printf((DumpPackets,"aodv%d created %s\n",(int)MyEtherAddr,new_p->dump().c_str())); // check if there's a route to the destination routing_table_t::iterator iter = m_routing_table.find(dst_addr); if(iter == m_routing_table.end()) { Printf((DumpPackets,"aodv%d no route\n",(int)MyEtherAddr)); init_rreq(dst_addr); // the payload packet gets dropped m_packet_buffer.push_back(new_p); } else { // route found - send packet SentPackets++; to_mac(new_p, (iter->second).next_hop, new_p->hdr.size); } } template <class PLD>void AODVI<PLD>::from_mac_ack (bool){}template <class PLD>void AODVI<PLD>::from_mac_data (packet_t* packet, ether_addr_t& dst_addr){ if(dst_addr==MyEtherAddr||dst_addr==ether_addr_t::BROADCAST) { RecvPackets++; Printf((DumpPackets,"aodv%d received %s\n",(int)MyEtherAddr, packet->dump().c_str())); switch(packet->hdr.type) { case RREQ: receive_rreq(packet); break; case RREP: receive_rrep(packet); break; case DATA: receive_data(packet); break; } } packet->free();} template <class PLD>void AODVI<PLD>::receive_data(packet_t* p){ if(p->hdr.dst_addr == MyEtherAddr) { p->inc_pld_ref(); to_transport(p->pld); return; } // check if there's a route to the destination routing_table_t::iterator iter = m_routing_table.find(p->hdr.dst_addr); if(iter == m_routing_table.end()) { Printf((DumpPackets,"aodv%d no route - %s\n",(int)MyEtherAddr, p->dump().c_str())); } else { // route found - forward the data packet packet_t* new_p = packet_t::alloc(); new_p->hdr.type = DATA; new_p->hdr.src_addr = p->hdr.src_addr; new_p->hdr.prev_hop_addr = MyEtherAddr; new_p->hdr.dst_addr = p->hdr.dst_addr; new_p->hdr.size = p->hdr.size; p->inc_pld_ref(); new_p->pld = p->pld; SentPackets++; to_mac(new_p, (iter->second).next_hop, new_p->hdr.size); }} template <class PLD>void AODVI<PLD>::init_rreq(ether_addr_t dst){ packet_t* new_p = packet_t::alloc(); // NOTE - the "lifetime" field is not used in RREQ's new_p->hdr.type = RREQ; new_p->hdr.TTL = TimeToLive; new_p->hdr.src_addr = MyEtherAddr; new_p->hdr.dst_addr = dst; new_p->hdr.prev_hop_addr = MyEtherAddr; new_p->hdr.hop_count = 0; new_p->hdr.rreq_id = ++ m_req_id; new_p->hdr.src_seq_num = ++ m_seq_num; new_p->hdr.size= RREQ_SIZE; new_p->hdr.flags.join=0; new_p->hdr.flags.repair=0; new_p->hdr.flags.gratuitous=0; new_p->hdr.flags.destination=0; new_p->hdr.flags.unknown=0; // buffer the RREQ (source and ID) for PathDiscoveryTime rreq_tuple_t tuple; tuple.rreq_id = m_req_id; tuple.rreq_time = SimTime(); m_rreq_cache.insert(make_pair(MyEtherAddr,tuple)); // see if route to dest is known - then we can obtain dst seq. num. routing_table_t::iterator iter = m_routing_table.find(dst); if(iter != m_routing_table.end()) new_p->hdr.dst_seq_num = iter->second.dst_seq_num; else new_p->hdr.flags.unknown = true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -