📄 vanetrbc.cc
字号:
/* ------------------------------------------------------------------- * Vehicular Ad Hoc Networks: Regular Broadcasting of messages. * Skeleton for VANET-protocols. This should be considered as an * example to create other VANET protocols! * Apart from channel load, the "protocol" as it is now does not do * anything useful. * * Dan Jungels (daniel.jungels@epfl.ch) * LCA - EPFL * * * Main Protocol file * Originally written for ns2.29 * * 2005-12-15: release of first version (dj) * 2005-12-23: update and cleanup, public release (dj) * 2006-01-05: bugfix in the packet header (dj) * ------------------------------------------------------------------- */#include <assert.h>#include "vanetrbc.h"int hdr_vanet::offset_;// define our Packet Headersstatic class VanetRBCHeaderClass : public PacketHeaderClass {public: VanetRBCHeaderClass() : PacketHeaderClass("PacketHeader/VanetRBC", sizeof(hdr_all_vanet)) { bind_offset(&hdr_vanet::offset_); }} class_vanetrbchdr;// define a TCL-classstatic class VanetRBCClass : public TclClass {public: VanetRBCClass() : TclClass("Agent/VanetRBC") { }; TclObject* create(int argc, const char*const* argv) { if(argc != 5) { printf("Creating VanetRBC-Agent: argc not equal 5: %d\n", argc); exit(1); } return (new VanetRBCAgent(atoi(argv[4]))); // pass the ID to // the constructor }} class_vanetrbc;// to reset the timervoidVanetRBCAgent::reset_vanetrbc_pkt_timer() { pkt_timer_.resched((double)interval_);}// called when the timer expiresvoidVanetRBC_PktTimer::expire(Event*) { agent_->timeout(0);}// ! if you need more timers, add the necessary stuff for them here// the constructorVanetRBCAgent::VanetRBCAgent(u_int32_t id) : Agent(PT_VANETRBC), pkt_timer_(this) { // please note that in the previous line the pkt_timer_ object is // already initialized vanetID_ = id; running_ = false; // bind some variables to be changeable by the TCL script bind("jitterFactor_", &jitterfactor_); bind("crypto_delay_", &crypto_delay_); bind_time("interval_", &interval_); // if you add some variables here, add them also to tcl/lib/ns-default.tcl long int rngseed = 0; rng_.set_seed(rngseed); // initialize RNG (for JITTER)}// this function is called when a command is given to the agent in a// TCL-script. Simply add your own commands...intVanetRBCAgent::command(int argc, const char*const* argv) { if (argc == 2) { // a command without additional parameter if (logtarget_ != 0) { if (strcmp(argv[1], "start-regbc") == 0) { // start the regular broadcasting of VANET messages // (example.. you may change this to fit your needs, or add // additional commands) running_ = true; // we want the timer to be rescheduled sendRBC_pkt(); // send the first message return (TCL_OK); // always return OK if we get until here } else if (strcmp(argv[1], "stop-regbc") == 0) { // stop the regular broadcasting of VANET messages running_ = false; // stop the timers pkt_timer_.cancel(); return (TCL_OK); } else if (strcmp(argv[1], "dump-rxdb") == 0) { // output the contents of the Receive-database to // the logtarget // create a header-line sprintf(logtarget_->pt_->buffer(), "Node %u: RxDB (t: %f)", vanetID_, Scheduler::instance().clock()); logtarget_->pt_->dump(); // new line rxdb_.print(logtarget_); // and now dump the data return (TCL_OK); } } // end if logtarget_ != 0 else { // for logging (only change if you know what you're doing) fprintf(stdout, "Your logtarget is not defined! You will not be able to\n" "print or dump databases (e.g., RxDB). Please create\n" "a trace file in your tcl script (Node %u).\n", vanetID_); } // end else logtarget } else if (argc == 3) { // a command with one parameter if (strcmp(argv[1], "lookup") == 0) { // lookup the status of node argv[2] in the RxDB u_int32_t against = atoi(argv[2]); double lh; debug("\nNode %u: information about node %u (t: %f):\n", vanetID_, against, Scheduler::instance().clock()); lh = rxdb_.lookup(against); if(lh >= 0) debug("\tRxDB: last heard at %f.\n", lh); else debug("\tRxDB: Never heard.\n"); return (TCL_OK); } // for logging (only change if you know what you are doing) else if (strcmp(argv[1], "log-target") == 0 || strcmp(argv[1], "tracetarget") == 0) { logtarget_ = (Trace*)TclObject::lookup(argv[2]); if (logtarget_ == 0) { printf("Node %u: logtarget is zero!\n", vanetID_); return TCL_ERROR; } return TCL_OK; } } // If the command hasn't been processed by VanetRBCAgent::command, // call the command() function for the base class return (Agent::command(argc, argv));}// this function is called by ns2 if a packet has been received by the// agent (so, don't remove!)voidVanetRBCAgent::recv(Packet* pkt, Handler*) { // the different header types, we may need to access. // for convenience, we use these structs to access them struct hdr_cmn *hdrcmn = HDR_CMN(pkt); struct hdr_ip *hdrip = HDR_IP(pkt); struct hdr_vanet *hdrgen = HDR_VANET(pkt); if ((u_int32_t)hdrip->daddr() != IP_BROADCAST) { // check if brdcast mode printf("N %u: NOT BROADCAST Packet received!!\n", vanetID_); exit(1); } // dispatch between the different functions for evaluation the // different message types if(hdrcmn->ptype() == PT_VANETRBC) { switch(hdrgen->vn_msgtype) { case VANETTYPE_REGBC: recvRBC(pkt); break; // ! add dispatching for your message types here // (if you have added some in vanetrbc_header.h) default: printf("N %u: Invalid VANET packet-type (%d)\n", vanetID_, hdrgen->vn_msgtype); exit(1); } } else { // if you also have other (non-VANET) protocols in your simulations, // remove this printf("N %d: Non-VANET-Packet received (type: %d)\n", vanetID_, hdrcmn->ptype()); exit(1); } // Discard the packet Packet::free(pkt);}// do the processing of an RBC message// (example, this is not a mandatory function needed by ns2)voidVanetRBCAgent::recvRBC(Packet* pkt) { u_int32_t senderID; double tStamp; double XposS, YposS; // for storing the Sender's coordinates (example) // different header access functions struct hdr_vanet_rbc *hdr = HDR_VANET_RBC(pkt); senderID = hdr->rbc_senderID; tStamp = hdr->rbc_timestamp; XposS = hdr->rbc_posx; YposS = hdr->rbc_posy; // Add/update the sender to/in the RxDB rxdb_.add_entry(senderID, Scheduler::instance().clock(), XposS, YposS); // Example: calculate the trip time (please note that as it is defined here, // the trip time also includes the delays introduced by the cryptosystem!) double trtime = (Scheduler::instance().clock() - tStamp)*1000; // in ms // in opposition to printf(), the debug() function only prints messages // if you have put "debug" for agents to true in the TCL script debug("Node %u: received packet from %u, trip time %f ms (t: %f)\n", vanetID_, senderID, trtime, tStamp); // In general, it is better to do most of the calculations in C++. // However, in some cases it is necessary to quickly change something, // w/o heavy recompilation... In this case, it is possible to call a // function in the TCL-script, that does the processing. // for example, we give the triptime to TCL, so it can search for the // maximum trip time. char out[100]; // Prepare the output to the Tcl interpreter. hdr_ip* hdrip = HDR_IP(pkt); // IP header for the received packet // call the "recv" function defined in your TCL script sprintf(out, "%s recv %d %3.1f", name(), hdrip->src_.addr_ >> Address::instance().NodeShift_[1], trtime); Tcl& tcl = Tcl::instance(); tcl.eval(out); }// called to reschedule a new broadcastvoidVanetRBCAgent::timeout(int) { pkt_timer_.resched(interval_); sendRBC_pkt();}// broadcast an RBC message// (example, this is not a mandatory function needed by ns2)voidVanetRBCAgent::sendRBC_pkt() { int pktsz; Packet* pkt = allocpkt(); // Create a new packet // Access the header for the new packet: //struct hdr_cmn *hdrcmn = HDR_CMN(pkt); // not used here struct hdr_vanet_rbc *hdr = HDR_VANET_RBC(pkt); // IP broadcast. This is to ensure that every agent receiving the packet // actually gets it, even we don't necessarily use IP hdr_ip* iph = HDR_IP(pkt); iph->daddr() = IP_BROADCAST; iph->dport() = iph->sport(); // set some flags in the header (example) hdr->rbc_msgtype = VANETTYPE_REGBC; // (necessary for dispatching!) // this can be read at reception in // hdrgen->vn_msgtype hdr->rbc_senderID = vanetID_; hdr->rbc_timestamp = Scheduler::instance().clock(); // get my current location MobileNode *pnode = (MobileNode*)Node::get_node_by_address(vanetID_); pnode->update_position(); // update the position, before using it hdr->rbc_posx = pnode->X(); // include current own location hdr->rbc_posy = pnode->Y(); // every packet that is created in ns2 contains in its C++ // *data-structure* lots of header-fields that you don't need. so this // here actually sets the size of the packet that would be transmitted in // reality... so always use the general VANET-header, and the specific // "subheader" for the current packet type (that you have defined in your // packetheader-file). pktsz = hdr->size(); // get packet-size of this type hdr_cmn::access(pkt)->size() = pktsz; // set it in the simulator // we suppose that "crypto_delay" includes all delays of the cryptosystem: // in general this should be signing-delay + 2*verification-delay (for // verifying the signature and the certificate at the receiver... it's // easier to add this delay already at the sender). // the jitter is added to get some randomness in sending, so that not // all simulation-runs generate exactly the same collisions... Scheduler::instance().schedule(target_, pkt, crypto_delay_ + JITTER*jitterfactor_); // if the timers are running, schedule the next packet // (else we are stopped, or it was a single-sent packet) if(running_ == true) pkt_timer_.resched(interval_);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -