EPONImplementationforOMNet++  0.8Beta
OLTQPerLLiDBase Class Reference

OLT_Q_mgmt_PerLLiD creates on queue per MAC-LLID tuple. More...

#include <OLTQPerLLiDBase.h>

Inheritance diagram for OLTQPerLLiDBase:
OLT_QPL_RR OLTQPerLLiDBase_P

List of all members.

Public Member Functions

 OLTQPerLLiDBase ()
virtual ~OLTQPerLLiDBase ()

Protected Types

typedef std::vector
< QueuePerMacLLid
PonQueues
 The vector holding the queues.

Protected Member Functions

virtual void initialize ()
virtual void finish ()
virtual void handleMessage (cMessage *msg)
virtual void processFrameFromHigherLayer (cMessage *msg)
virtual void processFrameFromLowerLayer (cMessage *msg)
virtual void processMPCP (EthernetIIFrame *frame)
 Do MPCP stuff.
virtual void handleRegTimeOut (cMessage *msg)
virtual void handleMPCPReport (MPCPReport *msg)
virtual void doOnuRegistration (MACAddress mac)
virtual cModule * findModuleUp (const char *name)
virtual void createONU_Q (ONUTableEntry &en)
 Create a new queue for an entry in the ONU table.
virtual bool existsInPONQueues (mac_llid ml)
virtual void DoUpstreamDBA ()
 This method calculates the upstream timers for each ONU in the ONUTable.
virtual void sendMPCPGateReg ()
 Generate and send the initial gate message.
virtual void SendGateUpdates ()
 Generate MPCPGate messages announcing the transmission times to the ONUs.
virtual void checkIfAllEmpty ()
 Check is all the Qs are empty.
int getIndexForLLID (uint16_t llid)
void addSortedMacLLID (QueuePerMacLLid tmp_qpml)
 Add a new queue to the pon_queues sorted by priority Higher priority Qs go up.
QueuePerMacLLidgetFastestQForMac (const MACAddress &mac)
 Get the higher priority queue for the specified MAC address.
QueuePerMacLLidgetFastestQForMac (const std::string &mac)
 Get the higher priority queue for the specified MAC address.
uint16_t getFastestLLiDForMac (const std::string &mac)
virtual bool isEmpty ()
uint64_t getSuperSlot_ns ()
 Return the Super Slot length (ns)
double getSuperSlot_sec ()
 Return the Super Slot length (sec).

Protected Attributes

ONUTableonutbl
vector< ONUTableEntrytemptbl
vector< cMessage * > pendingAck
SrvListserviceList
double regAckTimeOut
uint16_t slotLength
uint16_t slotNumber
int32_t regTimeInt
int queueLimit
uint64_t datarateLimit
PonQueues pon_queues
bool allQsEmpty
int nextQIndex

Detailed Description

OLT_Q_mgmt_PerLLiD creates on queue per MAC-LLID tuple.

Here is actually done all the bandwidth allocation and timer calculation. Also this class handles the ONU registration and the updates the ONU table. Thus some MPCP messages are generated from here and timeouts are defined here. Now since all the time management is done here... we have to define the number of time slots and the time slot duration. Finally this class is aware of any services in this network and thus has a pointer to the SrvList class (if any module is available in the scenario else it is NULL).

The whole idea is to extend this class and create your own bandwidth allocation algorithms. The default behavior of this class is to apply round robin on the queues (per frame). The only thing considered is the priority (not strictly) and happens because the queues are sorted based on the service priority.

Basic methods that would be useful to override when you extend are explained below.


Member Typedef Documentation

typedef std::vector<QueuePerMacLLid> OLTQPerLLiDBase::PonQueues [protected]

The vector holding the queues.


Constructor & Destructor Documentation

                                 {
      for (uint32_t i=0; i<pendingAck.size(); i++){
            cancelAndDelete((cMessage *)pendingAck[i]);
      }

      for (uint32_t i=0; i<pon_queues.size(); i++){
            pon_queues[i].clean();
      }
      pon_queues.clear();
}

Member Function Documentation

void OLTQPerLLiDBase::addSortedMacLLID ( QueuePerMacLLid  tmp_qpml) [protected]

Add a new queue to the pon_queues sorted by priority Higher priority Qs go up.

                                                              {
      // Just add it if empty...
      if (pon_queues.empty()) {
            pon_queues.push_back(tmp_qpml);
            return;
      }

      // Add in the proper position
      for (PonQueues::iterator it = pon_queues.begin(); it != pon_queues.end(); it++){
            if ((*it).prior < tmp_qpml.prior){
                  pon_queues.insert(it, tmp_qpml);
                  return;
            }
      }

      // If not added till here... add to the end
      pon_queues.push_back(tmp_qpml);
}
void OLTQPerLLiDBase::checkIfAllEmpty ( ) [protected, virtual]

Check is all the Qs are empty.

IF yes set the all empty variable. This must be done after the frame request from the lower layer.

                                     {
      if (pon_queues.size() == 0) allQsEmpty = true;
      if (pon_queues[0].isEmpty()
                  && pon_queues.size() == 1) allQsEmpty = true;


      for (uint32_t i=0; i< pon_queues.size(); i++){
            if (!pon_queues[i].isEmpty()){
                  allQsEmpty = false;
                  return;
            }
      }

      allQsEmpty = true;
}
void OLTQPerLLiDBase::createONU_Q ( ONUTableEntry en) [protected, virtual]

Create a new queue for an entry in the ONU table.

This method also calls the DoUpstreamDBA() to calculate the new granted times and finally calls the SendGateUpdates() to announce these to the ONUs.

                                                  {

      mac_llid tmp_ml;
      tmp_ml.mac = en.getId();
      // Scan llids
      for (int j=0; j<en.getLLIDsNum(); j++){

            tmp_ml.llid = en.getLLID(j);

            QueuePerMacLLid tmp_q;
            tmp_q.ml = tmp_ml;
            char tmp_name[20];
            sprintf(tmp_name,"Default-%d",tmp_ml.llid);

            tmp_q.prior = 0.0;

            if (serviceList && (int)serviceList->size() > j) {
                  sprintf(tmp_name,"%s-%d",serviceList->at(j).name.c_str(),tmp_ml.llid);
                  tmp_q.prior = serviceList->at(j).priority;
                  tmp_q.isDefault = false;
            }

            // Use the last LLiD as the default
            if ( en.getLLIDsNum() -1 == j){
                  EV << "Registering the default LLiD (BE) to "<<tmp_ml.llid<<endl;
                  sprintf(tmp_name,"%s-%d","Default",tmp_ml.llid);
                  tmp_q.prior = 0.0001;
                  tmp_q.isDefault = true;
            }

            tmp_q.setServiceName(tmp_name);
            addSortedMacLLID(tmp_q);


      }

      // Do Upstream DBA and calculate tx timers
      DoUpstreamDBA();
      // Announce these timers to the ONUs
      SendGateUpdates();
}
void OLTQPerLLiDBase::doOnuRegistration ( MACAddress  mac) [protected, virtual]
                                                     {
      // Find Entry Index....
      for (uint32_t i=0; i<temptbl.size(); i++){
            if (temptbl.at(i).getId() == mac){
                  EV << "OLTMacCtl: ONU (MAC: "<<mac<<") request "<< i << " Registered"<<endl;
                  // Clear message and move tb entry to the global
                  cancelAndDelete(pendingAck[i]);
                  pendingAck.erase(pendingAck.begin()+i);

                  // Copy
                  ONUTableEntry en=temptbl.at(i);
                  onutbl->addONU(en);

                  // Remove from tmp
                  //temptbl.removeONU(i);
                  temptbl.erase(temptbl.begin()+i);
                  createONU_Q(en);

                  break;
            }
      }


}
void OLTQPerLLiDBase::DoUpstreamDBA ( ) [protected, virtual]

This method calculates the upstream timers for each ONU in the ONUTable.

Fair Allocation per MAC-LLID with LIMIT.

This could be overridden to change the default behavior. The default is fair allocation per ONU.

In addition this method scale down the simulation data rates. If datarateLimit is set > 0 then only this is going to be allocated to the ONUs.

FOR NON-POLLING ALGORITHMS 2 Basic RULES At the end this method should:

  • Have set the _total_ length and start registers on the ONU table
  • Call SendGateUpdates() to announce to ONUs

FOR POLLING ALGORITHMS this method should:

  • Be called periodically to handle the next ONU (poll)
  • It should schedule the MPCP GATE sending
  • Example implementation: sendSingleGate() notifies ONU_i and calls doUpstreamDBA for ONU i+1 (which in turn schedules the next GATE). This is the ONLINE approach...

Reimplemented in OLTQPerLLiDBase_P.

                                   {
      EV <<"OLTQPerLLiDBase::DoUpstreamDBA"<<endl;
      /*
       * We do not need to allocate for the broadcast
       * Q on the upstream... so -1. Downstream is
       * different...
       */
      int numOfMACsLLIDs = pon_queues.size()-1;

      // Check IDLE
      if (numOfMACsLLIDs == 0) return;


      double each_llid = 0;


      if (datarateLimit <= 0){
            // This was the old one, divided all time to num of MACs/LLiDs
            double slots_per_ml = (double) slotNumber/numOfMACsLLIDs;
            each_llid = slots_per_ml*slotLength/16;
      } else{
            // NEW!!
            double superSlotNS = slotNumber*slotLength; // SuperSlot Length in ns
            double dataratePerSS = ((double)datarateLimit * superSlotNS ) / pow(10,9); // bps (NOT Mbps)
            each_llid = ceil(dataratePerSS/(numOfMACsLLIDs*16)); // ns -> ns16
      }

      /*
       *  NOTE: CAUTION:
       *   - ONUz _should_ handle it correctly (register shift also)
       *   - CODE FOR REGISTER SHIFT IS IN THE ONUz SO DO NOT CALCULATE IT HERE...
       */
      uint32_t curpointer=regTimeInt;

      // For each ONU generate start and length values
      for (int i=0; i<onutbl->getTableSize(); i++){
            CommitedTime ct;
            ct.length=each_llid*onutbl->getEntry(i)->getLLIDsNum();
            ct.start=curpointer;
            onutbl->getEntry(i)->setComTime(ct);
            curpointer+=each_llid*onutbl->getEntry(i)->getLLIDsNum();
      }

}
bool OLTQPerLLiDBase::existsInPONQueues ( mac_llid  ml) [protected, virtual]
                                                  {
      // MY FIND...
      bool found=false;
      for(PonQueues::const_iterator it = pon_queues.begin(); it != pon_queues.end(); ++it)
      {
            if ((mac_llid)it->ml == ml) {
                  found=true;
                  break;
            }
      }

      return found;
}
cModule * OLTQPerLLiDBase::findModuleUp ( const char *  name) [protected, virtual]
                                                        {
      cModule *mod = NULL;
      for (cModule *curmod=this; !mod && curmod; curmod=curmod->getParentModule())
           mod = curmod->getSubmodule(name);
      return mod;
}
void OLTQPerLLiDBase::finish ( ) [protected, virtual]
                            {
      simtime_t t = simTime();

      for (uint32_t i=0; i<pon_queues.size(); i++){
            std::string srvName =pon_queues[i].getServiceName();
            std::string name=srvName +" BytesDropped";
            recordScalar(name.c_str(), pon_queues[i].vec->numBytesDropped  );
            name=srvName +" BytesSent";
            recordScalar(name.c_str(), pon_queues[i].vec->numBytesSent  );

            if (t>0)
            {
                  name=srvName +" bytes dropped/sec";
                  recordScalar(name.c_str(), pon_queues[i].vec->numBytesDropped/t);
                  name=srvName +" bytes sent/sec";
                  recordScalar(name.c_str(), pon_queues[i].vec->numBytesSent/t);
            }
      }

      // Check and Log datarateLimit
      if (datarateLimit == 0)
            datarateLimit = 1000 * pow(10,6);

      recordScalar("DataRateLimit", datarateLimit);
}
uint16_t OLTQPerLLiDBase::getFastestLLiDForMac ( const std::string &  mac) [protected]
                                                          {

      for (uint32_t i=0; i<pon_queues.size(); i++){
            if (pon_queues[i].ml.mac.str() == mac) return pon_queues[i].ml.llid;
      }
      return 0;
}
QueuePerMacLLid * OLTQPerLLiDBase::getFastestQForMac ( const MACAddress &  mac) [protected]

Get the higher priority queue for the specified MAC address.

Since Qs are sorted, the first match is returned

                                                        {
      for (uint32_t i=0; i<pon_queues.size(); i++){
            if (pon_queues[i].ml.mac.compareTo(mac) == 0)
                  return &pon_queues[i];
      }
      return NULL;
}
QueuePerMacLLid * OLTQPerLLiDBase::getFastestQForMac ( const std::string &  mac) [protected]

Get the higher priority queue for the specified MAC address.

Since Qs are sorted, the first match is returned

                                                       {

      for (uint32_t i=0; i<pon_queues.size(); i++){
            if (pon_queues[i].ml.mac.str() == mac) return &pon_queues[i];
      }
      return NULL;
}
int OLTQPerLLiDBase::getIndexForLLID ( uint16_t  llid) [protected]
                                                 {
      for (uint32_t i=0; i<pon_queues.size(); i++)
            if (pon_queues[i].ml.llid == llid) return i;

      return -1;
}
uint64_t OLTQPerLLiDBase::getSuperSlot_ns ( ) [protected]

Return the Super Slot length (ns)

                                         {
      return slotLength*slotNumber;
}
double OLTQPerLLiDBase::getSuperSlot_sec ( ) [protected]

Return the Super Slot length (sec).

Useful for calculating data rates per second.

                                        {
      return ((double)getSuperSlot_ns())/pow(10,9);
}
void OLTQPerLLiDBase::handleMessage ( cMessage *  msg) [protected, virtual]

Reimplemented in OLTQPerLLiDBase_P.

{

      // Self Message
      if (msg->isSelfMessage())
      {
            EV << "Self-message " << msg << " received\n";
            if (msg->getKind() == ONUPENACK)
                  handleRegTimeOut(msg);
            else
                  EV << "UnKnown Self Message\n";

            return;
      }

      // Network Message
      cGate *ingate = msg->getArrivalGate();
      EV << "Frame " << msg << " arrived on port " << ingate->getName() << "...\n";



      if (ingate->getId() ==  gate( "lowerLayerIn")->getId()){
            processFrameFromLowerLayer(msg);
      }
      else if (ingate->getId() ==  gate( "upperLayerIn")->getId()){
            processFrameFromHigherLayer(msg);
      }else{
            EV << "OLTMacCtl: Message came FROM THE WRONG DIRRECTION???? Dropping\n";
            delete msg;
      }
}
void OLTQPerLLiDBase::handleMPCPReport ( MPCPReport msg) [protected, virtual]
                                                     {
      // Get the bit map... altho in simulation we do not
      // need it cause we can have the length from the lists
      //uint8_t bitMap = msg->getBitMap();

      // Get entry
      ONUTableEntry * en = onutbl->getEntry(msg->getSrc());

      uint64_t totalreq=0;
      for (uint i=0; i<msg->getQInfoArraySize(); i++){
            // No need to convert here...  FIXME: hardcoded line rate 1G
            //en->req[i] = MPCPTools::ns16ToBits(msg->getQInfo(i), 1);
            en->req[i] = msg->getQInfo(i);
            totalreq+=en->req[i];
      }

      en->totalReq = totalreq;

}
void OLTQPerLLiDBase::handleRegTimeOut ( cMessage *  msg) [protected, virtual]
                                                   {
      // Find Message Index....
      for (uint32_t i=0; i<pendingAck.size(); i++){
            if (pendingAck[i] == msg){
                  EV << "OLTMacCtl: ONU request "<< i << " TimeOut"<<endl;
                  // Clear message and tb entry
                  cancelAndDelete((cMessage *)pendingAck[i]);
                  pendingAck.erase(pendingAck.begin()+i);
                  //temptbl.removeONU(i);
                  temptbl.erase(temptbl.begin()+i);
            }
      }
}
void OLTQPerLLiDBase::initialize ( ) [protected, virtual]

Reimplemented in OLTQPerLLiDBase_P, and OLT_QPL_RR.

{
      // ONU table
      onutbl = NULL;
      onutbl = dynamic_cast<ONUTable *>( findModuleUp("onuTable"));
      if (!onutbl)
            error("Shit... no ONU table found ?!?!");


      // Service List
      serviceList=NULL;
      if (dynamic_cast<ServiceConfig *>( findModuleUp("serviceConfig")) != NULL){
            serviceList = &(dynamic_cast<ServiceConfig *>( findModuleUp("serviceConfig"))->srvs);
      }

      // Parameters
      regAckTimeOut = par("regAckTimeOut");
      regAckTimeOut/=1000;
      // in ns
      slotLength=par("slotLength");
      slotNumber=par("slotNumber");
      // Convert to ns16 time
      // (to be added in the MPCP frames)
      regTimeInt = par("regTimeInt");
      regTimeInt*=(double)1000 / 16;
      queueLimit = par("queueLimit");

      // Create Q for BroadCasts
      QueuePerMacLLid tmp_qpml;
      tmp_qpml.setServiceName("BroadCast");
      tmp_qpml.prior = 0.0;
      tmp_qpml.ml.llid = LLID_EPON_BC;
      addSortedMacLLID(tmp_qpml);

      allQsEmpty=true;
      nextQIndex = 0;


      datarateLimit=(uint64_t)(par("datarateLimit").doubleValue()*pow(10,6));
      if (datarateLimit>pow(10,10))
            error("Ensure that datarateLimit parameter is not negative...");


      // WATCH
      WATCH_VECTOR(pon_queues);
      WATCH(allQsEmpty);

      sendMPCPGateReg();
}
bool OLTQPerLLiDBase::isEmpty ( ) [protected, virtual]
                             {
      checkIfAllEmpty();
      return allQsEmpty;
}
void OLTQPerLLiDBase::processFrameFromHigherLayer ( cMessage *  msg) [protected, virtual]
                                                              {
      EV << "OLT_Q_mgmt_PerLLiD: Incoming from higher layer...\n";

      /*
       * Notify the lower layer.
       */
      if (allQsEmpty){
            EV << "Direct tx: "<<msg<<endl;
            send(msg, "lowerLayerOut");
            return;
      }

      EPON_LLidCtrlInfo *nfo = dynamic_cast<EPON_LLidCtrlInfo *>(msg->getControlInfo());

      // If frame has no info or is BC add to the BroadCast Q
      int Q_index=-1;
      if (!nfo || nfo->llid == LLID_EPON_BC){
            Q_index = getIndexForLLID(LLID_EPON_BC);
      }else{
            Q_index = getIndexForLLID(nfo->llid);
      }

      // Check if we can forward frame
      if (Q_index == -1){
            EV << "*** WRONG LLID : DROPPING" <<endl;
            delete msg;
            return;
      }

      // Update the incoming rate BEFORE discarding message
      // in case the Q is full.
      cPacket *pkt = dynamic_cast<cPacket *>(msg);
      pon_queues[Q_index].vec->numIncomingBits+=pkt->getBitLength();

      // Check that is not full
      if (pon_queues[Q_index].length() >= pon_queues[Q_index].queueLimit){
            pon_queues[Q_index].vec->numBytesDropped+=pkt->getByteLength();
            pon_queues[Q_index].vec->recordVectors();
            delete msg;
            return;
      }else{
            // Record the incoming bytes
            pon_queues[Q_index].vec->recordVectors();
      }
      // Add it
      pon_queues[Q_index].insert(dynamic_cast<cPacket *>(msg));



}
void OLTQPerLLiDBase::processFrameFromLowerLayer ( cMessage *  msg) [protected, virtual]
                                                             {
      EV << "OLT_Q_mgmt_PerLLiD: Incoming from lower layer\n";

      EthernetIIFrame * frame = dynamic_cast<EthernetIIFrame *>(msg);
      if (frame && frame->getEtherType() == MPCP_TYPE){
            processMPCP(frame);
            return;
      }

      // Not Control
      send(msg,"upperLayerOut");
}
void OLTQPerLLiDBase::processMPCP ( EthernetIIFrame *  frame) [protected, virtual]

Do MPCP stuff.

This handles the ONU registration and REPORT messages

                                                        {
      EV << "OLTMacCtl: MPCP Frame processing\n";
      MPCP * mpcp = check_and_cast<MPCP *>(frame);
      switch (mpcp->getOpcode())
      {
            case MPCP_REGREQ:
            {
                  MPCPRegReq * req = check_and_cast<MPCPRegReq *>(frame);
                  MPCPRegister *rspframe = new MPCPRegister();
                  rspframe->setOpcode(MPCP_REGISTER);
                  rspframe->setName("MPCPRegister");
                  rspframe->setEtherType(MPCP_TYPE);
                  rspframe->setDest(req->getSrc());
                  rspframe->setPtpNumReg(req->getPtpNumReq());

                  EV << "Log the LLIDs temporarly and add a TO timer\n";

                  ONUTableEntry te;
                  te.setId(req->getSrc());
                  // Parse and set LLIDS
                  rspframe->setLLIDsArraySize(req->getPtpNumReq());

                  for (int i=0; i<req->getPtpNumReq(); i++){
                        // 0xFFF = 4095 intrand -> [0-4095)
                        uint32_t llid_tmp=(uint32_t)intrand(4095);
                        while (te.addLLID(llid_tmp) <0 ){
                              EV << "*** RANDOM GEN FAILED!!!!???\n";
                              llid_tmp=(uint32_t)intrand(4095);
                        }

                        rspframe->setLLIDs(i,llid_tmp);
                  }

                  rspframe->setByteLength(MPCP_HEADER_LEN+MPCP_LIST_LEN+req->getPtpNumReq()*MPCP_LLID_LEN);

                  // TODO: add TimeStamp!
                  temptbl.push_back(te);


                  // NOTE: do NOT send... enqueue
                  //send(rspframe,"lowerLayerOut");
                  processFrameFromHigherLayer(rspframe);

                  // Create and add TO self message
                  cMessage *tmpmsg=new cMessage("OnuTOMsg", ONUPENACK);
                  pendingAck.push_back(tmpmsg);
                  scheduleAt(simTime()+regAckTimeOut, tmpmsg);

                  break;
            }
            case MPCP_REGACK:
            {
                  doOnuRegistration(mpcp->getSrc());
                  break;
            }
            case MPCP_REPORT:
            {
                  MPCPReport * rep = dynamic_cast<MPCPReport *>(frame);
                  handleMPCPReport(rep);
                  break;
            }
            default:
                  EV << "Unrecognized MPCP OpCode";
      };

      delete frame;
}
void OLTQPerLLiDBase::SendGateUpdates ( ) [protected, virtual]

Generate MPCPGate messages announcing the transmission times to the ONUs.

(For all the ONUs in the ONUTable)

This method should be called at the end of DoUpstreamDBA ONLY is the algorithm is NON-POLLING (burst) BASED. Polling algorithms have to override the DoUpstreamDBA to handle both allocation and GATE/GRANDs...

Reimplemented in OLTQPerLLiDBase_P.

                                     {

      for (int i=onutbl->getTableSize()-1; i>=0; i--){
            MPCPGate *gt = new MPCPGate();
            gt->setName("MPCPGate");
            gt->setEtherType(MPCP_TYPE);
            gt->setOpcode(MPCP_GATE);
            MPCPTools::setGateLen(*gt, 1);

            gt->setSlotTime(slotLength);
            gt->setSlotsNum(slotNumber);

            gt->setDest(onutbl->getEntry(i)->getId());
            gt->setStartTime(0, onutbl->getEntry(i)->getComTime().start);
            gt->setDuration(0, onutbl->getEntry(i)->getComTime().length);

            // Header + List + (start + Len) + slotNum + slotLen
            gt->setByteLength(MPCP_HEADER_LEN+MPCP_LIST_LEN+MPCP_TIMERS_LEN+MPCP_SLOTINFO_LEN);


            // Send directly
            send(gt, "lowerLayerOut");
      }
}
void OLTQPerLLiDBase::sendMPCPGateReg ( ) [protected, virtual]

Generate and send the initial gate message.

This message is used for the registration of the ONUs.

                                     {
      MPCPGate *gt = new MPCPGate();
      gt->setEtherType(MPCP_TYPE);
      gt->setOpcode(MPCP_GATE);
      gt->setName("MPCPGate(Reg)");
      MPCPTools::setGateLen(*gt, 1);

      gt->setDuration(0, regTimeInt);
      gt->setDest(MACAddress::BROADCAST_ADDRESS);
      gt->setSlotTime(slotLength);
      gt->setSlotsNum(slotNumber);

      // Header + List + (start + Len) + slotNum + slotLen
      gt->setByteLength(MPCP_HEADER_LEN+MPCP_LIST_LEN+MPCP_TIMERS_LEN+MPCP_SLOTINFO_LEN);

      send(gt, "lowerLayerOut");

}

Member Data Documentation

bool OLTQPerLLiDBase::allQsEmpty [protected]
uint64_t OLTQPerLLiDBase::datarateLimit [protected]
int OLTQPerLLiDBase::nextQIndex [protected]
vector<cMessage *> OLTQPerLLiDBase::pendingAck [protected]
int OLTQPerLLiDBase::queueLimit [protected]
double OLTQPerLLiDBase::regAckTimeOut [protected]
int32_t OLTQPerLLiDBase::regTimeInt [protected]
uint16_t OLTQPerLLiDBase::slotLength [protected]
uint16_t OLTQPerLLiDBase::slotNumber [protected]

The documentation for this class was generated from the following files:
 All Classes Files Functions Variables Typedefs Friends Defines