⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 olsr.cc

📁 UM-OLSR is an OLSR (Optimized Link State Routing protocol) implementation for the ns2 network simula
💻 CC
📖 第 1 页 / 共 5 页
字号:
/*************************************************************************** *   Copyright (C) 2004 by Francisco J. Ros                                * *   fjrm@dif.um.es                                                        * *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * *   This program is distributed in the hope that it will be useful,       * *   but WITHOUT ANY WARRANTY; without even the implied warranty of        * *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         * *   GNU General Public License for more details.                          * *                                                                         * *   You should have received a copy of the GNU General Public License     * *   along with this program; if not, write to the                         * *   Free Software Foundation, Inc.,                                       * *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             * ***************************************************************************/////// \file	OLSR.cc/// \brief	Implementation of OLSR agent and related classes.////// This is the main file of this software because %OLSR's behaviour is/// implemented here.///#include <olsr/OLSR.h>#include <olsr/OLSR_pkt.h>#include <olsr/OLSR_printer.h>#include <math.h>#include <limits.h>#include <address.h>#include <ip.h>#include <cmu-trace.h>#include <map>/// Length (in bytes) of UDP header.#define UDP_HDR_LEN	8////// \brief Function called by MAC layer when cannot deliver a packet.////// \param p Packet which couldn't be delivered./// \param arg OLSR agent passed for a callback.///static voidolsr_mac_failed_callback(Packet *p, void *arg) {  ((OLSR*)arg)->mac_failed(p);}/********** TCL Hooks **********/int OLSR_pkt::offset_;static class OLSRHeaderClass : public PacketHeaderClass {public:	OLSRHeaderClass() : PacketHeaderClass("PacketHeader/OLSR", sizeof(OLSR_pkt)) {		bind_offset(&OLSR_pkt::offset_);	}} class_rtProtoOLSR_hdr;static class OLSRClass : public TclClass {public:	OLSRClass() : TclClass("Agent/OLSR") {}	TclObject* create(int argc, const char*const* argv) {		// argv has the following structure:		// <tcl-object> <tcl-object> Agent/OLSR create-shadow <id>		// e.g: _o17 _o17 Agent/OLSR create-shadow 0		// argv[4] is the address of the node		assert(argc == 5);		return new OLSR((nsaddr_t)Address::instance().str2addr(argv[4]));	}} class_rtProtoOLSR;////// \brief Interface with TCL interpreter.////// From your TCL scripts or shell you can invoke commands on this OLSR/// routing agent thanks to this function. Currently you can call "start",/// "print_rtable", "print_linkset", "print_nbset", "print_nb2hopset",/// "print_mprset", "print_mprselset" and "print_topologyset" commands.////// \param argc Number of arguments./// \param argv Arguments./// \return TCL_OK or TCL_ERROR.///intOLSR::command(int argc, const char*const* argv) {	if (argc == 2) {		// Starts all timers		if (strcasecmp(argv[1], "start") == 0) {			hello_timer_.resched(0.0);			tc_timer_.resched(0.0);			mid_timer_.resched(0.0);						return TCL_OK;    		}		// Prints routing table		else if (strcasecmp(argv[1], "print_rtable") == 0) {			if (logtarget_ != NULL) {				sprintf(logtarget_->pt_->buffer(), "P %f _%d_ Routing Table",					CURRENT_TIME,					OLSR::node_id(ra_addr()));				logtarget_->pt_->dump();				rtable_.print(logtarget_);			}			else {				fprintf(stdout, "%f _%d_ If you want to print this routing table "					"you must create a trace file in your tcl script",					CURRENT_TIME,					OLSR::node_id(ra_addr()));			}			return TCL_OK;		}		// Prints link set		else if (strcasecmp(argv[1], "print_linkset") == 0) {			if (logtarget_ != NULL) {				sprintf(logtarget_->pt_->buffer(), "P %f _%d_ Link Set",					CURRENT_TIME,					OLSR::node_id(ra_addr()));				logtarget_->pt_->dump();				OLSR_printer::print_linkset(logtarget_, linkset());			}			else {				fprintf(stdout, "%f _%d_ If you want to print this link set "					"you must create a trace file in your tcl script",					CURRENT_TIME,					OLSR::node_id(ra_addr()));			}			return TCL_OK;		}		// Prints neighbor set		else if (strcasecmp(argv[1], "print_nbset") == 0) {			if (logtarget_ != NULL) {				sprintf(logtarget_->pt_->buffer(), "P %f _%d_ Neighbor Set",					CURRENT_TIME,					OLSR::node_id(ra_addr()));				logtarget_->pt_->dump();				OLSR_printer::print_nbset(logtarget_, nbset());			}			else {				fprintf(stdout, "%f _%d_ If you want to print this neighbor set "					"you must create a trace file in your tcl script",					CURRENT_TIME,					OLSR::node_id(ra_addr()));			}			return TCL_OK;		}		// Prints 2-hop neighbor set		else if (strcasecmp(argv[1], "print_nb2hopset") == 0) {			if (logtarget_ != NULL) {				sprintf(logtarget_->pt_->buffer(), "P %f _%d_ Neighbor2hop Set",					CURRENT_TIME,					OLSR::node_id(ra_addr()));				logtarget_->pt_->dump();				OLSR_printer::print_nb2hopset(logtarget_, nb2hopset());			}			else {				fprintf(stdout, "%f _%d_ If you want to print this neighbor2hop set "					"you must create a trace file in your tcl script",					CURRENT_TIME,					OLSR::node_id(ra_addr()));			}			return TCL_OK;		}		// Prints MPR set		else if (strcasecmp(argv[1], "print_mprset") == 0) {			if (logtarget_ != NULL) {				sprintf(logtarget_->pt_->buffer(), "P %f _%d_ MPR Set",					CURRENT_TIME,					OLSR::node_id(ra_addr()));				logtarget_->pt_->dump();				OLSR_printer::print_mprset(logtarget_, mprset());			}			else {				fprintf(stdout, "%f _%d_ If you want to print this mpr set "					"you must create a trace file in your tcl script",					CURRENT_TIME,					OLSR::node_id(ra_addr()));			}			return TCL_OK;		}		// Prints MPR selector set		else if (strcasecmp(argv[1], "print_mprselset") == 0) {			if (logtarget_ != NULL) {				sprintf(logtarget_->pt_->buffer(), "P %f _%d_ MPR Selector Set",					CURRENT_TIME,					OLSR::node_id(ra_addr()));				logtarget_->pt_->dump();				OLSR_printer::print_mprselset(logtarget_, mprselset());			}			else {				fprintf(stdout, "%f _%d_ If you want to print this mpr selector set "					"you must create a trace file in your tcl script",					CURRENT_TIME,					OLSR::node_id(ra_addr()));			}			return TCL_OK;		}		// Prints topology set		else if (strcasecmp(argv[1], "print_topologyset") == 0) {			if (logtarget_ != NULL) {				sprintf(logtarget_->pt_->buffer(), "P %f _%d_ Topology Set",					CURRENT_TIME,					OLSR::node_id(ra_addr()));				logtarget_->pt_->dump();				OLSR_printer::print_topologyset(logtarget_, topologyset());			}			else {				fprintf(stdout, "%f _%d_ If you want to print this topology set "					"you must create a trace file in your tcl script",					CURRENT_TIME,					OLSR::node_id(ra_addr()));			}			return TCL_OK;		}	}	else if (argc == 3) {		// Obtains the corresponding dmux to carry packets to upper layers		if (strcmp(argv[1], "port-dmux") == 0) {    			dmux_ = (PortClassifier*)TclObject::lookup(argv[2]);			if (dmux_ == NULL) {				fprintf(stderr, "%s: %s lookup of %s failed\n", __FILE__, argv[1], argv[2]);				return TCL_ERROR;			}			return TCL_OK;    		}		// Obtains the corresponding tracer		else if (strcmp(argv[1], "log-target") == 0 || strcmp(argv[1], "tracetarget") == 0) {			logtarget_ = (Trace*)TclObject::lookup(argv[2]);			if (logtarget_ == NULL)				return TCL_ERROR;			return TCL_OK;		}	}	// Pass the command up to the base class	return Agent::command(argc, argv);}/********** Timers **********/////// \brief Sends a HELLO message and reschedules the HELLO timer./// \param e The event which has expired.///voidOLSR_HelloTimer::expire(Event* e) {	agent_->send_hello();	agent_->set_hello_timer();}////// \brief Sends a TC message (if there exists any MPR selector) and reschedules the TC timer./// \param e The event which has expired.///voidOLSR_TcTimer::expire(Event* e) {	if (agent_->mprselset().size() > 0)		agent_->send_tc();	agent_->set_tc_timer();}////// \brief Sends a MID message (if the node has more than one interface) and resets the MID timer./// \warning Currently it does nothing because there is no support for multiple interfaces./// \param e The event which has expired.///voidOLSR_MidTimer::expire(Event* e) {#ifdef MULTIPLE_IFACES_SUPPORT	agent_->send_mid();	agent_->set_mid_timer();#endif}////// \brief Removes tuple_ if expired. Else timer is rescheduled to expire at tuple_->time().////// The task of actually removing the tuple is left to the OLSR agent.////// \param e The event which has expired.///voidOLSR_DupTupleTimer::expire(Event* e) {	if (tuple_->time() < CURRENT_TIME) {		agent_->rm_dup_tuple(tuple_);		delete tuple_;		delete this;	}	else		resched(DELAY(tuple_->time()));}////// \brief Removes tuple_ if expired. Else if symmetric time/// has expired then it is assumed a neighbor loss and agent_->nb_loss()/// is called. In this case the timer is rescheduled to expire at/// tuple_->time(). Otherwise the timer is rescheduled to expire at/// the minimum between tuple_->time() and tuple_->sym_time().////// The task of actually removing the tuple is left to the OLSR agent.////// \param e The event which has expired.///voidOLSR_LinkTupleTimer::expire(Event* e) {	double now	= CURRENT_TIME;		if (tuple_->time() < now) {		agent_->rm_link_tuple(tuple_);		delete tuple_;		delete this;	}	else if (tuple_->sym_time() < now) {		if (first_time_)			first_time_ = false;		else			agent_->nb_loss(tuple_);		resched(DELAY(tuple_->time()));	}	else		resched(DELAY(MIN(tuple_->time(), tuple_->sym_time())));}////// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time().////// The task of actually removing the tuple is left to the OLSR agent.////// \param e The event which has expired.///voidOLSR_Nb2hopTupleTimer::expire(Event* e) {	if (tuple_->time() < CURRENT_TIME) {		agent_->rm_nb2hop_tuple(tuple_);		delete tuple_;		delete this;	}	else		resched(DELAY(tuple_->time()));}////// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time().////// The task of actually removing the tuple is left to the OLSR agent.////// \param e The event which has expired.///voidOLSR_MprSelTupleTimer::expire(Event* e) {	if (tuple_->time() < CURRENT_TIME) {		agent_->rm_mprsel_tuple(tuple_);		delete tuple_;		delete this;	}	else		resched(DELAY(tuple_->time()));}////// \brief Removes tuple_ if expired. Else the timer is rescheduled to expire at tuple_->time().////// The task of actually removing the tuple is left to the OLSR agent.////// \param e The event which has expired.///voidOLSR_TopologyTupleTimer::expire(Event* e) {	if (tuple_->time() < CURRENT_TIME) {		agent_->rm_topology_tuple(tuple_);		delete tuple_;		delete this;	}	else		resched(DELAY(tuple_->time()));}////// \brief Removes tuple_ if expired. Else timer is rescheduled to expire at tuple_->time()./// \warning Actually this is never invoked because there is no support for multiple interfaces./// \param e The event which has expired.///voidOLSR_IfaceAssocTupleTimer::expire(Event* e) {	if (tuple_->time() < CURRENT_TIME) {		agent_->rm_ifaceassoc_tuple(tuple_);		delete tuple_;		delete this;	}	else		resched(DELAY(tuple_->time()));}////// \brief Sends a control packet which must bear every message in the OLSR agent's buffer.////// The task of actually sending the packet is left to the OLSR agent.////// \param e The event which has expired.///voidOLSR_MsgTimer::expire(Event* e) {	agent_->send_pkt();	delete this;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -