INET Framework for OMNeT++/OMNEST
EtherBus Class Reference

#include <EtherBus.h>

List of all members.

Classes

struct  BusTap

Public Member Functions

 EtherBus ()
virtual ~EtherBus ()

Protected Member Functions

virtual void initialize ()
virtual void handleMessage (cMessage *)
virtual void finish ()
virtual void tokenize (const char *str, std::vector< double > &array)

Protected Attributes

double propagationSpeed
BusTaptap
int taps
long numMessages

Detailed Description

Implements the bus which connects hosts, switches and other LAN entities on an Ethernet LAN.


Constructor & Destructor Documentation

EtherBus::EtherBus ( )
{
    tap = NULL;
}
EtherBus::~EtherBus ( ) [virtual]
{
    delete [] tap;
}

Member Function Documentation

void EtherBus::finish ( ) [protected, virtual]
{
    simtime_t t = simTime();
    recordScalar("simulated time", t);
    recordScalar("messages handled", numMessages);
    if (t>0)
        recordScalar("messages/sec", numMessages/t);
}
void EtherBus::handleMessage ( cMessage *  msg) [protected, virtual]
{
    if (!msg->isSelfMessage())
    {
        // Handle frame sent down from the network entity
        int tapPoint = msg->getArrivalGate()->getIndex();
        EV << "Frame " << msg << " arrived on tap " << tapPoint << endl;

        // create upstream and downstream events
        if (tapPoint>0)
        {
            // start UPSTREAM travel
            // if goes downstream too, we need to make a copy
            cMessage *msg2 = (tapPoint<taps-1) ? (cMessage *)msg->dup() : msg;
            msg2->setKind(UPSTREAM);
            msg2->setContextPointer(&tap[tapPoint-1]);
            scheduleAt(simTime()+tap[tapPoint].propagationDelay[UPSTREAM], msg2);
        }
        if (tapPoint<taps-1)
        {
            // start DOWNSTREAM travel
            msg->setKind(DOWNSTREAM);
            msg->setContextPointer(&tap[tapPoint+1]);
            scheduleAt(simTime()+tap[tapPoint].propagationDelay[DOWNSTREAM], msg);
        }
        if (taps==1)
        {
            // if there's only one tap, there's nothing to do
            delete msg;
        }
    }
    else
    {
        // handle upstream and downstream events
        int direction = msg->getKind();
        BusTap *thistap = (BusTap *) msg->getContextPointer();
        int tapPoint = thistap->id;

        EV << "Event " << msg << " on tap " << tapPoint << ", sending out frame\n";

        // send out on gate
        bool isLast = (direction==UPSTREAM) ? (tapPoint==0) : (tapPoint==taps-1);
        cPacket *msg2 = isLast ? PK(msg) : PK(msg->dup());
        send(msg2, "ethg$o", tapPoint);

        // if not end of the bus, schedule for next tap
        if (isLast)
        {
            EV << "End of bus reached\n";
        }
        else
        {
            EV << "Scheduling for next tap\n";
            int nextTap = (direction==UPSTREAM) ? (tapPoint-1) : (tapPoint+1);
            msg->setContextPointer(&tap[nextTap]);
            scheduleAt(simTime()+tap[tapPoint].propagationDelay[direction], msg);
        }
    }
}
void EtherBus::initialize ( ) [protected, virtual]
{
    numMessages = 0;
    WATCH(numMessages);

    propagationSpeed = par("propagationSpeed").doubleValue();

    // initialize the positions where the hosts connects to the bus
    taps = gateSize("ethg");

    // read positions and check if positions are defined in order (we're lazy to sort...)
    std::vector<double> pos;
    tokenize(par("positions").stringValue(), pos);
    int numPos = pos.size();
    if (numPos>taps)
        EV << "Note: `positions' parameter contains more values ("<< numPos << ") than "
              "the number of taps (" << taps << "), ignoring excess values.\n";
    else if (numPos<taps && numPos>=2)
        EV << "Note: `positions' parameter contains less values ("<< numPos << ") than "
              "the number of taps (" << taps << "), repeating distance between last 2 positions.\n";
    else if (numPos<taps && numPos<2)
        EV << "Note: `positions' parameter contains too few values, using 5m distances.\n";

    tap = new BusTap[taps];

    int i;
    double distance = numPos>=2 ? pos[numPos-1]-pos[numPos-2] : 5;
    for (i=0; i<taps; i++)
    {
        tap[i].id = i;
        tap[i].position = i<numPos ? pos[i] : i==0 ? 5 : tap[i-1].position+distance;
    }
    for (i=0; i<taps-1; i++)
    {
        if (tap[i].position > tap[i+1].position)
            error("Tap positions must be ordered in ascending fashion, modify 'positions' parameter and rerun\n");
    }

    // Calculate propagation of delays between tap points on the bus
    for (i=0; i<taps; i++)
    {
        // Propagation delay between adjacent tap points
        if (i == 0) {
            tap[i].propagationDelay[UPSTREAM] = 0;
            tap[i].propagationDelay[DOWNSTREAM] = (tap[i+1].position - tap[i].position)/propagationSpeed;
        }
        else if (i == taps-1) {
            tap[i].propagationDelay[UPSTREAM] = tap[i-1].propagationDelay[DOWNSTREAM];
            tap[i].propagationDelay[DOWNSTREAM] = 0;
        }
        else {
            tap[i].propagationDelay[UPSTREAM] = tap[i-1].propagationDelay[DOWNSTREAM];
            tap[i].propagationDelay[DOWNSTREAM] = (tap[i+1].position - tap[i].position)/propagationSpeed;;
        }
    }

    // Prints out data of parameters for parameter checking...
    EV << "Parameters of (" << getClassName() << ") " << getFullPath() << "\n";
    EV << "propagationSpeed: " << propagationSpeed << "\n";
    for (i=0; i<taps; i++)
    {
        EV << "tap[" << i << "] pos: " << tap[i].position <<
              "  upstream delay: " << tap[i].propagationDelay[UPSTREAM] <<
              "  downstream delay: " << tap[i].propagationDelay[DOWNSTREAM] << endl;
    }
    EV << "\n";

    // autoconfig: tell everyone that bus supports only 10Mb half-duplex
    EV << "Autoconfig: advertising that we only support 10Mb half-duplex operation\n";
    for (i=0; i<taps; i++)
    {
        EtherAutoconfig *autoconf = new EtherAutoconfig("autoconf-10Mb-halfduplex");
        autoconf->setHalfDuplex(true);
        autoconf->setTxrate(10000000); // 10Mb
        send(autoconf,"ethg$o",i);
    }
}
void EtherBus::tokenize ( const char *  str,
std::vector< double > &  array 
) [protected, virtual]

Referenced by initialize().

{
    char *str2 = opp_strdup(str);
    if (!str2) return;
        char *s = strtok(str2, " ");
    while (s)
    {
        array.push_back(atof(s));
        s = strtok(NULL, " ");
    }
    delete [] str2;
}

Member Data Documentation

long EtherBus::numMessages [protected]

Referenced by finish(), and initialize().

double EtherBus::propagationSpeed [protected]

Referenced by initialize().

int EtherBus::taps [protected]

Referenced by handleMessage(), and initialize().


The documentation for this class was generated from the following files: