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

📄 vanetrbc.cc

📁 基于NS-2的车辆Ad Hoc网络(VANET)的一个应用层协议框架
💻 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 + -