INET Framework for OMNeT++/OMNEST
AnsaQosSystem.h
Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2011 Martin Danko
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 //
00018 
00019 
00020 #ifndef __ANSA_QOS_SYSTEM_H
00021 #define __ANSA_QOS_SYSTEM_H
00022 
00023 #include <vector>
00024 #include <iostream>
00025 #include <omnetpp.h>
00026 #include "AnsaQosClassifiers.h"
00027 #include "PassiveQueueBase.h"
00028 
00029 
00030 namespace ANSAQOS {
00031 
00032 /* Vycet typov fronty */
00033 enum QueueType {
00034     Q_FIFO = 1,
00035     Q_PQ = 2,
00036     Q_CQ = 3,
00037     Q_WFQ = 4,
00038     Q_CBWFQ = 5,
00039     Q_WRED = 6
00040 };
00041 
00042 /* Vycet typov podfronty */  
00043 enum SubQueueType {
00044     S_FIFO = 1,
00045     S_WFQ = 2,
00046     S_WRED = 3
00047 };
00048 
00049 /* Vycet typov vysledku operacie vlozenia do fronty */
00050 enum EnqueueingResult {
00051     QUEUED = 1,
00052     NOMATCH = 2,
00053     NOTQUEUED = 3
00054 };
00055 
00056 /* Trieda pre uchovanie parametrov fronty */
00057 class QueueConfig {
00058   private:
00059     QueueType qt;          // typ fronty
00060     std::string listId;    // ID Priority alebo Custom listu
00061     int numQueues;         // aktualny pocet front
00062     int maxActQueues;      // maximalny pocet aktivnych front
00063     int maxQueues;         // maximalny limit poctu front
00064     int currentHold;       // aktualny celkovy pocet paketov vo fronte
00065     int holdCapacity;      // maximalny limit poctu paketov vo fronte
00066     int cdt;               // Congestive Discard Threshold pre WFQ
00067     int droped;            // pocet zahodenych paketov
00068     int currentCQQueueId;  // ID prave obsluhovanej podfronty u CQ
00069     int defaultQueueId;    // defaultna fronta u PQ a CQ
00070     
00071     cOutVector *qlenVec;     // ukazovatel na vektor pre zaznamenanie dlzky fronty
00072     cOutVector *dropVec;     // ukazovatel na vektor pre zaznamenanie zahodenych paketov
00073     
00074   public:
00075     QueueConfig() {currentHold = 0;}
00076     
00077     void setQueueType(QueueType type) {qt = type;}
00078     QueueType getQueueType() {return qt;}
00079     void setListId(std::string id) {listId = id;}
00080     std::string getListId() {return listId;}
00081     void setNumQueues(int num) {numQueues = num;}
00082     int getNumQueues() {return numQueues;}
00083     void setMaxActQueues(int num) {maxActQueues = num;}
00084     int getMaxActQueues() {return maxActQueues;}
00085     void setMaxQueues(int num) {maxQueues = num;}
00086     int getMaxQueues() {return maxQueues;}
00087     void setCurrentHold(int num) {currentHold = num;}
00088     int getCurrentHold() {return currentHold;}
00089     void setHoldCapacity(int num) {holdCapacity = num;}
00090     void addHoldCapacity(int num) {holdCapacity += num;}
00091     int getHoldCapacity() {return holdCapacity;}
00092     void setCdt(int num) {cdt = num;}
00093     int getCdt() {return cdt;}
00094     void setDroped(int num) {droped = num;}
00095     int getDroped() {return droped;}
00096     void setCurrentCQQueueId(int id) {currentCQQueueId = id;}
00097     void addCurrentCQQueueId() {currentCQQueueId = (currentCQQueueId + 1) % 16;}
00098     int getCurrentCQQueueId() {return currentCQQueueId;}
00099     void setDefaultQueueId(int id) {defaultQueueId = id;}
00100     int getDefaultQueueId() {return defaultQueueId;}
00101     void setVectorPointer(cOutVector* l, cOutVector* d) { qlenVec = l; dropVec = d;}
00102     
00103     void addNumQueues() {++numQueues; maxActQueues = (numQueues < maxActQueues ? maxActQueues:numQueues);}
00104     void remNumQueues() {--numQueues;}
00105     void addCurrentHold() {++currentHold; qlenVec->record(currentHold);}
00106     void remCurrentHold() {--currentHold; qlenVec->record(currentHold);}
00107     void addDroped() {++droped; dropVec->record(1);}
00108     
00109     /* Inicializacia parametrov FIFO fronty */
00110     void setVectorName (QueueType type);
00111     
00112     void setFIFO(int hold) {qt=Q_FIFO; currentHold = droped = 0; maxQueues = numQueues = 1; 
00113                             holdCapacity = cdt = hold; setVectorName(Q_FIFO);}
00114     /* Inicializacia parametrov WFQ fronty */        
00115     void setWFQ()  {qt=Q_WFQ; numQueues = maxActQueues = currentHold = droped = 0; 
00116                     maxQueues = 256; holdCapacity = 1000; cdt = 64; setVectorName(Q_WFQ);}
00117     /* Inicializacia parametrov PQ fronty */                
00118     void setPQ() {qt=Q_PQ; currentHold = droped = holdCapacity = cdt = 0;
00119                   maxQueues = numQueues = 4; defaultQueueId = 3; setVectorName(Q_PQ);}
00120     /* Inicializacia parametrov CQ fronty */              
00121     void setCQ() {qt=Q_CQ; currentHold = droped = holdCapacity = cdt = 0; 
00122                   maxQueues = numQueues = 16; defaultQueueId = currentCQQueueId= 1; setVectorName(Q_CQ);}               
00123 };
00124 
00125 
00126 /* Trieda reprezentujuca paket zo sekvencnym cislom */ 
00127 class SNPacket {
00128 
00129 private:
00130     cMessage *msg;   // ukazovatel na paket
00131     int sn;          // sekvencne cislo paketu
00132 
00133 public:
00134     SNPacket() {msg = NULL; sn = 0;}
00135     SNPacket(cMessage *c_msg, int c_sn) {msg = c_msg; sn = c_sn;}
00136     
00137     int getSn() {return sn;}
00138     void setSn(int n_sn) {sn = n_sn;}
00139     void substractSn(int subNum) {sn = sn - subNum;}
00140     
00141     cMessage *getMsg() {return msg;}
00142     void setMsg(cMessage *n_msg) {msg = n_msg;}
00143 };
00144 
00145 
00146 /* Trieda reprezentujuca podfrontu */
00147 class SubQueue {
00148 
00149 private:
00150     Classifier *clsfr;       // klasifikator pre podfrontu
00151     QueueType qt;            // typ fronty, ktorej je podfronta clenom
00152     SubQueueType sbqt;       // typ podfronty
00153     int queueId;             // ID fronty
00154     int maxLength;           // maximalna dlzka podfronty
00155     int lastSn;              // sekvencne cislo posledneho paketu fronty
00156     int droped;              // pocet zahodenych paketov v podfronte
00157     int weight;              // vaha podfronty
00158     int actualBytes;         // aktualny volny pocet bajtov pre CQ alg.
00159     
00160     cOutVector *qlenVec;     // vektor pre zaznamenanie dlzky fronty
00161     cOutVector *dropVec;     // vektor pre zaznamenanie zahodenych paketov
00162     
00163     std::vector<SNPacket> snPackets;  // ulozene pakety v podfronte
00164     
00165 
00166 public:
00167   
00168     SubQueue() {lastSn = 0; qlenVec = dropVec = NULL;}
00169     SubQueue(cMessage *msg, int cdt);
00170     SubQueue(QueueType t1, SubQueueType t2, int len, cXMLElement& clsfrConfig);
00171     
00172     void clearSubQueue();
00173     
00174     void setQueueType(QueueType type) {qt = type;}
00175     QueueType getQueueType() {return qt;}
00176     void setSubQueueType(SubQueueType type) {sbqt = type;}
00177     SubQueueType getSubQueueType() {return sbqt;}
00178     void setQueueId(int id) {queueId = id;}
00179     int getQueueId() {return queueId;}
00180     void setMaxLength(int len) {maxLength = len;}
00181     int getMaxLength() {return maxLength;}
00182     void setLastSn(int n_sn) {lastSn = n_sn;}
00183     int getLastSn() {return lastSn;}
00184     void addDroped() {++droped; }
00185     int getDroped() {return droped;}
00186     void setWeight(cMessage *msg);
00187     void setWeight(int w) {weight = w;}
00188     int getWeight() {return weight;}
00189     void setActualBytes() {actualBytes = weight;}
00190     void setActualBytes(int b) {actualBytes = b;}
00191     void addActualBytes(int b) {actualBytes += b;}
00192     void remActualBytes(int b) {actualBytes -= b;}
00193     int getActualBytes() {return actualBytes;}
00194     std::string getClassifierInfo() {return clsfr->info();}
00195     void setVectorPointer(cOutVector* l, cOutVector* d) { qlenVec = l; dropVec = d;}
00196     void updateVectorLenght() {if(qlenVec) qlenVec->record(snPackets.size());}
00197     void updateVectorDrop() {if(dropVec) dropVec->record(1);}
00198 
00199     int getQueueLength() {return snPackets.size();}
00200     bool isQueueEmpty() {return getQueueLength()>0 ? false : true ;}
00201     void substractSnFromAll(int subNum);
00202     int getLowestSn() {return (snPackets.front()).getSn();}
00203     int calculateSn(cMessage *msg);
00204     
00205     short enqueue(cMessage *msg, bool classify);
00206     cMessage *dequeue();
00207 };
00208 
00209 /*
00210  * Pretazenie operatoru "<<" pre vypis stavu podfronty do grafickeho rozhrania 
00211  */
00212 
00213 inline std::ostream& operator<< (std::ostream& ostr, SubQueue& sbq)
00214 {
00215   switch (sbq.getQueueType())
00216   {
00217     case ANSAQOS::Q_FIFO :
00218       ostr  << "No subqueues in FIFO queue";
00219       break;
00220     case ANSAQOS::Q_WFQ : 
00221       ostr  << "(depth/weight/total drops) ";
00222       ostr << sbq.getQueueLength() << "/";
00223       ostr << sbq.getWeight() << "/";
00224       ostr << sbq.getDroped() << "  ";
00225       ostr << sbq.getClassifierInfo(); 
00226       break;
00227     case ANSAQOS::Q_PQ :
00228       switch (sbq.getQueueId())
00229       {
00230         case 1 :
00231           ostr  << "High: ";
00232           break;
00233         case 2 :
00234           ostr  << "Medium: ";
00235           break;
00236         case 3 :
00237           ostr  << "Normal: ";
00238           break;
00239         case 4 :
00240           ostr  << "Low: ";
00241           break;
00242         default:
00243           ostr  << "Error";
00244       }
00245       ostr << sbq.getQueueLength() << "/";
00246       ostr << sbq.getMaxLength() << "/";
00247       ostr << sbq.getDroped() ;
00248       ostr << " (size/max/drops)  Classifier: ";
00249       ostr << sbq.getClassifierInfo(); 
00250       
00251       break;
00252     case ANSAQOS::Q_CQ :
00253       ostr  << "Queue "<< sbq.getQueueId() <<": ";
00254       ostr << sbq.getQueueLength() << "/";
00255       ostr << sbq.getMaxLength() << "/";
00256       ostr << sbq.getDroped() ;
00257       ostr << " (size/max/drops)  ByteCount: ";
00258       ostr << sbq.getActualBytes() << "/";
00259       ostr << sbq.getWeight() ;
00260       ostr << " (actual/max)  Classifier: ";
00261       ostr << sbq.getClassifierInfo();
00262       break;
00263     default :
00264       ostr  << "Error";
00265   }
00266      
00267     return ostr;
00268 }
00269 
00270 }
00271 
00272 typedef std::vector<ANSAQOS::SubQueue> AnsaSubQueues;
00273 
00274 /* Trieda definujuca modul s frontami FIFO, WFQ, PQ, CQ */ 
00275 class INET_API AnsaQosSystem : public PassiveQueueBase
00276 {
00277   protected:
00278   
00279     AnsaSubQueues  subQueues;         // podfronty
00280     cGate *outGate;                   // vystupna brana modulu
00281     
00282     cOutVector qlenVec;     // vektor pre zaznamenanie dlzky fronty
00283     cOutVector dropVec;     // vektor pre zaznamenanie zahodenych paketov
00284     
00285     cOutVector *subqlenVec; // vektory podfront
00286     cOutVector *subdropVec; // vektory podfront
00287     
00288     ANSAQOS::QueueConfig QueueInfo;   // parametre fronty
00289 
00290   public:
00291     AnsaQosSystem() {QueueInfo.setVectorPointer(&qlenVec, &dropVec);};
00292     ~AnsaQosSystem();
00293     
00294     void loadConfigFromXML();
00295     int getLowestSn(); 
00296     AnsaSubQueues::iterator getSubQueueBySn(int sn);
00297     void substractSnInAllQueues(int sn);
00298     void setPQSubQueue(std::string id, cXMLElement* pql, int len);
00299     void setCQSubQueue (int id, cXMLElement* pql);
00300     void initSubQueueVectors(ANSAQOS::QueueType type);
00301 
00302 
00303   protected:
00304 
00305     virtual void initialize(int stage);
00306 
00307     /* Redefinovane z PassiveQueueBase. */
00308     virtual bool enqueue(cMessage *msg);
00309 
00310     /* Redefinovane z PassiveQueueBase. */
00311     virtual cMessage *dequeue();
00312 
00313     /* Redefinovane z PassiveQueueBase. */
00314     virtual void sendOut(cMessage *msg);
00315     
00316     virtual int numInitStages() const  { return 5;}
00317      
00318 };
00319 
00320 
00321 #endif
00322 
00323