INET Framework for OMNeT++/OMNEST
AnsaQosSystem Class Reference

#include <AnsaQosSystem.h>

Inheritance diagram for AnsaQosSystem:
PassiveQueueBase IPassiveQueue

List of all members.

Public Member Functions

 AnsaQosSystem ()
 ~AnsaQosSystem ()
void loadConfigFromXML ()
int getLowestSn ()
AnsaSubQueues::iterator getSubQueueBySn (int sn)
void substractSnInAllQueues (int sn)
void setPQSubQueue (std::string id, cXMLElement *pql, int len)
void setCQSubQueue (int id, cXMLElement *pql)
void initSubQueueVectors (ANSAQOS::QueueType type)

Protected Member Functions

virtual void initialize (int stage)
virtual bool enqueue (cMessage *msg)
virtual cMessage * dequeue ()
virtual void sendOut (cMessage *msg)
virtual int numInitStages () const

Protected Attributes

AnsaSubQueues subQueues
cGate * outGate
cOutVector qlenVec
cOutVector dropVec
cOutVector * subqlenVec
cOutVector * subdropVec
ANSAQOS::QueueConfig QueueInfo

Detailed Description

Definition at line 275 of file AnsaQosSystem.h.


Constructor & Destructor Documentation

Definition at line 291 of file AnsaQosSystem.h.

Definition at line 32 of file AnsaQosSystem.cc.

{
  for (AnsaSubQueues::iterator sbqIt = subQueues.begin(); sbqIt != subQueues.end(); ++sbqIt)
  {
    sbqIt->clearSubQueue();
  }
  
  delete[] subqlenVec;
  delete[] subdropVec;
}

Member Function Documentation

cMessage * AnsaQosSystem::dequeue ( ) [protected, virtual]

Returns a packet from the queue, or NULL if the queue is empty.

Implements PassiveQueueBase.

Definition at line 453 of file AnsaQosSystem.cc.

{
    if(QueueInfo.getCurrentHold() <= 0)
    {
        return NULL; // fronta je prazdna
    }
    
    cMessage *msg; cPacket *pkt;
    int sn,id;  
    AnsaSubQueues::iterator queueIt;
    
    switch (QueueInfo.getQueueType())
    {
      /* FIFO fronta ma len jednu "podfrontu" z ktorej sa vyberie prvy paket */
      case ANSAQOS::Q_FIFO : 
        msg = subQueues.begin()->dequeue();
        break;
      /* Vo WFQ fronte sa vyberie paket s najmensim sekvencnym cislom.
         V pripade, ze podfronta sa vyprazdni, tak je odstranena.
         Aby nedoslo k preteceniu hodnoty sekvencneho cisla, tak je po kazdom 
         vybrani paketu jeho sekvencne cislo odcitane od ostatnych */
      case ANSAQOS::Q_WFQ :
        sn = getLowestSn();
        queueIt = getSubQueueBySn(sn);
                
        msg = queueIt->dequeue();
        if(queueIt->isQueueEmpty())
        {
          subQueues.erase(queueIt);
          QueueInfo.remNumQueues();
        }
        substractSnInAllQueues(getLowestSn());
        break;
      /* PQ fronta obsahuje 4 fronty, ktore prechadza podla priority
         prvy paket, na ktory narazi je vybrany */
      case ANSAQOS::Q_PQ :
          for (AnsaSubQueues::iterator queueIt = subQueues.begin(); queueIt != subQueues.end(); ++queueIt)
          {
            if(!queueIt->isQueueEmpty())
            {
              msg = queueIt->dequeue();
              break;
            }
          }
        break;
      /* CQ obsahuje 16 front, ktore su prechadzane round robin. 
         Pakety su z fronty vyberane az dovtedy, kym obsahuje dostatocny 
         pocet bajtov alebo je fronta prazdna*/
      case ANSAQOS::Q_CQ :
          while (subQueues[QueueInfo.getCurrentCQQueueId()].isQueueEmpty())
          { // najdenie prvej neprazdnej fronty
            subQueues[QueueInfo.getCurrentCQQueueId()].setActualBytes();
            QueueInfo.addCurrentCQQueueId();
          }
          
          id = QueueInfo.getCurrentCQQueueId();
          msg = subQueues[id].dequeue(); // vybranie paketu z fronty
          pkt = dynamic_cast<cPacket *> (msg->dup());
          subQueues[id].remActualBytes(pkt->getByteLength()); // odstanenie bajtov z fronty
          delete pkt;
          
          if(subQueues[id].getActualBytes() <= 0)
          { // nedostatocny pocet bajtov.. prechod na dalsiu frontu a reset bajtov
            subQueues[id].setActualBytes();
            QueueInfo.addCurrentCQQueueId();  
          }
        break; 
      default :
        msg = NULL;
        break;
    }

    QueueInfo.remCurrentHold();
    return msg;
}
bool AnsaQosSystem::enqueue ( cMessage *  msg) [protected, virtual]

Inserts packet into the queue or the priority queue, or drops it (or another packet). Returns true if a packet was dropped.

Implements PassiveQueueBase.

Definition at line 403 of file AnsaQosSystem.cc.

{   
    if(QueueInfo.getCurrentHold() < QueueInfo.getHoldCapacity())
    { // je miesto vo fronte
      for(AnsaSubQueues::iterator sbqIt = subQueues.begin(); sbqIt != subQueues.end(); ++sbqIt)
      { // prechadza vsetky podfronty
        short res = sbqIt->enqueue(msg,true);
        if(res == ANSAQOS::QUEUED)
        {
          QueueInfo.addCurrentHold();
          return false; // paket bol vlozeny do fronty
        }
        else if(res == ANSAQOS::NOTQUEUED)
        {
          QueueInfo.addDroped();
          delete msg;
          return true;  // paket zahodeny lebo sa nevojde do podfronty
        }
      }
      if(QueueInfo.getQueueType() == ANSAQOS::Q_WFQ)
      { // vo WFQ neexistuje podfronta pre dany tok
        if(QueueInfo.getNumQueues() < QueueInfo.getMaxQueues())
        { // je mozne vytvorit podfrontu a vlozit do nej paket 
          subQueues.push_back(ANSAQOS::SubQueue(msg, QueueInfo.getCdt()));
          QueueInfo.addNumQueues();
          QueueInfo.addCurrentHold();
          return false;
        }
      }
      else if(QueueInfo.getQueueType() == ANSAQOS::Q_PQ || QueueInfo.getQueueType() == ANSAQOS::Q_CQ)
      { // u PQ a CQ moznost vlozenia paketu do defaultnej fronty 
        if (subQueues[QueueInfo.getDefaultQueueId()-1].enqueue(msg,false) == ANSAQOS::QUEUED)
        {
          QueueInfo.addCurrentHold();
          return false;
        }
      }  
    }

    QueueInfo.addDroped();
    delete msg;  
    return true; //paket bol zahodeny
}

Definition at line 302 of file AnsaQosSystem.cc.

Referenced by dequeue().

{
    int sn = -1;
    
    for (AnsaSubQueues::iterator sbqIt = subQueues.begin(); sbqIt != subQueues.end(); ++sbqIt)
    {
      if(sn == -1 && !sbqIt->isQueueEmpty())
      {
        sn = sbqIt->getLowestSn();
      }
      else if(!sbqIt->isQueueEmpty() && sbqIt->getLowestSn() < sn )
      {
        sn = sbqIt->getLowestSn();
      }
    }  
    return sn;
}
AnsaSubQueues::iterator AnsaQosSystem::getSubQueueBySn ( int  sn)

Definition at line 370 of file AnsaQosSystem.cc.

Referenced by dequeue().

{
    for (AnsaSubQueues::iterator sbqIt = subQueues.begin(); sbqIt != subQueues.end(); ++sbqIt)
    {
      if(sn == sbqIt->getLowestSn())
      {
        return sbqIt;
      }
    }
    return subQueues.end();
}
void AnsaQosSystem::initialize ( int  stage) [protected, virtual]

Definition at line 49 of file AnsaQosSystem.cc.

{
  if(stage == 0)
  {
    PassiveQueueBase::initialize();

    outGate = gate("out");
    
    WATCH(QueueInfo);
    WATCH_VECTOR(subQueues);
  }
  else if (stage == 4)
  {
    // nacitanie konfiguracie zo XML
    loadConfigFromXML();
  }

}

Definition at line 328 of file AnsaQosSystem.cc.

Referenced by loadConfigFromXML().

{
 std::stringstream forStr;
 switch(type)
  {
    case ANSAQOS::Q_PQ :
      subqlenVec = new cOutVector[4];
      subqlenVec[0].setName("High Length");
      subqlenVec[1].setName("Medium Length");
      subqlenVec[2].setName("Normal Length");
      subqlenVec[3].setName("Low Length");
      subdropVec = new cOutVector[4];
      subdropVec[0].setName("High Drops");
      subdropVec[1].setName("Medium Drops");
      subdropVec[2].setName("Normal Drops");
      subdropVec[3].setName("Low Drops");  
      break;
    case ANSAQOS::Q_CQ :
      subqlenVec = new cOutVector[16];
      subdropVec = new cOutVector[16]; 
      for(int i = 0; i < 16; ++i)
      {
        forStr.str(std::string());
        forStr << "Q" << i+1 << " Length";
        subqlenVec[i].setName(forStr.str().c_str());
        forStr.str(std::string());
        forStr << "Q" << i+1 << " Drops";
        subdropVec[i].setName(forStr.str().c_str());
      }
      break;
    default :
      break;
  }  
}

Definition at line 73 of file AnsaQosSystem.cc.

Referenced by initialize().

{
  IRoutingTable* rt = RoutingTableAccess().get();
  
  const char *fileName = par("configFile");
  cXMLElement* document = ev.getXMLDocument(fileName);
  if (document == NULL)
  { 
    error("Cannot read AS configuration from file %s", fileName);
  }
  /* Ziskanie elementu konfiguracie daneho smerovaca */
  std::string routerXPath("Router[@id='");
  std::string routerId = rt->getRouterId().str();
  routerXPath += routerId;
  routerXPath += "']";
 
  cXMLElement* router = document->getElementByPath(routerXPath.c_str());
  if (router == NULL)
  {
    error("No configuration for Router ID: %s", routerId.c_str());
  }

  /* Ziskanie elementu konfiguracie daneho rozhrania */
  std::string itfName = this->getParentModule()->getName();
  itfName += (char)('0' + this->getParentModule()->getIndex());
  std::string intXPath(".//Interface[@name='");
  intXPath += itfName;
  intXPath += "']";

  cXMLElement* qInt = router->getElementByPath(intXPath.c_str());
  if (qInt == NULL)
  {
    error("No configuration for Interface: %s", itfName.c_str());
  }
  
  /* Ziskanie elementu konfiguracie vystupnej fronty */
  cXMLElement* clsfrEl =  NULL;
  cXMLElement* qs = qInt->getFirstChildWithTag("OutputQueue");
  if (qs == NULL)
  { // ziadna konfiguracia -> defaultne FIFO o dlzke 75
    QueueInfo.setFIFO(75);
    subQueues.push_back(ANSAQOS::SubQueue(ANSAQOS::Q_FIFO, ANSAQOS::S_FIFO, QueueInfo.getHoldCapacity(), *clsfrEl));
    return;
  }
 
  /* Nacitanie konfiguracie podla typu fronty */
  std::string qType = qs->getAttribute("type");
  if(qType == "WFQ")
  {
    QueueInfo.setWFQ();
    cXMLElementList ifDetails = qs->getChildren();
    for (cXMLElementList::iterator ifElemIt = ifDetails.begin(); ifElemIt != ifDetails.end(); ++ifElemIt) 
    {
      std::string nodeName = (*ifElemIt)->getTagName();
      if (nodeName == "HoldQueueLength")
        QueueInfo.setHoldCapacity(atoi((*ifElemIt)->getNodeValue()));
      if (nodeName == "CDT")
        QueueInfo.setCdt(atoi((*ifElemIt)->getNodeValue()));
      if (nodeName == "DynamicQueues")
        QueueInfo.setMaxQueues(atoi((*ifElemIt)->getNodeValue()));
    }
  }
  else if(qType == "FIFO")
  {
    int len = 75;
    cXMLElementList ifDetails = qs->getChildren();
    for (cXMLElementList::iterator ifElemIt = ifDetails.begin(); ifElemIt != ifDetails.end(); ++ifElemIt) 
    {
      std::string nodeName = (*ifElemIt)->getTagName();
      if (nodeName == "HoldQueueLength")
        len = atoi((*ifElemIt)->getNodeValue());
    }
    QueueInfo.setFIFO(len);
    subQueues.push_back(ANSAQOS::SubQueue(ANSAQOS::Q_FIFO, ANSAQOS::S_FIFO, QueueInfo.getHoldCapacity(), *clsfrEl));
  }
  else if(qType == "PQ")
  {
    QueueInfo.setPQ();

    cXMLElement* pql = qs->getFirstChildWithTag("PriorityQueueList");
    if (pql == NULL)
    {
      error("No priority-list specified on interface: %s", itfName.c_str());
    }
    
    QueueInfo.setListId(pql->getNodeValue());
    std::string pqlXPath(".//PriorityQueueList[@id='");
    pqlXPath += QueueInfo.getListId();
    pqlXPath += "']";

    

    pql = router->getElementByPath(pqlXPath.c_str());
    if (pql == NULL)
    {
      error("Priority-list %s is not defined", QueueInfo.getListId().c_str());
    }
    initSubQueueVectors(ANSAQOS::Q_PQ);
    setPQSubQueue ("HighQueue", pql, 20);
    setPQSubQueue ("MediumQueue", pql, 40);
    setPQSubQueue ("NormalQueue", pql, 60);
    setPQSubQueue ("LowQueue", pql, 80);       
  }
  else if(qType == "CQ")
  {
    QueueInfo.setCQ();

    cXMLElement* pql = qs->getFirstChildWithTag("CustomQueueList");
    if (pql == NULL)
    {
      error("No custom-list specified on interface: %s", itfName.c_str());
    }
    
    QueueInfo.setListId(pql->getNodeValue());
    std::string pqlXPath(".//CustomQueueList[@id='");
    pqlXPath += QueueInfo.getListId();
    pqlXPath += "']";

    pql = router->getElementByPath(pqlXPath.c_str());
    if (pql == NULL)
    {
      error("Custom-list %s is not defined", QueueInfo.getListId().c_str());
    }
    
    initSubQueueVectors(ANSAQOS::Q_CQ);
    for(int i = 0; i < 16; ++i)
      setCQSubQueue (i+1, pql);
  }
   
}
virtual int AnsaQosSystem::numInitStages ( ) const [inline, protected, virtual]

Definition at line 316 of file AnsaQosSystem.h.

{ return 5;}
void AnsaQosSystem::sendOut ( cMessage *  msg) [protected, virtual]

Should be redefined to send out the packet; e.g. send(msg,"out").

Implements PassiveQueueBase.

Definition at line 535 of file AnsaQosSystem.cc.

{
    send(msg, outGate);
}
void AnsaQosSystem::setCQSubQueue ( int  id,
cXMLElement *  pql 
)

Definition at line 255 of file AnsaQosSystem.cc.

Referenced by loadConfigFromXML().

{
    cXMLElement* clsfr = NULL;
    int dqVal;
    int len = 20;
    int bc = 1500;
    
    cXMLElementList pqlDetails = pql->getChildren();
    for (cXMLElementList::iterator pqlElemIt = pqlDetails.begin(); pqlElemIt != pqlDetails.end(); ++pqlElemIt) 
    {
      std::string nodeName = (*pqlElemIt)->getTagName();
      if (nodeName == "DefaultQueue")
         dqVal = atoi((*pqlElemIt)->getNodeValue());
      if (nodeName == "CustomQueue" && atoi((*pqlElemIt)->getAttribute("id")) == id)
      {
        cXMLElementList qDetails = (*pqlElemIt)->getChildren();
        for (cXMLElementList::iterator qElemIt = qDetails.begin(); qElemIt != qDetails.end(); ++qElemIt)
        {
          std::string nn = (*qElemIt)->getTagName();
          if (nn == "Lenght")
            len = atoi((*qElemIt)->getNodeValue());
          if (nn == "ByteCount")
            bc = atoi((*qElemIt)->getNodeValue());
          if (nn == "Classifier")
            clsfr = *qElemIt;
        } 
      }
    }
    
    subQueues.push_back(ANSAQOS::SubQueue(ANSAQOS::Q_CQ, ANSAQOS::S_FIFO, len, *clsfr));
    subQueues.back().setQueueId(id);
    subQueues.back().setWeight(bc);
    subQueues.back().setActualBytes(bc);
    subQueues.back().setVectorPointer(&subqlenVec[id-1], &subdropVec[id-1]);
    QueueInfo.addHoldCapacity(len);

    if (dqVal == id)
       QueueInfo.setDefaultQueueId(id);
   
}
void AnsaQosSystem::setPQSubQueue ( std::string  id,
cXMLElement *  pql,
int  len 
)

Definition at line 211 of file AnsaQosSystem.cc.

Referenced by loadConfigFromXML().

{
    cXMLElement* clsfr = NULL;
    std::string elemDQ;
    
    cXMLElementList pqlDetails = pql->getChildren();
    for (cXMLElementList::iterator pqlElemIt = pqlDetails.begin(); pqlElemIt != pqlDetails.end(); ++pqlElemIt) 
    {
      std::string nodeName = (*pqlElemIt)->getTagName();
      if (nodeName == "DefaultQueue")
         elemDQ = (*pqlElemIt)->getNodeValue();
      if (nodeName == id)
      {
        cXMLElementList qDetails = (*pqlElemIt)->getChildren();
        for (cXMLElementList::iterator qElemIt = qDetails.begin(); qElemIt != qDetails.end(); ++qElemIt)
        {
          std::string nn = (*qElemIt)->getTagName();
          if (nn == "Lenght")
            len = atoi((*qElemIt)->getNodeValue());
          if (nn == "Classifier")
            clsfr = *qElemIt;
        } 
      }
    }
    
    subQueues.push_back(ANSAQOS::SubQueue(ANSAQOS::Q_PQ, ANSAQOS::S_FIFO, len, *clsfr));
    int d = subQueues.size();
    subQueues.back().setQueueId(d);
    subQueues.back().setVectorPointer(&subqlenVec[d-1], &subdropVec[d-1]);
    QueueInfo.addHoldCapacity(len);

    if (elemDQ.length() > 0 && elemDQ[2] == id[2])
       QueueInfo.setDefaultQueueId(subQueues.size());
  
    
}

Definition at line 388 of file AnsaQosSystem.cc.

Referenced by dequeue().

{
    for (AnsaSubQueues::iterator sbqIt = subQueues.begin(); sbqIt != subQueues.end(); ++sbqIt)
    {
      sbqIt->substractSnFromAll(sn);
    }
}

Member Data Documentation

cOutVector AnsaQosSystem::dropVec [protected]

Definition at line 283 of file AnsaQosSystem.h.

cGate* AnsaQosSystem::outGate [protected]

Definition at line 280 of file AnsaQosSystem.h.

Referenced by initialize(), and sendOut().

cOutVector AnsaQosSystem::qlenVec [protected]

Definition at line 282 of file AnsaQosSystem.h.

cOutVector* AnsaQosSystem::subdropVec [protected]

Definition at line 286 of file AnsaQosSystem.h.

Referenced by initSubQueueVectors(), setCQSubQueue(), setPQSubQueue(), and ~AnsaQosSystem().

cOutVector* AnsaQosSystem::subqlenVec [protected]

Definition at line 285 of file AnsaQosSystem.h.

Referenced by initSubQueueVectors(), setCQSubQueue(), setPQSubQueue(), and ~AnsaQosSystem().


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