INET Framework for OMNeT++/OMNEST
ISIS Class Reference

#include <ISIS.h>

List of all members.

Public Member Functions

 ISIS ()
virtual ~ISIS ()
void printAdjTable ()
void printLSPDB ()

Protected Member Functions

virtual void initialize (int stage)
virtual void handleMessage (cMessage *msg)
virtual int numInitStages () const
bool compareArrays (unsigned char *first, unsigned char *second, unsigned int size)
void copyArrayContent (unsigned char *src, unsigned char *dst, unsigned int size, unsigned int startSrc, unsigned int startDst)

Private Member Functions

void initISIS ()
void initHello ()
void initGenerate ()
void initRefresh ()
void initPeriodicSend ()
void initCsnp ()
void initPsnp ()
void initSPF ()
void handlePTPHelloMsg (ISISMessage *inMsg)
void sendBroadcastHelloMsg (int interfaceIndex, short circuitType)
void sendPTPHelloMsg (int interfaceIndex, short circuitType)
unsigned short getHoldTime (int interfaceIndex, short circuitType=L1_TYPE)
double getHelloInterval (int interfaceIndex, short circuitType)
ISISadjgetAdjByGateIndex (int gateIndex, short circuitType, int offset=0)
ISISadjgetAdjBySystemID (unsigned char *systemID, short circuitType, int gateIndex=-1)
ISISadjgetAdj (ISISMessage *inMsg, short circuitType=L1_TYPE)
ISISinterfacegetIfaceByGateIndex (int gateIndex)
bool isAdjBySystemID (unsigned char *systemID, short circuitType)
bool isUp (int gateIndex, short circuitType)
bool amIL1DIS (int interfaceIndex)
bool amIL2DIS (int interfaceIndex)
void handleL1Lsp (ISISLSPPacket *lsp)
void handleL1Csnp (ISISCSNPPacket *csnp)
void handleL1Psnp (ISISPSNPPacket *psnp)
std::vector< unsigned char * > * getLspRange (unsigned char *startLspID, unsigned char *endLspID, short circuitType)
unsigned char * getStartLspID (ISISCSNPPacket *csnp)
unsigned char * getEndLspID (ISISCSNPPacket *csnp)
unsigned char * getLspID (ISISLSPPacket *msg)
void setLspID (ISISLSPPacket *msg, unsigned char *lspID)
void updateLSP (ISISLSPPacket *lsp, short circuitType)
void replaceLSP (ISISLSPPacket *lsp, LSPRecord *lspRecord, short circuitType)
void purgeRemainLSP (unsigned char *lspId, short circuitType)
void purgeLSP (unsigned char *lspId, short circuitType)
void purgeLSP (ISISLSPPacket *lsp, short circuitType)
void purgeMyLSPs (short circuitType)
void deleteLSP (ISISTimer *timer)
void sendLSP (LSPRecord *lspRec, int gateIndex)
std::vector< ISISLSPPacket * > * genLSP (short circuitType)
void generateLSP (ISISTimer *timer)
void generateLSP (short circuitType)
void refreshLSP (ISISTimer *timer)
void refreshLSP (short circuitType)
std::vector< LSPRecord * > * getLSPDb (short circuitType)
void periodicSend (ISISTimer *timer, short circuitType)
void sendL1Csnp (ISISTimer *timer)
void sendL1Psnp (ISISTimer *timer)
unsigned char * getLSPID ()
LSPRecordgetLSPFromDbByID (unsigned char *LSPID, short circuitType)
bool compareLSP (ISISLSPPacket *lsp1, ISISLSPPacket *lsp2)
LSPRecordinstallLSP (ISISLSPPacket *lsp, short circuitType)
void fullSPF (ISISTimer *timer)
bool extractISO (ISISCons_t *initial, short circuitType)
ISISPathgetPath (ISISPaths_t *paths, unsigned char *id)
ISISCons_tgetCons (ISISCons_t *cons, unsigned char *from)
void getBestMetric (ISISPaths_t *paths)
ISISPathgetBestPath (ISISPaths_t *paths)
void twoWayCheck (ISISCons_t *cons)
bool isCon (ISISCons_t *cons, unsigned char *from, unsigned char *to)
void bestToPath (ISISCons_t *cons, ISISPaths_t *ISISTent, ISISPaths_t *ISISPaths)
void moveToTent (ISISCons_t *initial, unsigned char *from, uint32_t metric, ISISPaths_t *ISISTent)
void moveToPath (ISISPath *path)
std::vector< std::vector
< FlagRecord * > * > * 
getSRMPTPQueue (short circuitType)
std::vector< std::vector
< FlagRecord * > * > * 
getSRMBQueue (short circuitType)
std::vector< std::vector
< FlagRecord * > * > * 
getSSNPTPQueue (short circuitType)
std::vector< std::vector
< FlagRecord * > * > * 
getSSNBQueue (short circuitType)
std::vector< FlagRecord * > * getSRMQ (bool network, int index, short circuitType)
std::vector< FlagRecord * > * getSSNQ (bool network, int index, short circuitType)
void setSRMflag (LSPRecord *lspRec, int index, short circuitType)
void setSRMflags (LSPRecord *lspRec, short circuitType)
void setSRMflagsBut (LSPRecord *lspRec, unsigned int index, short circuitType)
void clearSRMflag (LSPRecord *lspRec, int index, short circuitType)
void clearSRMflags (LSPRecord *lspRec, short circuitType)
void clearSRMflagsBut (LSPRecord *lspRec, unsigned int index, short circuitType)
void setSSNflag (LSPRecord *lspRec, int index, short circuitType)
void setSSNflags (LSPRecord *lspRec, short circuitType)
void setSSNflagsBut (LSPRecord *lspRec, unsigned int index, short circuitType)
void clearSSNflag (LSPRecord *lspRec, int index, short circuitType)
void clearSSNflags (LSPRecord *lspRec, short circuitType)
void clearSSNflagsBut (LSPRecord *lspRec, unsigned int index, short circuitType)
void addFlags (LSPRecord *lspRec, short circuitType)
void printLSP (ISISLSPPacket *lsp, char *from)
void printSysId (unsigned char *sysId)
void printLspId (unsigned char *lspId)
void printPaths (ISISPaths_t *paths)
void schedule (ISISTimer *timer, double timee=-1)
unsigned char * getSysID (ISISMessage *msg)
unsigned char * getSysID (ISISTimer *timer)
unsigned char * getLspID (ISISTimer *timer)
void addTLV (ISISMessage *inMsg, enum TLVtypes tlvType)
void addTLV (ISISMessage *inMsg, TLV_t *tlv)
void addTLV (std::vector< TLV_t * > *tlvtable, enum TLVtypes tlvType, short circuitType, unsigned char nsel=0)
bool isAdjUp (short circuitType)
bool isAdjUp (ISISMessage *msg, short circuitType)
TLV_tgetTLVByType (ISISMessage *inMsg, enum TLVtypes tlvType, int offset=0)
bool isMessageOK (ISISMessage *inMsg)
bool isAreaIDOK (TLV_t *areaAddressTLV, unsigned char *compare=NULL)
int getIfaceIndex (ISISinterface *interface)
std::vector< ISISadj > * getAdjTab (short circuitType)
void insertIft (InterfaceEntry *entry, cXMLElement *device)
void sendHelloMsg (ISISTimer *timer)
bool parseNetAddr ()
void handleL1HelloMsg (ISISMessage *inMsg)
void handleL2HelloMsg (ISISMessage *inMsg)
void removeDeadNeighbour (ISISTimer *msg)
void electL1DesignatedIS (ISISL1HelloPacket *msg)
void electL2DesignatedIS (ISISL2HelloPacket *msg)
void resetDIS (unsigned char *systemID, int gateIndex, short circuitType)
void sendMyL1LSPs ()
void sendMyL2LSPs ()
void floodFurtherL1LSP (ISISLSPL1Packet *msg)
void sendSpecificL1LSP (unsigned char *LSPid)
void handleL1LSP (ISISMessage *msg)
void handleL2LSP (ISISMessage *msg)
void sendL1CSNP ()
void sendL2CSNP ()
void handleL1CSNP (ISISMessage *msg)
void handleL2CSNP (ISISMessage *msg)
void sendL1PSNP (std::vector< unsigned char * > *LSPlist, int gateIndex)
void sendL2PSNP ()
void handleL1PSNP (ISISMessage *msg)
void handleL2PSNP (ISISMessage *msg)
bool checkDuplicateSysID (ISISMessage *msg)
void removeDeadLSP (ISISTimer *msg)
void updateMyLSP ()

Private Attributes

IInterfaceTableift
std::vector< ISISinterfaceISISIft
const char * deviceType
const char * deviceId
const char * configFile
const char * netAddr
const unsigned char * areaId
const unsigned char * sysId
const unsigned char * NSEL
std::vector< ISISadjadjL1Table
std::vector< ISISadjadjL2Table
short isType
std::vector< LSPrecordL1LSP
std::vector< LSPrecordL2LSP
LSPRecQ_tL1LSPDb
LSPRecQ_tL2LSPDb
FlagRecQQ_tL1SRMBQueue
FlagRecQQ_tL1SRMPTPQueue
FlagRecQQ_tL2SRMBQueue
FlagRecQQ_tL2SRMPTPQueue
FlagRecQQ_tL1SSNBQueue
FlagRecQQ_tL1SSNPTPQueue
FlagRecQQ_tL2SSNBQueue
FlagRecQQ_tL2SSNPTPQueue
int L1HelloInterval
int L2HelloInterval
short L1HelloMultiplier
short L2HelloMultiplier
int lspInterval
int lspRefreshInterval
int lspMaxLifetime
int L1LspGenInterval
int L2LspGenInterval
int L1LspSendInterval
int L2LspSendInterval
int L1LspInitWait
int L2LspInitWait
int L1CsnpInterval
int L2CsnpInterval
int L1PsnpInterval
int L2PsnpInterval
int L1SPFFullInterval
int L2SPFFullInterval
unsigned long helloCounter

Detailed Description

Single class providing all functionality of whole module.

Definition at line 52 of file ISIS.h.


Constructor & Destructor Documentation

Definition at line 24 of file ISIS.cc.

          {
    this->L1LSPDb = new std::vector<LSPRecord*>;
    this->L2LSPDb = new std::vector<LSPRecord*>;

    this->L1SRMBQueue = new std::vector<std::vector<FlagRecord *> *>;
    this->L2SRMBQueue = new std::vector<std::vector<FlagRecord *> *>;

    this->L1SRMPTPQueue = new std::vector<std::vector<FlagRecord *> *>;
    this->L2SRMPTPQueue = new std::vector<std::vector<FlagRecord *> *>;

    this->L1SSNBQueue = new std::vector<std::vector<FlagRecord *> *>;
    this->L2SSNBQueue = new std::vector<std::vector<FlagRecord *> *>;

    this->L1SSNPTPQueue = new std::vector<std::vector<FlagRecord *> *>;
    this->L2SSNPTPQueue = new std::vector<std::vector<FlagRecord *> *>;

}
ISIS::~ISIS ( ) [virtual]

Definition at line 45 of file ISIS.cc.

{
    if(this->L1LSPDb != NULL){
        std::vector<LSPRecord *>::iterator it = this->L1LSPDb->begin();
        for(; it != this->L1LSPDb->end(); ++it){
            //delete (*it)->LSP;
            //delete (*it)->deadTimer;
            delete (*it);
        }
        this->L1LSPDb->clear();
        delete this->L1LSPDb;
    }

    if(this->L2LSPDb != NULL){
        std::vector<LSPRecord *>::iterator it = this->L2LSPDb->begin();
            for(; it != this->L2LSPDb->end(); ++it){
                //delete (*it)->LSP;
                //delete (*it)->deadTimer;
                delete (*it);
            }
            this->L2LSPDb->clear();
            delete this->L2LSPDb;
        }

    /* delete SRM */
    if(this->L1SRMBQueue != NULL){
        std::vector<std::vector<FlagRecord*> *>::iterator qIt = this->L1SRMBQueue->begin();
        for(; qIt != this->L1SRMBQueue->end(); ++qIt){
            std::vector<FlagRecord*>::iterator it = (*qIt)->begin();
            for(; it != (*qIt)->end(); ++it){
                delete (*it);
            }
            (*qIt)->clear();
            delete (*qIt);
        }
        this->L1SRMBQueue->clear();
        delete this->L1SRMBQueue;
    }

    if(this->L1SRMPTPQueue != NULL){
        std::vector<std::vector<FlagRecord*> *>::iterator qIt = this->L1SRMPTPQueue->begin();
        for(; qIt != this->L1SRMPTPQueue->end(); ++qIt){
            std::vector<FlagRecord*>::iterator it = (*qIt)->begin();
            for(; it != (*qIt)->end(); ++it){
                delete (*it);
            }
            (*qIt)->clear();
            delete (*qIt);
        }
        this->L1SRMPTPQueue->clear();
        delete this->L1SRMPTPQueue;
    }

    if(this->L2SRMBQueue != NULL){
        std::vector<std::vector<FlagRecord*> *>::iterator qIt = this->L2SRMBQueue->begin();
        for(; qIt != this->L2SRMBQueue->end(); ++qIt){
            std::vector<FlagRecord*>::iterator it = (*qIt)->begin();
            for(; it != (*qIt)->end(); ++it){
                delete (*it);
            }
            (*qIt)->clear();
            delete (*qIt);
        }
        this->L2SRMBQueue->clear();
        delete this->L2SRMBQueue;
    }

    if(this->L2SRMPTPQueue != NULL){
        std::vector<std::vector<FlagRecord*> *>::iterator qIt = this->L2SRMPTPQueue->begin();
        for(; qIt != this->L2SRMPTPQueue->end(); ++qIt){
            std::vector<FlagRecord*>::iterator it = (*qIt)->begin();
            for(; it != (*qIt)->end(); ++it){
                delete (*it);
            }
            (*qIt)->clear();
            delete (*qIt);
        }
        this->L2SRMPTPQueue->clear();
        delete this->L2SRMPTPQueue;
    }
    /* end of delete SRM */

    /* delete SSN */
    if(this->L1SSNBQueue != NULL){
        std::vector<std::vector<FlagRecord*> *>::iterator qIt = this->L1SSNBQueue->begin();
        for(; qIt != this->L1SSNBQueue->end(); ++qIt){
            std::vector<FlagRecord*>::iterator it = (*qIt)->begin();
            for(; it != (*qIt)->end(); ++it){

                delete (*it);

            }
            (*qIt)->clear();
            delete (*qIt);
        }
        this->L1SSNBQueue->clear();
        delete this->L1SSNBQueue;
    }

    if(this->L1SSNPTPQueue != NULL){
        std::vector<std::vector<FlagRecord*> *>::iterator qIt = this->L1SSNPTPQueue->begin();
        for(; qIt != this->L1SSNPTPQueue->end(); ++qIt){
            std::vector<FlagRecord*>::iterator it = (*qIt)->begin();
            for(; it != (*qIt)->end(); ++it){
                delete (*it);
            }
            (*qIt)->clear();
            delete (*qIt);
        }
        this->L1SSNPTPQueue->clear();
        delete this->L1SSNPTPQueue;
    }

    if(this->L2SSNBQueue != NULL){
        std::vector<std::vector<FlagRecord*> *>::iterator qIt = this->L2SSNBQueue->begin();
        for(; qIt != this->L2SSNBQueue->end(); ++qIt){
            std::vector<FlagRecord*>::iterator it = (*qIt)->begin();
            for(; it != (*qIt)->end(); ++it){
                delete (*it);
            }
            (*qIt)->clear();
            delete (*qIt);
        }
        this->L2SSNBQueue->clear();
        delete this->L2SSNBQueue;
    }

    if(this->L2SSNPTPQueue != NULL){
        std::vector<std::vector<FlagRecord*> *>::iterator qIt = this->L2SSNPTPQueue->begin();
        for(; qIt != this->L2SSNPTPQueue->end(); ++qIt){
            std::vector<FlagRecord*>::iterator it = (*qIt)->begin();
            for(; it != (*qIt)->end(); ++it){
                delete (*it);
            }
            (*qIt)->clear();
            delete (*qIt);
        }
        this->L2SSNPTPQueue->clear();
        delete this->L2SSNPTPQueue;
    }
        /* end of delete SSN */

}

Member Function Documentation

void ISIS::addFlags ( LSPRecord lspRec,
short  circuitType 
) [private]

Definition at line 6198 of file ISIS.cc.

Referenced by clearSRMflags(), clearSRMflagsBut(), clearSSNflags(), clearSSNflagsBut(), setSRMflag(), setSRMflags(), setSRMflagsBut(), setSSNflag(), setSSNflags(), and setSSNflagsBut().

                                                       {

    //add flags
    if(!lspRec->SRMflags.empty() || !lspRec->SSNflags.empty()){
        EV <<"ISIS: Warning: Adding *flags to non-empty vectors." <<endl;
        return;

    }
    for (std::vector<ISISinterface>::iterator intIt = this->ISISIft.begin(); intIt != this->ISISIft.end(); ++intIt)
    {

        lspRec->SRMflags.push_back(false);
        lspRec->SSNflags.push_back(false);

    }
    //set SRM
    //this->setSRMflags(lspRec, circuitType);
}
void ISIS::addTLV ( ISISMessage inMsg,
enum TLVtypes  tlvType 
) [private]

Definition at line 7146 of file ISIS.cc.

Referenced by genLSP(), sendL1Csnp(), and sendL1Psnp().

{
    unsigned int tlvSize;
    switch (tlvType)
    {
        case (AREA_ADDRESS):
            TLV_t myTLV;
            myTLV.type = AREA_ADDRESS;
            myTLV.length = ISIS_AREA_ID;
            myTLV.value = new unsigned char[ISIS_AREA_ID];
            this->copyArrayContent((unsigned char*) this->areaId, myTLV.value, 3, 0, 0);

            tlvSize = inMsg->getTLVArraySize();
            inMsg->setTLVArraySize(tlvSize + 1);
            inMsg->setTLV(tlvSize, myTLV);
            break;

        default:
            EV <<"ISIS: ERROR: This TLV type is not (yet) implemented in addTLV(ISISMessage*, enum TLVtypes)" << endl;
            break;

    }

}
void ISIS::addTLV ( ISISMessage inMsg,
TLV_t tlv 
) [private]

Definition at line 7176 of file ISIS.cc.

                                               {
    TLV_t tmpTlv;
    unsigned int tlvSize;

    tmpTlv.type = tlv->type; // set type
    tmpTlv.length = tlv->length; //set length
    tmpTlv.value = new unsigned char [tlv->length]; //allocate appropriate space
    this->copyArrayContent(tlv->value, tmpTlv.value, tlv->length, 0, 0); //copy it


    tlvSize = inMsg->getTLVArraySize(); //get array size
    inMsg->setTLVArraySize(tlvSize + 1);// increase it by one
    inMsg->setTLV(tlvSize, tmpTlv); //finally add TLV at the end
}
void ISIS::addTLV ( std::vector< TLV_t * > *  tlvtable,
enum TLVtypes  tlvType,
short  circuitType,
unsigned char  nsel = 0 
) [private]

Definition at line 7197 of file ISIS.cc.

{

    TLV_t * myTLV;


    if (tlvType == AREA_ADDRESS)
    {
        myTLV = new TLV_t;
        myTLV->type = AREA_ADDRESS;
        myTLV->length = ISIS_AREA_ID;
        myTLV->value = new unsigned char[ISIS_AREA_ID];
        this->copyArrayContent((unsigned char*) this->areaId, myTLV->value, 3, 0, 0);
        tlvTable->push_back(myTLV);

    }
    else if (tlvType == IS_NEIGHBOURS_LSP)
    {

        if (nsel == 0)
        {
            std::vector<LSPneighbour> neighbours;
            ISISadj *tmpAdj;
            for (std::vector<ISISinterface>::iterator it = this->ISISIft.begin(); it != this->ISISIft.end(); ++it)
            {
                LSPneighbour neighbour;
                tmpAdj = this->getAdjByGateIndex((*it).gateIndex, circuitType);
                //if there's not adjacency in state "UP" for specified interface, then skip this interface
                if (tmpAdj == NULL || !tmpAdj->state)
                {
                    continue;
                }

                if ((*it).network)
                {
                    //TODO how do you know it's L1DIS and not L2
                    this->copyArrayContent((*it).L1DIS, neighbour.LANid, ISIS_SYSTEM_ID + 1, 0, 0);
                }
                else
                {
                    this->copyArrayContent(tmpAdj->sysID, neighbour.LANid, ISIS_SYSTEM_ID, 0, 0);
                    neighbour.LANid[ISIS_SYSTEM_ID] = 0;
                }

                //find interface which is DIS connected to and set metrics
                neighbour.metrics.defaultMetric = (*it).metric; //default = 10
                neighbour.metrics.delayMetric = 128; //disabled;
                neighbour.metrics.expenseMetric = 128; //disabled
                neighbour.metrics.errortMetric = 128; //disabled

                neighbours.push_back(neighbour);

            }
            //we have vector of neighbours

            //now compute size needed in tlv
            // virtual link + ((metrics + System-ID + 1) * number_of_neighbours


            int entrySize = (4 + ISIS_SYSTEM_ID + 1);
            //run until there's any neighbour
            for (; !neighbours.empty();)
            {
                myTLV = new TLV_t;
                myTLV->type = IS_NEIGHBOURS_LSP;
                myTLV->length = 1 + ((4 + ISIS_SYSTEM_ID + 1) * neighbours.size());
                myTLV->value = new unsigned char[ISIS_LSP_MAX_SIZE];

                //virtualFlag
                myTLV->value[0] = 40;//TODO should be 0
                //inner loop for separate TLV; after reaching ISIS_LSP_MAX_SIZE or empty neighbours stop filling this tlv
                // 2 bytes for type and length fields and 1 byte for virtual circuit
                for (unsigned int i = 0; ((i + 1) * entrySize) + 1 < 255 && 2 + 1 + (entrySize * i) + entrySize < ISIS_LSP_MAX_SIZE && !neighbours.empty();
                        i++)
                {
                    myTLV->value[(i * 11) + 1] = neighbours.at(0).metrics.defaultMetric;
                    myTLV->value[(i * 11) + 2] = neighbours.at(0).metrics.delayMetric;
                    myTLV->value[(i * 11) + 3] = neighbours.at(0).metrics.expenseMetric;
                    myTLV->value[(i * 11) + 4] = neighbours.at(0).metrics.errortMetric;
                    this->copyArrayContent(neighbours.at(0).LANid, myTLV->value, ISIS_SYSTEM_ID + 1, 0, (i * 11) + 5); //set system ID
                    myTLV->length = 1 + ((4 + ISIS_SYSTEM_ID + 1) * (i + 1));
                    //delete first entry
                    neighbours.erase(neighbours.begin());
                }
                //this tlv is full or no other neighbour entry is present
                tlvTable->push_back(myTLV);
                //TODO do i need to create new myTLV and allocate value?
                //myTLV = new TLV_t;

            }
            return;
        }
        else
        //pseudonode
        {
            std::vector<LSPneighbour> neighbours;

            ISISadj *tmpAdj;
            for (std::vector<ISISinterface>::iterator it = this->ISISIft.begin(); it != this->ISISIft.end(); ++it)
            {

                for (int offset = 0; (tmpAdj = this->getAdjByGateIndex((*it).gateIndex, circuitType, offset)) != NULL;
                        offset++)
                {
                    LSPneighbour neighbour;
                    if (!tmpAdj->state)
                    {
                        continue;
                    }

                    this->copyArrayContent(tmpAdj->sysID, neighbour.LANid, ISIS_SYSTEM_ID, 0, 0);
                    neighbour.LANid[ISIS_SYSTEM_ID] = 0;

                    neighbour.metrics.defaultMetric = 0; //metric from DIS is 0
                    neighbour.metrics.delayMetric = 128; //disabled;
                    neighbour.metrics.expenseMetric = 128; //disabled
                    neighbour.metrics.errortMetric = 128; //disabled

                    neighbours.push_back(neighbour);
                }
            }
            //add also mine non-pseudonode interface as neighbour
                        LSPneighbour neighbour;
                        this->copyArrayContent((unsigned char*) this->sysId, neighbour.LANid, ISIS_SYSTEM_ID, 0, 0);
                        neighbour.LANid[ISIS_SYSTEM_ID] = 0;
                        neighbour.metrics.defaultMetric = 0;  //metric to every neighbour in pseudonode LSP is always zero!!!
                        neighbour.metrics.delayMetric = 128; //disabled;
                        neighbour.metrics.expenseMetric = 128; //disabled
                        neighbour.metrics.errortMetric = 128; //disabled

                        neighbours.push_back(neighbour);

            //we have vector neighbours for pseudo

            int entrySize = (4 + ISIS_SYSTEM_ID + 1);
            //run until there's any neighbour
            for (; !neighbours.empty();)
            {
                myTLV = new TLV_t;
                myTLV->type = IS_NEIGHBOURS_LSP;
                myTLV->length = 1 + ((4 + ISIS_SYSTEM_ID + 1) * neighbours.size());
                myTLV->value = new unsigned char[ISIS_LSP_MAX_SIZE];

                //virtualFlag
                myTLV->value[0] = 40; //TODO should be 0
                //inner loop for separate TLV; after reaching ISIS_LSP_MAX_SIZE or empty neighbours stop filling this tlv
                // 2 bytes for type and length fields and 1 byte for virtual circuit
                for (unsigned int i = 0;
                        ((i + 1) * entrySize) + 1 < 255 && 2 + 1 + (entrySize * i) + entrySize < ISIS_LSP_MAX_SIZE
                                && !neighbours.empty(); i++)
                {
                    myTLV->value[(i * 11) + 1] = neighbours.at(0).metrics.defaultMetric;
                    myTLV->value[(i * 11) + 2] = neighbours.at(0).metrics.delayMetric;
                    myTLV->value[(i * 11) + 3] = neighbours.at(0).metrics.expenseMetric;
                    myTLV->value[(i * 11) + 4] = neighbours.at(0).metrics.errortMetric;
                    this->copyArrayContent(neighbours.at(0).LANid, myTLV->value, ISIS_SYSTEM_ID + 1, 0, (i * 11) + 5); //set system ID
                    myTLV->length = 1 + ((4 + ISIS_SYSTEM_ID + 1) * (i + 1));
                    //delete first entry
                    neighbours.erase(neighbours.begin());
                }
                //this tlv is full or no other neighbour entry is present
                tlvTable->push_back(myTLV);
                //TODO do i need to create new myTLV and allocate value?
                //myTLV = new TLV_t;

            }
        }





        //end of TLV IS_NEIGHBOURS_LSP
    }
    else
    {
        EV << "ISIS: ERROR: This TLV type is not (yet) implemented in addTLV" << endl;
    }
}
bool ISIS::amIL1DIS ( int  interfaceIndex) [private]

Definition at line 6963 of file ISIS.cc.

Referenced by electL1DesignatedIS(), genLSP(), getHelloInterval(), getHoldTime(), sendL1Csnp(), and sendL1Psnp().

{
    //if this is not broadcast interface then no DIS is elected
    if (!this->ISISIft.at(interfaceIndex).network)
    {
        return false;
    }

    return (compareArrays((unsigned char *) this->sysId, this->ISISIft.at(interfaceIndex).L1DIS, ISIS_SYSTEM_ID));

}
bool ISIS::amIL2DIS ( int  interfaceIndex) [private]

Definition at line 6980 of file ISIS.cc.

Referenced by getHelloInterval(), and getHoldTime().

{
    //if this is not broadcast interface then no DIS is elected
    if (!this->ISISIft.at(interfaceIndex).network)
    {
        return false;
    }

    return (compareArrays((unsigned char *) this->sysId, this->ISISIft.at(interfaceIndex).L2DIS, ISIS_SYSTEM_ID));

}
void ISIS::bestToPath ( ISISCons_t cons,
ISISPaths_t ISISTent,
ISISPaths_t ISISPaths 
) [private]

Definition at line 7614 of file ISIS.cc.

Referenced by fullSPF().

                                                                                    {

    ISISPath *path;
    ISISPath *tmpPath;
    //sort it
    std::sort(ISISTent->begin(), ISISTent->end());
    //save best in path
    path = ISISTent->front();
    //mov
    this->moveToTent(init, path->to, path->metric, ISISTent);

    ISISTent->erase(ISISTent->begin());

    if ((tmpPath = this->getPath(ISISPaths, path->to)) == NULL)
    {
        //path to this destination doesn't exist, so simply push

        ISISPaths->push_back(path);
    }
    else
    {
        if (tmpPath->metric >= path->metric)
        {
            if (tmpPath->metric > path->metric)
            {
                EV <<"ISIS: Error during SPF. We got better metric than the one PATHS."<<endl;
                //we got better metric so clear "from" neighbours
                tmpPath->from.clear();
            }
            EV <<"ISIS: Error during SPF. I think we shouldn't have neither same metric."<<endl;
            //append
            tmpPath->metric = path->metric;
            for(ISISNeighbours_t::iterator it = path->from.begin(); it != path->from.end(); ++it){
                tmpPath->from.push_back((*it));
            }

        }
    }

}
bool ISIS::checkDuplicateSysID ( ISISMessage msg) [private]

Check sysId from received hello packet for duplicity.

Returns:
True if neighbour's sysId is the same as mine, false otherwise.

Definition at line 4848 of file ISIS.cc.

Referenced by handleL1HelloMsg(), handleL2HelloMsg(), and handlePTPHelloMsg().

{

    bool test = false;

    if (msg->getType() == LAN_L1_HELLO || msg->getType() == LAN_L2_HELLO)
    {

        // typecast for L1 hello; L1 and L2 hellos differ only in "type" field
        ISISL1HelloPacket *hello = check_and_cast<ISISL1HelloPacket *>(msg);

        //check for area address tlv and compare with my area id
        for (unsigned int j = 0; j < hello->getTLVArraySize(); j++)
        {
            if (hello->getTLV(j).type == AREA_ADDRESS
                    && this->compareArrays((unsigned char *) this->areaId, hello->getTLV(j).value,
                            hello->getTLV(j).length))
            {

                bool equal = true;

                //compare sys ID
                for (unsigned int i = 0; i < hello->getSourceIDArraySize(); i++)
                {
                    if (this->sysId[i] != hello->getSourceID(i))
                        equal = false;
                }

                test = equal;
                break;
            }
        }
    }
    else if (msg->getType() == PTP_HELLO)
    {
        test = true;
        ISISPTPHelloPacket *hello = check_and_cast<ISISPTPHelloPacket *>(msg);
        for (unsigned int i = 0; i < hello->getSourceIDArraySize(); i++)
        {
            if (this->sysId[i] != hello->getSourceID(i))
            {
                test = false;
                break;
            }
        }
    }

    if (test)
    {
        EV << this->deviceId << ": IS-IS WARNING: possible duplicate system ID ";
        for (unsigned g = 0; g < 6; g++)
        {
            EV << setfill('0') << setw(2) << dec << (unsigned int) sysId[g];
            if (g == 1 || g == 3)
                EV << ".";
        }
        EV << " detected" << endl;
    }

    return test;
}
void ISIS::clearSRMflag ( LSPRecord lspRec,
int  index,
short  circuitType 
) [private]

Definition at line 5916 of file ISIS.cc.

Referenced by clearSRMflags(), clearSRMflagsBut(), handleL1Csnp(), handleL1Lsp(), handleL1Psnp(), periodicSend(), purgeLSP(), and setSRMflagsBut().

                                                                      {

    std::vector<FlagRecord*>* srmQ;
    srmQ =  this->getSRMQ(this->ISISIft.at(index).network, this->ISISIft.at(index).gateIndex, circuitType);

    //clear flag
    lspRec->SRMflags.at(index) = false;

    //and remove FlagRecord from Queue
    std::vector<FlagRecord*>::iterator it = srmQ->begin();
    for (; it != srmQ->end(); )
    {
        if ((*it)->index == index && (*it)->lspRec == lspRec)
        {
            it = srmQ->erase(it);
            //break;
        }else{
            ++it;
        }
    }
}
void ISIS::clearSRMflags ( LSPRecord lspRec,
short  circuitType 
) [private]

Definition at line 5938 of file ISIS.cc.

Referenced by deleteLSP().

                                                            {

    if(lspRec->SRMflags.size() == 0 ){
        this->addFlags(lspRec, circuitType);
    }
    for (unsigned int i = 0; i < lspRec->SRMflags.size(); i++)
    {
        this->clearSRMflag(lspRec, i, circuitType);
    }

}
void ISIS::clearSRMflagsBut ( LSPRecord lspRec,
unsigned int  index,
short  circuitType 
) [private]

Definition at line 5950 of file ISIS.cc.

{
    if(lspRec->SRMflags.size() == 0 ){
        this->addFlags(lspRec, circuitType);
    }
    for (unsigned int i = 0; i < lspRec->SRMflags.size(); i++)
    {
        if(i == index){
            this->setSRMflag(lspRec, i, circuitType);
        }else{
            this->clearSRMflag(lspRec, i, circuitType);
        }
    }

}
void ISIS::clearSSNflag ( LSPRecord lspRec,
int  index,
short  circuitType 
) [private]

Definition at line 6054 of file ISIS.cc.

Referenced by clearSSNflags(), clearSSNflagsBut(), handleL1Csnp(), handleL1Lsp(), handleL1Psnp(), purgeLSP(), sendL1Psnp(), and setSSNflagsBut().

                                                                      {

    std::vector<FlagRecord*>* ssnQ;
    ssnQ =  this->getSSNQ(this->ISISIft.at(index).network, this->ISISIft.at(index).gateIndex, circuitType);

    //clear flag
    lspRec->SSNflags.at(index) = false;

    //and remove FlagRecord from Queue
    std::vector<FlagRecord*>::iterator it = ssnQ->begin();
    for (; it != ssnQ->end();)
    {
        if ((*it)->index == index && (*it)->lspRec == lspRec)
        {
            it = ssnQ->erase(it);
            //break;
        }else{
            ++it;
        }
    }
}
void ISIS::clearSSNflags ( LSPRecord lspRec,
short  circuitType 
) [private]

Definition at line 6076 of file ISIS.cc.

Referenced by deleteLSP(), and installLSP().

                                                            {

    if(lspRec->SSNflags.size() == 0 ){
        this->addFlags(lspRec, circuitType);
    }
    for (unsigned int i = 0; i < lspRec->SSNflags.size(); i++)
    {
        this->clearSSNflag(lspRec, i, circuitType);
    }

}
void ISIS::clearSSNflagsBut ( LSPRecord lspRec,
unsigned int  index,
short  circuitType 
) [private]

Definition at line 6088 of file ISIS.cc.

Referenced by replaceLSP().

{
    if(lspRec->SSNflags.size() == 0 ){
        this->addFlags(lspRec, circuitType);
    }
    for (unsigned int i = 0; i < lspRec->SSNflags.size(); i++)
    {
        if(i == index){
            this->setSSNflag(lspRec, i, circuitType);
        }else{
            this->clearSSNflag(lspRec, i, circuitType);
        }
    }

}
bool ISIS::compareArrays ( unsigned char *  first,
unsigned char *  second,
unsigned int  size 
) [protected]

Compare two unsigned char arrays and return result of comparison.

Parameters:
firstFirst unsigned char array to be compared
secondFirst unsigned char array to be compared
sizeSize of two arrays
Returns:
True if arrays match, false otherwise.

Definition at line 3119 of file ISIS.cc.

Referenced by amIL1DIS(), amIL2DIS(), checkDuplicateSysID(), compareLSP(), deleteLSP(), generateLSP(), getAdj(), getAdjBySystemID(), getCons(), getLSPFromDbByID(), getPath(), handleL1CSNP(), handleL1HelloMsg(), handleL1Lsp(), handleL1LSP(), handleL1PSNP(), handleL2HelloMsg(), isAdjBySystemID(), isAdjUp(), isAreaIDOK(), isCon(), moveToTent(), purgeLSP(), purgeMyLSPs(), refreshLSP(), resetDIS(), sendL1CSNP(), sendMyL1LSPs(), sendSpecificL1LSP(), and updateMyLSP().

{
    bool result = true;
    for(unsigned int i=0; i<size;i++)
    {
        if(first[i] != second[i])
            result = false;
    }

    return result;
}
bool ISIS::compareLSP ( ISISLSPPacket lsp1,
ISISLSPPacket lsp2 
) [private]

Definition at line 6281 of file ISIS.cc.

Referenced by generateLSP().

                                                             {

    //pduLength
    //so far this field is not used, or at least not properly

    //remLifeTime
    //newly generated LSP will have different remaining time

    //lspID
    //lspIDs have to match, because lsp2 is selected based on matching LSP-ID

    //seqNumber
    //newly generated LSP will have seqNumber set to 1

    //checksum
    //not used

    //PATTLSPDBOLIS
    //so far this field is set only to 0x01 = only IS Type = L1, but check anyway
    if(lsp1->getPATTLSPDBOLIS() != lsp2->getPATTLSPDBOLIS()){
        return false;
    }

    if(lsp1->getTLVArraySize() != lsp2->getTLVArraySize()){
        return false;
    }

    for(unsigned int i = 0; i < lsp1->getTLVArraySize(); i++){
        if(lsp1->getTLV(i).type != lsp2->getTLV(i).type || lsp1->getTLV(i).length != lsp2->getTLV(i).length || !this->compareArrays(lsp1->getTLV(i).value, lsp2->getTLV(i).value, lsp1->getTLV(i).length) ){
            return false;
        }
    }

    //packets match
    return true;
}
void ISIS::copyArrayContent ( unsigned char *  src,
unsigned char *  dst,
unsigned int  size,
unsigned int  startSrc,
unsigned int  startDst 
) [protected]

Copy content of one unsigned char array to another.

Parameters:
srcSource array to be copied from.
dstDestination array to be copied to.
sizeSize in bytes co be copied.
startSrcPosition in first array, where copying has to be started (usually 0).
startDstPosition in second, where data are saved.

Definition at line 3139 of file ISIS.cc.

Referenced by addTLV(), electL1DesignatedIS(), extractISO(), fullSPF(), getLSPID(), handleL1Csnp(), handleL1CSNP(), handleL1HelloMsg(), handleL1LSP(), handleL1Psnp(), handleL1PSNP(), handleL2HelloMsg(), handlePTPHelloMsg(), insertIft(), moveToTent(), resetDIS(), sendBroadcastHelloMsg(), sendL1Csnp(), sendL1CSNP(), sendL1Psnp(), sendL1PSNP(), sendMyL1LSPs(), sendPTPHelloMsg(), sendSpecificL1LSP(), and updateMyLSP().

{
    for(unsigned int i=0; i<size;i++)
    {
        dst[i+startDst] = src[i+startSrc];
    }
}
void ISIS::deleteLSP ( ISISTimer timer) [private]

Definition at line 5720 of file ISIS.cc.

Referenced by handleMessage().

{
    short circuitType = timer->getIsType();
    unsigned char* lspId = this->getLspID(timer);
    std::vector<LSPRecord *> *lspDb = this->getLSPDb(circuitType);
    unsigned char * tmpLspId;

    for(std::vector<LSPRecord*>::iterator it = lspDb->begin(); it != lspDb->end(); ++it){
        tmpLspId = this->getLspID((*it)->LSP);
        if(this->compareArrays(tmpLspId, lspId, ISIS_SYSTEM_ID + 2)){
            //clearing *flags shoudn't be necessary, but just to be sure
            this->clearSRMflags((*it), timer->getIsType());
            this->clearSSNflags((*it), timer->getIsType());
            delete (*it);
            lspDb->erase(it);
            delete lspId;
            delete tmpLspId;
            return;
        }
        delete tmpLspId;
    }

    delete lspId;
}
void ISIS::electL1DesignatedIS ( ISISL1HelloPacket msg) [private]

Election of L1 Designated IS. Priorities are compared when received new hello packet. Higher priority wins.

See also:
handleL1HelloMsg(ISISMessage *inMsg)
Parameters:
msgReceived hello packet containing neighbours priority.

Definition at line 3247 of file ISIS.cc.

Referenced by handleL1HelloMsg().

{
    /* TODO Please rewrite this mess. */

//    Ieee802Ctrl *ctrl = check_and_cast <Ieee802Ctrl *> (msg->getControlInfo());
    short circuitType = L1_TYPE;
    unsigned int i;
    for(i=0; i<ISISIft.size(); i++)
    {
        if(ISISIft.at(i).gateIndex == msg->getArrivalGate()->getIndex())
        {
            if(ISISIft.at(i).gateIndex != i){
                EV << "ISIS: Warning: Houston, we got a problem! A BIG ONE!" << endl;
            }
            //break the cycle, we have the right position stored at "i"
            break;
        }
    }

    //compare LAN-ID from message aka LAN DIS with supposed DIS
    bool equal = true;
    unsigned char * msgLanID = new unsigned char [7];
    for(unsigned int k=0; k<msg->getLanIDArraySize(); k++)
    {
        msgLanID[k] = msg->getLanID(k);
        if(msg->getLanID(k) != ISISIft.at(i).L1DIS[k]){
            equal = false;
            //break;
        }
    }
    if(equal){
        //DIS-ID from IIH and local DIS in interface->L1DIS is same so we don't need to elect anybody
        return;

    }

//    bool last = this->amIL1DIS(i);
    unsigned char* lastDIS = new unsigned char[ISIS_SYSTEM_ID + 1];
    for (unsigned int k = 0; k < msg->getLanIDArraySize(); k++)
    {
        lastDIS[k] = ISISIft.at(i).L1DIS[k];
    }

    MACAddress localDIS, receivedDIS;
    ISISadj *tmpAdj;

//    MACAddress tmpMAC = ISISIft.at(i).entry->getMacAddress();


    //first old/local DIS
    //if DIS == me then use my MAC for specified interface
    if (this->amIL1DIS(i))
    {
        localDIS = ISISIft.at(i).entry->getMacAddress();
    }
    //else find adjacency and from that use MAC
    else
    {
        if((tmpAdj = this->getAdjBySystemID(lastDIS, L1_TYPE, ISISIft.at(i).gateIndex)) != NULL){
            localDIS = tmpAdj->mac;
        }else{
            EV << "deviceId: " << deviceId << " ISIS: Warning: Didn't find adjacency for local MAC comparison in electL1DesignatedIS "<<endl;
            localDIS = MACAddress("000000000000");
        }
    }
    //find out MAC address for IS with LAN-ID from received message
    if ((tmpAdj = this->getAdjBySystemID(msgLanID, L1_TYPE, ISISIft.at(i).gateIndex)) != NULL)
    {
        receivedDIS = tmpAdj->mac;
    }
    else
    {
        EV
                << "deviceId: " << deviceId
                        << " ISIS: Warning: Didn't find adjacency for received MAC comparison in electL1DesignatedIS "
                        << endl;
        receivedDIS = MACAddress("000000000000");
    }


    //if announced DIS priority is higher then actual one or if they are equal and src MAC is higher than mine, then it's time to update DIS
    if ((!equal)
            && ((msg->getPriority() > ISISIft.at(i).L1DISpriority)
                    || (msg->getPriority() == ISISIft.at(i).L1DISpriority
                            && (receivedDIS.compareTo(localDIS) > 0) )))
    {
        unsigned char * disLspID = new unsigned char [ISIS_SYSTEM_ID + 2];
        this->copyArrayContent(lastDIS, disLspID, ISIS_SYSTEM_ID + 1, 0, 0);
        disLspID[ISIS_SYSTEM_ID + 1] = 0;//set fragment-ID
        //purge lastDIS's LSPs
        this->purgeRemainLSP(disLspID, circuitType);

        for (unsigned int j = 0; j < msg->getLanIDArraySize(); j++)
        {
            //set new DIS
            ISISIft.at(i).L1DIS[j] = msg->getLanID(j);
        }
        //and set his priority
        ISISIft.at(i).L1DISpriority = msg->getPriority();

        //purge DIS LSP
        //clear LSP containing dead neighbour

/*        for (unsigned int it = 0; it < L1LSP.size();)
        {
            bool found = false;
            if (this->compareArrays(this->L1LSP.at(it).LSPid, lastDIS, ISIS_SYSTEM_ID + 1))
            {
                found = true;

            }

            if (found)
            {
                //mark with sequence number 0
                L1LSP.at(it).seq = 0;
                L1LSP.at(it).neighbours.clear();
                //send empty LSP informing about expiration
                this->sendSpecificL1LSP(L1LSP.at(it).LSPid);
                //now completely delete
                L1LSP.erase(L1LSP.begin() + it);

            }
            else
            {
                it++;

            }
        }*/

    }
}
void ISIS::electL2DesignatedIS ( ISISL2HelloPacket msg) [private]

Not implemented yet

See also:
electL1DesignatedIS(ISISL1HelloPacket *msg)

Definition at line 3387 of file ISIS.cc.

{

    //TODO implement
}
bool ISIS::extractISO ( ISISCons_t initial,
short  circuitType 
) [private]

Extracts ISO informations from lspDb needed to perform SPF calculation. >

Definition at line 7743 of file ISIS.cc.

Referenced by fullSPF().

                                                           {

    ISISLspDb_t *lspDb = this->getLSPDb(circuitType);
    unsigned char *lspId;

    ISISCon* connection;

    for(ISISLspDb_t::iterator it = lspDb->begin(); it != lspDb->end(); ++it){
        //getLspId
        lspId = this->getLspID((*it)->LSP);

        //check if it's zero-th fragment. if not try to find it -> getLspFromDbByID

        if(lspId[ISIS_SYSTEM_ID + 1] != 0){
            unsigned char backup = lspId[ISIS_SYSTEM_ID + 1];
            lspId[ISIS_SYSTEM_ID + 1] = 0;
            //if doesn't exist -> continue to next lsp
            if(this->getLSPFromDbByID(lspId, circuitType) == NULL){
                continue;
            }
            lspId[ISIS_SYSTEM_ID + 1] = backup;

        }
        //else
        else{
            TLV_t *tmpTLV;
            for(int offset = 0; (tmpTLV = this->getTLVByType((*it)->LSP, IS_NEIGHBOURS_LSP, offset)) != NULL; offset++){
                for(unsigned int i = 1; i + 11 <= tmpTLV->length; i += 11)
                {
                    connection = new ISISCon;
                    connection->from = new unsigned char [ISIS_SYSTEM_ID + 2];
                    this->copyArrayContent(lspId, connection->from, ISIS_SYSTEM_ID + 1, 0, 0);
                    connection->from[ISIS_SYSTEM_ID + 1] = 0;
                    connection->to = new unsigned char [ISIS_SYSTEM_ID + 2];
                    this->copyArrayContent(tmpTLV->value, connection->to, ISIS_SYSTEM_ID +1, i + 4, 0);
                    connection->to[ISIS_SYSTEM_ID + 1] = 0;
                    connection->metric = tmpTLV->value[i];//default metric
                    connection->type = false;//it's not a leaf

                    initial->push_back(connection);
                    //path->neighbours.push_back(neighbour);
                }


            }

        }
    }

    this->twoWayCheck(initial);

    return true;
}
void ISIS::floodFurtherL1LSP ( ISISLSPL1Packet msg) [private]

Send received LSP packet to all other neighbours (flooding).

Parameters:
msgreceived packet that has to be resent

Definition at line 6641 of file ISIS.cc.

Referenced by handleL1LSP().

{
    //duplicate packet

    Ieee802Ctrl *ctrl = check_and_cast <Ieee802Ctrl *> (msg->getControlInfo());


    //resend unchanged message to all L1 IS-IS enabled interfaces except of that, which message came from
    for(unsigned int i=0; i<ISISIft.size(); i++)
    {
        if(!ISISIft.at(i).passive &&
            ISISIft.at(i).ISISenabled &&
           (ISISIft.at(i).circuitType == L1_TYPE || ISISIft.at(i).circuitType == L1L2_TYPE) &&
            ISISIft.at(i).gateIndex != msg->getArrivalGate()->getIndex())
        {
            //send it
            ISISLSPL1Packet *myMsg = msg->dup();
            Ieee802Ctrl *ctrlCopy = ctrl->dup();
            myMsg->setControlInfo(ctrlCopy);

            send(myMsg, "ifOut", ISISIft.at(i).gateIndex);
        }
    }

}
void ISIS::fullSPF ( ISISTimer timer) [private]

Definition at line 7461 of file ISIS.cc.

Referenced by handleMessage().

                                  {

    ISISCons_t initial;
    ISISPaths_t ISISPaths;
    ISISPaths_t ISISTent;
    ISISPath * tmpPath;

    //let's fill up the initial paths with supported-protocol's reachability informations

    //fill ISO
    bool result;
    result = this->extractISO(&initial, timer->getIsType());
    if(!result){
        //there was an error during extraction so cancel SPF
        //todo reschedule
        this->schedule(timer);
        //TODO clean
        return;
    }

    //put myself (this IS) on TENT list
    unsigned char *lspId = this->getLSPID();//returns sysId + 00


    tmpPath = new ISISPath;
    tmpPath->to = new unsigned char[ISIS_SYSTEM_ID + 2];
    this->copyArrayContent(lspId, tmpPath->to, ISIS_SYSTEM_ID + 2, 0, 0);

    tmpPath->metric = 0;

    ISISNeighbour *neighbour = new ISISNeighbour;
    neighbour->id = new unsigned char[ISIS_SYSTEM_ID + 2];
    this->copyArrayContent(lspId, neighbour->id, ISIS_SYSTEM_ID + 2, 0, 0);
    neighbour->type = false; //not a leaf
    tmpPath->from.push_back(neighbour);

    ISISTent.push_back(tmpPath);


//    ISISCons_t *cons = this->getCons(&initial, lspId);
//    if(cons->empty()){
//        EV <<"ISIS: Error during SPF. Didn't find my own LSP"<<endl;
//        //TODO clean
//        delete cons;
//        return;
//    }
//


    //add my connections as a starting point
  /*  for(ISISCons_t::iterator it = cons->begin(); it != cons->end(); ++it){
        if ((tmpPath = this->getPath(&(ISISTent), (*it)->to)) == NULL)
        {
            //path to this destination doesn't exist, co create new
            tmpPath = new ISISPath;
            tmpPath->to = new unsigned char[ISIS_SYSTEM_ID + 2];
            this->copyArrayContent((*it)->to, tmpPath->to, ISIS_SYSTEM_ID + 2, 0, 0);
            tmpPath->metric = (*it)->metric;

            ISISNeighbour *neighbour = new ISISNeighbour;
            neighbour->id = new unsigned char[ISIS_SYSTEM_ID + 2];
            this->copyArrayContent((*it)->from, neighbour->id, ISIS_SYSTEM_ID + 2, 0, 0);
            neighbour->type = false; //not a leaf
            tmpPath->from.push_back(neighbour);

            ISISTent.push_back(tmpPath);
        }
        else
        {
            if(tmpPath->metric >= (*it)->metric){
                if(tmpPath->metric > (*it)->metric){
                    //we got better metric so clear "from" neighbours
                    tmpPath->from.clear();
                }
                //append
                tmpPath->metric = (*it)->metric;
                ISISNeighbour *neighbour = new ISISNeighbour;
                neighbour->id = new unsigned char[ISIS_SYSTEM_ID + 2];
                this->copyArrayContent((*it)->from, neighbour->id, ISIS_SYSTEM_ID + 2, 0, 0);
                neighbour->type = false; //not a leaf
                tmpPath->from.push_back(neighbour);

            }

        }

    }*/

    //TODO shoudn't i put myself in PATH list?

    for(;!ISISTent.empty();)
    {
        //tmpPath = this->getBestPath(&(this->ISISTent));

        //this->moveToPath(tmpPath);
        this->bestToPath(&initial, &ISISTent, &ISISPaths);

    }

    this->printPaths(&ISISPaths);

    //find shortest metric in TENT


    this->schedule(timer);
}
void ISIS::generateLSP ( ISISTimer timer) [private]

Definition at line 5429 of file ISIS.cc.

Referenced by handleMessage().

                                      {

    if (this->isType == L1_TYPE || this->isType == L1L2_TYPE)
    {
        this->generateLSP(L1_TYPE);
    }
    if (this->isType == L2_TYPE || this->isType == L1L2_TYPE)
    {
        this->generateLSP(L2_TYPE);
    }

    this->schedule(timer);

}
void ISIS::generateLSP ( short  circuitType) [private]

Definition at line 5449 of file ISIS.cc.

{
    /*
     * I am not 100% sure that this method correctly handle situation in which:
     * There are DIS's LSPs in DB, but when the DIS resign, and we don't generate any DIS's LSPs
     * we don't even know that we should purge something.
     * In worst case scenario these LSPs age out.
     */

    unsigned char *lspId;
    std::vector<LSPRecord *> *lspDb = this->getLSPDb(circuitType);
    //don't forget to delete it
    std::vector<ISISLSPPacket *>* tmpLSPDb;

    tmpLSPDb = this->genLSP(circuitType);

    if (lspDb->empty())
    {
        //our database is empty, so put everything from tmpLSPDb into L1LSPDb
        //LSPRecord* tmpLSPRecord;
        for (std::vector<ISISLSPPacket *>::iterator it = tmpLSPDb->begin(); it != tmpLSPDb->end(); ++it)
        {
            this->installLSP((*it), circuitType);

        }
        tmpLSPDb->clear();
    }

    else if (tmpLSPDb->empty())
    {
        //nothing generated so purge all existing LSPs
        this->purgeMyLSPs(circuitType);
    }
    else
    {
        //something in between
        /*
         * 1. get System-ID + NSEL from LSP-ID
         * 2. after processing check if the next generated (if any exist) has the same LAN-ID
         *      if not -> purge all remaining LSP fragments from database with same LAN-ID
         *      if they have same LAN-ID OR there is not another LSP fragment, continue in processing
         */

        //lspId = this->getLspID(tmpLSPDb->at(0));
        //we need to compare each LSP
        //because of the way we create LSP, from the first one that doesn't match we can discard/replace all successive
        LSPRecord * tmpLSPRecord; // = this->getLSPFromDbByID(this->getLspID(tmpLSPDb->at(0)), circuitType);
        for (; !tmpLSPDb->empty();)
        {
            lspId = this->getLspID(tmpLSPDb->front());
            if ((tmpLSPRecord = this->getLSPFromDbByID(this->getLspID(tmpLSPDb->at(0)), circuitType)) != NULL)
            {
                if (this->compareLSP(tmpLSPRecord->LSP, tmpLSPDb->at(0)))
                {
                    //LSP match we don't need to do anything
                    delete tmpLSPDb->at(0);
                    tmpLSPDb->erase(tmpLSPDb->begin());
                    tmpLSPRecord = NULL;
                    //continue;

                }
                else
                {
                    //install tmpLSPDb->at(0) into this->L1LSPDb
                    this->replaceLSP(tmpLSPDb->at(0), tmpLSPRecord, circuitType);
                    //set SRMflag on all circuits (that have at least one adjacency UP)
                    //done in replaceLSP

                    //erase
                    tmpLSPDb->erase(tmpLSPDb->begin());

                    //set tmpLSPRecord to NULL
                    tmpLSPRecord = NULL;
                    //continue;
                }
            }
            else
            {
                //install tmpLSPDb->at(0)
                this->installLSP(*tmpLSPDb->begin(), circuitType);

                //erase
                tmpLSPDb->erase(tmpLSPDb->begin());
                //break;
            }
            /* if there is any generated LSP in tmpLSPDb, and the current LSP-ID
             *  and next LSP's LSP-ID doesn't match (without fragment-ID) => we don't have any LSPs from this LAN-ID,
             *  so purge all remaining LSPs with matching LAN-ID (System-ID + NSEL)
             */
            if (!tmpLSPDb->empty() && !this->compareArrays(lspId, this->getLspID((*tmpLSPDb->begin())), ISIS_SYSTEM_ID + 1)) {
                //purge all remaining fragments with lspId (without fragment-ID)
                lspId[ISIS_SYSTEM_ID + 1] = lspId[ISIS_SYSTEM_ID + 1] + 1;
                this->purgeRemainLSP(lspId, circuitType);
            }
            //tmpLSPRecord = this->getLSPFromDbByID(this->getLspID(tmpLSPDb->at(0)), circuitType);

            delete lspId;
        }

    }

    delete tmpLSPDb;
}
std::vector< ISISLSPPacket * > * ISIS::genLSP ( short  circuitType) [private]

Create or update my own LSP.

Parameters:
circuiTypespecify level e.g. L1 or L2
Returns:
vector of generated LSPs

Definition at line 5094 of file ISIS.cc.

Referenced by generateLSP().

{
    unsigned char *myLSPID = this->getLSPID();
    ISISLSPPacket* LSP; // = new ISISLSPL1Packet;

//    if ((LSP = this->getLSPFromDbByID(myLSPID, circuitType)) != NULL)
    //we have at least "System-ID.00-00" LSP

    //generate LSP and then compare it with one found in database
    //if they differ get sequence number from the one found in database, increment it by one
    //and replace the original LSP entry -> if only one LSP is present in DB then it's easy,
    //but what to do when there are multiple fragments

    //how to compare two LSP and recognize

    //generate LSP only up to ISIS_LSP_MAX_SIZE
    /* after reaching ISIS_LSP_MAX_SIZE (minus few %) (and comparing the two LSPs and such)
     * 1.if there's more -> create new LSP
     * 2.if not, check if there's another fragment in DB (it should be enough to check only next fragment)
     *
     */

    //create new LSP
    std::vector<TLV_t *>* tlvTable = new std::vector<TLV_t *>;

    //if sizeOfNeighboursUp == 0 then return NULL
    if (!this->isAdjUp(circuitType))
    {
        //FIXME
        return new std::vector<ISISLSPPacket *>;
    }
    //TLV IS_NEIGHBOURS
    this->addTLV(tlvTable, IS_NEIGHBOURS_LSP, circuitType, 0);

    //TLV AREA ADDRESS
    this->addTLV(tlvTable, AREA_ADDRESS, circuitType);

    //add other TLVs

    //now start putting informations from tlvTable into LSP Packets

    /*
     * while(! tlvTable->empty())
     *   get first tlv from tlvTable
     *   if tlv_entry.length > max_lsp_size (minus header)
     *     we won't fit it into single lsp
     *
     *   else if tlv_entry.length > available_space in current LSP
     *     allocate new lsp
     *   else
     *     start putting it in current LSP
     *     remove it from vector
     *     DONT FORGET to PUT EVERY GENERATED LSP INTO returning vector
     *     start new iteration
     */

    TLV_t * tmpTlv;
    unsigned int tlvSize; //tmp variable
    unsigned int availableSpace = ISIS_LSP_MAX_SIZE; //available space in LSP

    //deleted at the end of generateLSP
    std::vector<ISISLSPPacket *>* tmpLSPDb = new std::vector<ISISLSPPacket *>;
    for (unsigned char fragment = 0; !tlvTable->empty(); fragment++)
    {
        if (circuitType == L1_TYPE)
        {
            LSP = new ISISLSPPacket("L1 LSP");
            LSP->setType(L1_LSP);
        }
        else if (circuitType == L2_TYPE)
        {
            LSP = new ISISLSPPacket("L2 LSP");
            LSP->setType(L2_LSP);
        }
        else
        {
            EV << "ISIS: ERROR: Wrong circuitType in genLSP()" << endl;
        }

        //set pduLength

        //set remLifeTime
        LSP->setRemLifeTime(this->lspMaxLifetime);

        //set lspID[8];
        myLSPID[ISIS_SYSTEM_ID + 1] = fragment;
        this->setLspID(LSP, myLSPID);

        //set seqNum
        LSP->setSeqNumber(1);

        //set checksum

        //set PATTLSPDBOLIS
        LSP->setPATTLSPDBOLIS(0x01); //only setting IS type = L1 (TODO)
        //set TLV
        LSP->setTest("ahoj");
                        const char * lspId = (const char *)this->getLspID(LSP);
                        LSP->setTest(lspId);
        //TLV_t tmpTLV;


        for (; !tlvTable->empty();)
        {
            tmpTlv = tlvTable->at(0);

            //TODO incorporate header size and mostly get actual MTU something like this->ISISIft.at(0).entry->getMTU()
            if (tmpTlv->length > ISIS_LSP_MAX_SIZE)
            {
                //tlv won't fit into single message (this shouldn't happen)
                EV << "ISIS: Warning: TLV won't fit into single message (this shouldn't happen)" << endl;
                tlvTable->erase(tlvTable->begin());
            }
            else if (tmpTlv->length > availableSpace)
            {
                //tlv won't fit into this LSP, so break cycle and create new LSP
//                tmpLSPDb->push_back(LSP);
                EV << "ISIS: This TLV is full." << endl;
                break;//ends inner cycle

            }
            else
            {
                this->addTLV(LSP,tmpTlv);
                //tlvSize = LSP->getTLVArraySize();
                //LSP->setTLVArraySize(tlvSize + 1);

                //update availableSpace
                availableSpace = availableSpace - (2 + tmpTlv->length);// "2" means Type and Length fields

                //clean up
                delete tmpTlv->value;
                delete tmpTlv;
                tlvTable->erase(tlvTable->begin());

            }
        }
        //this->printLSP(LSP, "genLSP, non-pseudo");
        tmpLSPDb->push_back(LSP);

    }
    //what about pseudonode?
    /*
     * H   H  EEEEE  RRRR   EEEEE
     * H   H  E      R   R  E
     * HHHHH  EEEEE  RRRR   EEEEE
     * H   H  E      R  R   E
     * H   H  EEEEE  R   R  EEEEE
     */


    std::vector<bool> activeIface; //interfaces with adjacency in state UP


    for(std::vector<ISISinterface>::iterator it = this->ISISIft.begin(); it != this->ISISIft.end(); ++it){
        activeIface.push_back(this->isUp((*it).gateIndex, circuitType));

    }

    for(std::vector<ISISinterface>::iterator it = this->ISISIft.begin(); it != this->ISISIft.end(); ++it)
    {
        //if at least one adjacency is UP and network type is broadcast (there is no DIS on PTP) AND I am DIS on this interface
        if(this->isUp((*it).gateIndex, circuitType) && (*it).network && this->amIL1DIS(this->getIfaceIndex(&(*it))))
        {
            tlvTable->clear();
            //tmpLSPDb->clear(); //Why? Why? Why, you fucked-up crazy-ass weirdo beaver?!?
            availableSpace = ISIS_LSP_MAX_SIZE;
            unsigned char nsel;
            if(circuitType == L1_TYPE){
                myLSPID[ISIS_SYSTEM_ID] = (*it).L1DIS[ISIS_SYSTEM_ID];
                nsel = (*it).L1DIS[ISIS_SYSTEM_ID];
            }else if (circuitType == L2_TYPE){
                myLSPID[ISIS_SYSTEM_ID] = (*it).L2DIS[ISIS_SYSTEM_ID];
                nsel = (*it).L2DIS[ISIS_SYSTEM_ID];
            }else{
                EV <<"ISIS: ERROR: Wrong circuitType in genLSP()" << endl;
            }

            //TLV IS_NEIGHBOURS
            this->addTLV(tlvTable, IS_NEIGHBOURS_LSP, circuitType, nsel);

            //TLV AREA_ADDRESS
            this->addTLV(tlvTable, AREA_ADDRESS, circuitType);

            for (unsigned char fragment = 0; !tlvTable->empty(); fragment++)
                {

                if (circuitType == L1_TYPE)
                {
                    LSP = new ISISLSPPacket("L1 LSP"); //TODO based on circuitType
                    LSP->setType(L1_LSP);
                }
                else if (circuitType == L2_TYPE)
                {
                    LSP = new ISISLSPPacket("L2 LSP"); //TODO based on circuitType
                    LSP->setType(L2_LSP);
                }
                else
                {
                    EV << "ISIS: ERROR: Wrong circuitType in genLSP()" << endl;
                }

                //set pduLength

                //set remLifeTime
                LSP->setRemLifeTime(this->lspMaxLifetime);

                //set lspID[8];
                myLSPID[ISIS_SYSTEM_ID + 1] = fragment;
                this->setLspID(LSP, myLSPID);

                //set seqNum
                LSP->setSeqNumber(1);

                //set checksum

                //set PATTLSPDBOLIS
                LSP->setPATTLSPDBOLIS(0x01); //only setting IS type = L1 (TODO)
                //set TLV
                LSP->setTest("ahoj");
                const char * lspId = (const char *)this->getLspID(LSP);
                LSP->setTest(lspId);
                //TLV_t tmpTLV;

                for (; !tlvTable->empty();)
                {
                    tmpTlv = tlvTable->at(0);

                    //TODO incorporate header size and mostly get actual MTU something like this->ISISIft.at(0).entry->getMTU()
                    if (tmpTlv->length > ISIS_LSP_MAX_SIZE)
                    {
                        //tlv won't fit into single message (this shouldn't happen)
                        EV << "ISIS: Warning: TLV won't fit into single message (this shouldn't happen)" << endl;
                        tlvTable->erase(tlvTable->begin());
                    }
                    else if (tmpTlv->length > availableSpace)
                    {
                        //tlv won't fit into this LSP, so break cycle and create new LSP
                        //                tmpLSPDb->push_back(LSP);
                        EV << "ISIS: This TLV is full." << endl;
                        break; //ends inner cycle

                    }
                    else
                    {
                        this->addTLV(LSP, tmpTlv);
                        //tlvSize = LSP->getTLVArraySize();
                        //LSP->setTLVArraySize(tlvSize + 1);

                        //update availableSpace
                        availableSpace = availableSpace - (2 + tmpTlv->length);

                        //clean up
                        delete tmpTlv->value;
                        delete tmpTlv;
                        tlvTable->erase(tlvTable->begin());

                    }
                }
                //this->printLSP(LSP, "genLSP, pseudo");
                tmpLSPDb->push_back(LSP);

            }

        }
    }



    delete myLSPID;
    return tmpLSPDb;
}
ISISadj * ISIS::getAdj ( ISISMessage inMsg,
short  circuitType = L1_TYPE 
) [private]

This method check adjacency in table based on inMsg type and compares System-ID, MAC address and gateIndex. If any of these parameters don't match returns NULL, otherwise relevant adjacency;

Parameters:
inMsgis incoming message that is being parsed

Definition at line 2473 of file ISIS.cc.

Referenced by handleL1HelloMsg(), and handlePTPHelloMsg().

{
//    short circuitType;
    unsigned char * systemID = new unsigned char[ISIS_SYSTEM_ID];
    std::vector<ISISadj> *adjTable;

    if (inMsg->getType() == LAN_L1_HELLO)
    {
        ISISL1HelloPacket *msg = check_and_cast<ISISL1HelloPacket *>(inMsg);
        systemID = this->getSysID(msg);
                    circuitType = L1_TYPE;
        adjTable = &(this->adjL1Table);
    }
    else if (inMsg->getType() == LAN_L2_HELLO)
    {
        ISISL2HelloPacket *msg = check_and_cast<ISISL2HelloPacket *>(inMsg);
        systemID = this->getSysID(msg);
                    circuitType = L2_TYPE;
        adjTable = &(this->adjL2Table);
    }
    else if (inMsg->getType() == PTP_HELLO)
    {
        ISISPTPHelloPacket *msg = check_and_cast<ISISPTPHelloPacket *>(inMsg);
        systemID = this->getSysID(msg);
//        circuitType = msg->getCircuitType();

        adjTable = &(this->adjL1Table);
        if (circuitType == L1_TYPE)
        {
            adjTable = &(this->adjL1Table);
        }
        else if (circuitType == L2_TYPE)
        {
            adjTable = &(this->adjL2Table);
        }
    }



    int gateIndex = inMsg->getArrivalGate()->getIndex();
 //            ISISinterface * tmpIntf = this->getIfaceByGateIndex(gateIndex);
             //TODO for truly point-to-point link there would not be MAC address
             Ieee802Ctrl *ctrl = check_and_cast<Ieee802Ctrl *>(inMsg->getControlInfo());
             MACAddress tmpMac = ctrl->getSrc();

    for (std::vector<ISISadj>::iterator it = adjTable->begin(); it != adjTable->end(); ++it)
    {
        //System-ID match?
        if (compareArrays(systemID, (*it).sysID, ISIS_SYSTEM_ID))
        {

            //MAC Address and gateIndex
            //we need to check source (tmpMac) and destination interface thru we received this hello

            if (tmpMac.compareTo((*it).mac) == 0 && gateIndex == (*it).gateIndex)
            {
                if(circuitType != L2_TYPE){ //shoudn't it be "!="
                    //check if at least one areaId matches our areaId (don't do this for L2)
                    bool areaOK = false;
                    TLV_t* tmpTLV;
                    tmpTLV = this->getTLVByType(inMsg, AREA_ADDRESS, 0);
                    for (int i = 0; tmpTLV  != NULL; i++)
                    {
                        areaOK = areaOK || this->isAreaIDOK(tmpTLV, (*it).areaID);
                        tmpTLV = this->getTLVByType(inMsg, AREA_ADDRESS, i);
                    }

                    if (!areaOK)
                    {
                        //TODO schedule event AreaIDMismatch
//                        EV << "ISIS: Warning: L1_LAN_HELLO doesn't contain Area address TLV." << endl;
                        break;
                    }
                }
                delete systemID;
                return &(*it);
            }
        }
    }
    delete systemID;
    return NULL;

}
ISISadj * ISIS::getAdjByGateIndex ( int  gateIndex,
short  circuitType,
int  offset = 0 
) [private]

Since this method is used for point-to-point links only one adjacency is expected

Parameters:
gateIndexindex to global interface table

Definition at line 6770 of file ISIS.cc.

Referenced by addTLV(), sendPTPHelloMsg(), and updateMyLSP().

{

    if (circuitType == L1_TYPE || circuitType == L1L2_TYPE)//L1L2_TYPE option is there for L1L2 PTP links, because for such links there should be adjacency in both tables
    {
        for (std::vector<ISISadj>::iterator it = this->adjL1Table.begin(); it != this->adjL1Table.end(); ++it)
        {
            if ((*it).gateIndex == gateIndex)
            {
                if (offset == 0)
                {
                    return &(*it);
                }
                else
                {
                    offset--;
                }

            }
        }
    }
    else if (circuitType == L2_TYPE)
    {
        for (std::vector<ISISadj>::iterator it = this->adjL2Table.begin(); it != this->adjL2Table.end(); ++it)
        {
            if (offset == 0)
            {
                return &(*it);
            }
            else
            {
                offset--;
            }

        }
    }
    return NULL;


}
ISISadj * ISIS::getAdjBySystemID ( unsigned char *  systemID,
short  circuitType,
int  gateIndex = -1 
) [private]

Don't use this method, but rather ISIS::getAdj(ISISMessage *) which can handle multiple adjacencies between two ISes.

Parameters:
systemIDis system-ID for which we want to find adjacency
specifylevel
gateIndexspecify interface

Definition at line 2563 of file ISIS.cc.

Referenced by electL1DesignatedIS().

                                                                                        {

    /* For redundant links there could be more than one adjacency for the same System-ID.
     * We should return std::vector<ISISadj> with all adjacencies */

    if (circuitType == L1_TYPE)
    {

        for (std::vector<ISISadj>::iterator it = this->adjL1Table.begin(); it != this->adjL1Table.end(); ++it)
        {
            if (compareArrays(systemID, (*it).sysID, ISIS_SYSTEM_ID))
            {
                if (gateIndex > -1 && (*it).gateIndex != gateIndex)
                {
                    continue;
                }
                return &(*it);
            }

        }
    }
    else if (circuitType == L2_TYPE)
    {

        for (std::vector<ISISadj>::iterator it = this->adjL2Table.begin(); it != this->adjL2Table.end(); ++it)
        {
            if (compareArrays(systemID, (*it).sysID, ISIS_SYSTEM_ID))
            {
                if (gateIndex > -1 && (*it).gateIndex != gateIndex)
                {
                    continue;
                }
                return &(*it);
            }

        }
    }else if (circuitType == L1L2_TYPE){
        EV << "ISIS: ERROR: getAdjBySystemID for L1L2_TYPE is not implemented (yet)" <<endl;
        //TODO
        /* For point-to-point link there should be only ONE adjacency in both tables*/
        for (std::vector<ISISadj>::iterator it = this->adjL1Table.begin(); it != this->adjL1Table.end(); ++it)
        {
            if (compareArrays(systemID, (*it).sysID, ISIS_SYSTEM_ID))
            {
                return &(*it);
            }

        }

    }
    return NULL;
}
std::vector< ISISadj > * ISIS::getAdjTab ( short  circuitType) [private]

Definition at line 5771 of file ISIS.cc.

Referenced by isAdjUp(), and isUp().

{

    if (circuitType == L1_TYPE)
    {
        return &(this->adjL1Table);
    }
    else if (circuitType == L2_TYPE)
    {
        return &(this->adjL2Table);
    }

    return NULL;
}
void ISIS::getBestMetric ( ISISPaths_t paths) [private]

Definition at line 7732 of file ISIS.cc.

                                          {

    for(ISISPaths_t::iterator it = paths->begin(); it != paths->end(); ++it){

    }
}
ISISPath * ISIS::getBestPath ( ISISPaths_t paths) [private]

Definition at line 7724 of file ISIS.cc.

                                              {

    std::sort(paths->begin(), paths->end());
    return paths->front();

}
ISISCons_t * ISIS::getCons ( ISISCons_t cons,
unsigned char *  from 
) [private]

Definition at line 7817 of file ISIS.cc.

Referenced by moveToTent().

                                                               {

    ISISCons_t *retCon = new ISISCons_t;
    for(ISISCons_t::iterator it = cons->begin(); it != cons->end(); ){
        if(this->compareArrays((*it)->from, from, 8)){
            retCon->push_back((*it));
            it = cons->erase(it);
        }else{
            ++it;
        }
    }

    return retCon;
}
unsigned char * ISIS::getEndLspID ( ISISCSNPPacket csnp) [private]

Definition at line 4474 of file ISIS.cc.

Referenced by handleL1Csnp().

                                                     {

        unsigned char *lspId = new unsigned char[ISIS_SYSTEM_ID + 2];

        for (int i = 0; i < ISIS_SYSTEM_ID + 2; i++)
        {
            lspId[i] = csnp->getEndLspID(i);
        }

        return lspId;
}
double ISIS::getHelloInterval ( int  interfaceIndex,
short  circuitType 
) [private]

Definition at line 6896 of file ISIS.cc.

Referenced by schedule().

{

    //check if interface is DIS for specified circuitType (only on broadcast interfaces)
    //for DIS interface return one third of actual value
    int dis1, dis2;
    dis1 = dis2 = 1;
    ISISinterface tmpIntf = this->ISISIft.at(interfaceIndex);
    //TODO check whether this interface is DIS and if so, return only 1/3
    if (this->amIL1DIS(interfaceIndex))
    {
        dis1 = 3;
    }

    if (this->amIL2DIS(interfaceIndex))
    {
        dis2 = 3;
    }

    if (circuitType == L1_TYPE)
        {
            if (tmpIntf.L1HelloInterval == 0)
            {
                return 1 / tmpIntf.L1HelloMultiplier;
            }
            else
            {
                return (tmpIntf.L1HelloInterval) / dis1;
            }
        }
        else if (circuitType == L2_TYPE)
        {
            if (tmpIntf.L2HelloInterval == 0)
            {
                return 1 / tmpIntf.L2HelloMultiplier;
            }
            else
            {
                return (tmpIntf.L2HelloInterval) / dis2;
            }

        }
        else if (circuitType == L1L2_TYPE)
        {
            EV << "deviceId " << deviceId << ": Warning: Are you sure you want to know Hello interval for L1L2_TYPE ?!? in ISIS::getHelloInterval()\n";
            //return smaller of L1 and L2 hold timers
            return (this->getHelloInterval(interfaceIndex, L1_TYPE) < this->getHelloInterval(interfaceIndex, L2_TYPE) ? this->getHelloInterval(
                    interfaceIndex, L1_TYPE) :
                    this->getHelloInterval(interfaceIndex, L2_TYPE));

        }
        else
        {
            return 1;
            EV << "deviceId " << deviceId << ": Warning: Unrecognized circuitType used in ISIS::getHelloInterval()\n";
        }

return 0.0;



}
unsigned short ISIS::getHoldTime ( int  interfaceIndex,
short  circuitType = L1_TYPE 
) [private]
Parameters:
interfaceIndexis index to ISISIft vector

Definition at line 6834 of file ISIS.cc.

Referenced by sendPTPHelloMsg().

                                                                     {

    int dis1, dis2;
    dis1 = dis2 = 1;
    ISISinterface tmpIntf = this->ISISIft.at(interfaceIndex);
    //TODO check whether this interface is DIS and if so, return only 1/3
    if (this->amIL1DIS(interfaceIndex))
    {
        dis1 = 3;
    }

    if (this->amIL2DIS(interfaceIndex))
    {
        dis2 = 3;
    }

    if (circuitType == L1_TYPE)
    {
        if (tmpIntf.L1HelloInterval == 0)
        {
            return 1;
        }
        else
        {
            return (tmpIntf.L1HelloMultiplier * tmpIntf.L1HelloInterval) / dis1;
        }
    }
    else if (circuitType == L2_TYPE)
    {
        if (tmpIntf.L2HelloInterval == 0)
        {
            return 1;
        }
        else
        {
            return (tmpIntf.L2HelloMultiplier * tmpIntf.L2HelloInterval) / dis2;
        }

    }
    else if (circuitType == L1L2_TYPE)
    {
        //return smaller of L1 and L2 hold timers
        return (this->getHoldTime(interfaceIndex, L1_TYPE) < this->getHoldTime(interfaceIndex, L2_TYPE) ? this->getHoldTime(
                interfaceIndex, L1_TYPE) :
                this->getHoldTime(interfaceIndex, L2_TYPE));

    }
    else
    {
        return 1;
        EV << "deviceId " << deviceId << ": Warning: Unrecognized circuitType used in ISIS::getHoldTime()\n";
    }
    return 1; //this is here just so OMNeT wouldn't bother me with "no return in non-void method" warning
}
ISISinterface * ISIS::getIfaceByGateIndex ( int  gateIndex) [private]
Parameters:
gateIndexindex to global interface table

Definition at line 6816 of file ISIS.cc.

Referenced by handleL1HelloMsg(), handleL2HelloMsg(), handleMessage(), handlePTPHelloMsg(), purgeLSP(), sendL1Csnp(), and sendL1Psnp().

{

    for (std::vector<ISISinterface>::iterator it = this->ISISIft.begin(); it != this->ISISIft.end(); ++it)
    {

        if ((*it).gateIndex == gateIndex)
        {
            return &(*it);
        }
    }
    return NULL;
}
int ISIS::getIfaceIndex ( ISISinterface interface) [private]

Definition at line 7126 of file ISIS.cc.

Referenced by genLSP(), handleL1HelloMsg(), handlePTPHelloMsg(), sendL1Csnp(), and sendL1Psnp().

{

    for (unsigned int i = 0; i < this->ISISIft.size(); i++)
    {

        if (interface == &(ISISIft.at(i)))
        {
            return i;
        }
    }
    return 0;
}
std::vector< LSPRecord * > * ISIS::getLSPDb ( short  circuitType) [private]

Definition at line 5751 of file ISIS.cc.

Referenced by deleteLSP(), extractISO(), generateLSP(), getLSPFromDbByID(), getLspRange(), installLSP(), printLSPDB(), purgeMyLSPs(), refreshLSP(), and sendL1Csnp().

{

    if (circuitType == L1_TYPE)
    {
        return this->L1LSPDb;
    }
    else if (circuitType == L2_TYPE)
    {
        return this->L2LSPDb;
    }

    return NULL;
}
LSPRecord * ISIS::getLSPFromDbByID ( unsigned char *  LSPID,
short  circuitType 
) [private]

Definition at line 6323 of file ISIS.cc.

Referenced by extractISO(), generateLSP(), handleL1Csnp(), handleL1Lsp(), handleL1Psnp(), purgeLSP(), purgeRemainLSP(), and updateLSP().

{

    std::vector<LSPRecord *> *lspDb;

    if (LSPID == NULL)
    {
        return NULL;
    }

    lspDb = this->getLSPDb(circuitType);
    unsigned char *lspId;
    for (std::vector<LSPRecord*>::iterator it = lspDb->begin(); it != lspDb->end(); ++it)
    {
        lspId = this->getLspID((*it)->LSP);
        if (this->compareArrays(lspId, LSPID, ISIS_SYSTEM_ID + 2))
        {
            delete lspId;
            return (*it);
        }
        delete lspId;
    }

    return NULL;
}
unsigned char * ISIS::getLspID ( ISISLSPPacket msg) [private]

Definition at line 2759 of file ISIS.cc.

Referenced by deleteLSP(), extractISO(), generateLSP(), genLSP(), getLSPFromDbByID(), getLspRange(), handleL1Lsp(), handleMessage(), printLSP(), purgeLSP(), purgeMyLSPs(), refreshLSP(), removeDeadNeighbour(), sendL1Csnp(), sendL1Psnp(), and updateLSP().

                                               {

    unsigned char *lspId = new unsigned char[8]; //TODO change back to ISIS_SYSTEM_ID + 2

    for (int i = 0; i < ISIS_SYSTEM_ID + 2; i++)
    {
        lspId[i] = msg->getLspID(i);
    }

    return lspId;

}
unsigned char * ISIS::getLSPID ( ) [private]

Definition at line 6352 of file ISIS.cc.

Referenced by fullSPF(), and genLSP().

{

    unsigned char *myLSPID = new unsigned char[8];

    this->copyArrayContent((unsigned char*) this->sysId, myLSPID, ISIS_SYSTEM_ID, 0, 0);
    myLSPID[6] = 0;
    myLSPID[7] = 0;
    return myLSPID;
}
unsigned char * ISIS::getLspID ( ISISTimer timer) [private]

Definition at line 2708 of file ISIS.cc.

                                             {
    unsigned char *lspID = new unsigned char[ISIS_SYSTEM_ID + 2];

    for (int i = 0; i < ISIS_SYSTEM_ID + 2; i++)
    {
        lspID[i] = timer->getLSPid(i);
    }

    return lspID;
}
std::vector< unsigned char * > * ISIS::getLspRange ( unsigned char *  startLspID,
unsigned char *  endLspID,
short  circuitType 
) [private]

Definition at line 4429 of file ISIS.cc.

Referenced by handleL1Csnp().

                                                                                                                   {

    int res1, res2;
    unsigned char * lspID;
    std::vector<LSPRecord *> *lspDb = this->getLSPDb(circuitType);
    std::vector<unsigned char*> *lspRange = new std::vector<unsigned char *>;
    std::sort(lspDb->begin(), lspDb->end());
    //TODO we can end the search before hitting lspDb->end when DB is sorted
    for (std::vector<LSPRecord *>::iterator it = lspDb->begin(); it != lspDb->end(); ++it)
    {
        lspID = this->getLspID((*it)->LSP);
        res1 = memcmp(startLspID, lspID, ISIS_SYSTEM_ID + 2);
        res2 = memcmp(lspID, endLspID, ISIS_SYSTEM_ID + 2);
        if(res1 <= 0 && res2 >= 0){
            lspRange->push_back(lspID);
        }
        delete lspID;
    }

    return lspRange;

}
ISISPath * ISIS::getPath ( ISISPaths_t paths,
unsigned char *  id 
) [private]

Definition at line 7853 of file ISIS.cc.

Referenced by bestToPath(), and moveToTent().

                                                             {

    for(ISISPaths_t::iterator it = paths->begin(); it != paths->end(); ++it){
        if(this->compareArrays((*it)->to, id, 8)){
            return (*it);
        }
    }

    return NULL;
}
std::vector< std::vector< FlagRecord * > * > * ISIS::getSRMBQueue ( short  circuitType) [private]

Definition at line 5805 of file ISIS.cc.

Referenced by periodicSend().

                                                                         {

    if (circuitType == L1_TYPE)
    {
        return (this->L1SRMBQueue);
    }
    else if (circuitType == L2_TYPE)
    {
        return (this->L2SRMBQueue);
    }

    return NULL;
}
std::vector< std::vector< FlagRecord * > * > * ISIS::getSRMPTPQueue ( short  circuitType) [private]

Definition at line 5791 of file ISIS.cc.

Referenced by periodicSend().

                                                                           {

    if (circuitType == L1_TYPE)
    {
        return (this->L1SRMPTPQueue);
    }
    else if (circuitType == L2_TYPE)
    {
        return (this->L2SRMPTPQueue);
    }

    return NULL;
}
std::vector< FlagRecord * > * ISIS::getSRMQ ( bool  network,
int  index,
short  circuitType 
) [private]

Definition at line 5968 of file ISIS.cc.

Referenced by clearSRMflag(), and setSRMflag().

                                                                               {
    if(circuitType == L1_TYPE){
        if(network){
            return this->L1SRMBQueue->at(index);
        }else{
            return this->L1SRMPTPQueue->at(index);
        }

    }else if (circuitType == L2_TYPE){
        if(network){
                    return this->L2SRMBQueue->at(index);
                }else{
                    return this->L2SRMPTPQueue->at(index);
                }
    }
    return NULL;
}
std::vector< std::vector< FlagRecord * > * > * ISIS::getSSNBQueue ( short  circuitType) [private]

Definition at line 5833 of file ISIS.cc.

                                                                         {

    if (circuitType == L1_TYPE)
    {
        return (this->L1SSNBQueue);
    }
    else if (circuitType == L2_TYPE)
    {
        return (this->L2SSNBQueue);
    }

    return NULL;
}
std::vector< std::vector< FlagRecord * > * > * ISIS::getSSNPTPQueue ( short  circuitType) [private]

Definition at line 5819 of file ISIS.cc.

                                                                           {

    if (circuitType == L1_TYPE)
    {
        return (this->L1SSNPTPQueue);
    }
    else if (circuitType == L2_TYPE)
    {
        return (this->L2SSNPTPQueue);
    }

    return NULL;
}
std::vector< FlagRecord * > * ISIS::getSSNQ ( bool  network,
int  index,
short  circuitType 
) [private]

Definition at line 6104 of file ISIS.cc.

Referenced by clearSSNflag(), sendL1Psnp(), and setSSNflag().

                                                                               {
    if(circuitType == L1_TYPE){
        if(network){
            return this->L1SSNBQueue->at(index);
        }else{
            return this->L1SSNPTPQueue->at(index);
        }

    }else if (circuitType == L2_TYPE){
        if(network){
                    return this->L2SSNBQueue->at(index);
                }else{
                    return this->L2SSNPTPQueue->at(index);
                }
    }
    return NULL;
}
unsigned char * ISIS::getStartLspID ( ISISCSNPPacket csnp) [private]

Definition at line 4457 of file ISIS.cc.

Referenced by handleL1Csnp().

                                                       {

        unsigned char *lspId = new unsigned char[ISIS_SYSTEM_ID + 2];

        for (int i = 0; i < ISIS_SYSTEM_ID + 2; i++)
        {
            lspId[i] = csnp->getStartLspID(i);
        }

        return lspId;
}
unsigned char * ISIS::getSysID ( ISISMessage msg) [private]

Definition at line 2621 of file ISIS.cc.

Referenced by getAdj(), isAdjUp(), and purgeLSP().

{

    unsigned char *systemID = new unsigned char[ISIS_SYSTEM_ID];
    if (msg->getType() == LAN_L1_HELLO)
    {
        ISISL1HelloPacket *l1hello = check_and_cast<ISISL1HelloPacket *>(msg);
        for (int i = 0; i < ISIS_SYSTEM_ID; i++)
        {
            systemID[i] = l1hello->getSourceID(i);
        }
    }
    else if (msg->getType() == LAN_L2_HELLO)
    {
        ISISL2HelloPacket *l2hello = check_and_cast<ISISL2HelloPacket *>(msg);
        for (int i = 0; i < ISIS_SYSTEM_ID; i++)
        {
            systemID[i] = l2hello->getSourceID(i);
        }
    }
    else if (msg->getType() == PTP_HELLO)
    {
        ISISPTPHelloPacket *ptphello = check_and_cast<ISISPTPHelloPacket *>(msg);
        for (int i = 0; i < ISIS_SYSTEM_ID; i++)
        {
            systemID[i] = ptphello->getSourceID(i);
        }

    }
    else if (msg->getType() == L1_PSNP)
    {
        ISISPSNPPacket *psnp = check_and_cast<ISISPSNPPacket *>(msg);
        for (int i = 0; i < ISIS_SYSTEM_ID; i++)
        {
            systemID[i] = psnp->getSourceID(i);
        }

    }
    else if (msg->getType() == L1_CSNP)
    {
        ISISCSNPPacket *csnp = check_and_cast<ISISCSNPPacket *>(msg);
        for (int i = 0; i < ISIS_SYSTEM_ID; i++)
        {
            systemID[i] = csnp->getSourceID(i);
        }

    }
    else if (msg->getType() == L1_LSP || msg->getType() == L2_LSP)
    {
        ISISLSPPacket *lsp = check_and_cast<ISISLSPPacket *>(msg);
        for (int i = 0; i < ISIS_SYSTEM_ID; i++)
        {
            systemID[i] = lsp->getLspID(i);
        }

    }
    else
    {
        EV << "ISIS: ERROR: getSysID for this message type is not implemented (yet?): "<< msg->getType() << endl;
    }


    return systemID;

}
unsigned char * ISIS::getSysID ( ISISTimer timer) [private]

Definition at line 2692 of file ISIS.cc.

                                             {
    unsigned char *systemID = new unsigned char[ISIS_SYSTEM_ID];

    for (int i = 0; i < ISIS_SYSTEM_ID; i++)
    {
        systemID[i] = timer->getSysID(i);
    }

    return systemID;
}
TLV_t * ISIS::getTLVByType ( ISISMessage inMsg,
enum TLVtypes  tlvType,
int  offset = 0 
) [private]

Definition at line 6999 of file ISIS.cc.

Referenced by extractISO(), getAdj(), handleL1Csnp(), handleL1HelloMsg(), handleL1Psnp(), handlePTPHelloMsg(), printLSP(), and printLSPDB().

{

    for (unsigned int i = 0; i < inMsg->getTLVArraySize(); i++)
    {
        if (inMsg->getTLV(i).type == tlvType)
        {
            if (offset == 0)
            {
                return &(inMsg->getTLV(i));
            }
            else
            {
                offset--;
            }
        }
    }

    return NULL;
}
void ISIS::handleL1Csnp ( ISISCSNPPacket csnp) [private]

Definition at line 4293 of file ISIS.cc.

Referenced by handleMessage().

                                           {

    short circuitType = L1_TYPE; //TODO get circuitType from csnp
    int gateIndex = csnp->getArrivalGate()->getIndex();
    ISISinterface* intf = &(this->ISISIft.at(gateIndex));


    /* 7.3.15.2 a) 6) */
    /* we handle broadcast and non-broadcast adjacencies same way */
    if (!this->isAdjUp(csnp, circuitType))
    {
        EV << "ISIS: Warning: Discarding CSNP. Didn't find matching adjacency." << endl;
        delete csnp;
        return;
    }

    /* 7.3.15.2 a) 7) */
    /* 7.3.15.2 a) 8) */
    /* Authentication is omitted */

    std::vector<unsigned char *>* lspRange;
    lspRange = this->getLspRange(this->getStartLspID(csnp),this->getEndLspID(csnp), circuitType);




    //for -> iterate over tlvArraySize and then iterate over TLV
//    for(int i = 0; i < csnp->getTLVArraySize(); i++)
    /* 7.3.15.2 b) */
    TLV_t * tmpTlv;
    unsigned char *tmpLspID;
    for(int offset = 0; (tmpTlv = this->getTLVByType(csnp, LSP_ENTRIES, offset)) != NULL; offset++)
    {

        for(int i = 0; i < tmpTlv->length; i+=16)//TODO change 16 to something
        {
            tmpLspID = new unsigned char [ISIS_SYSTEM_ID + 2];
            this->copyArrayContent(tmpTlv->value, tmpLspID, (ISIS_SYSTEM_ID + 2), i + 2, 0);
            unsigned short remLife = tmpTlv->value[i] * 255 +tmpTlv->value[i + 1];
            /* this just makes me laugh */
            unsigned long seqNum = tmpTlv->value[i + 10] * 255 * 255 * 255 + tmpTlv->value[i + 11] * 255 *255 + tmpTlv->value[i + 12] * 255 + tmpTlv->value[i + 13];

            /* 7.3.15.2 c) */
            if (!lspRange->empty())
            {
                while (memcmp(lspRange->front(), tmpLspID, ISIS_SYSTEM_ID + 2) < 0)
                {
                    this->setSRMflag(this->getLSPFromDbByID(lspRange->front(), circuitType), gateIndex, circuitType);
                    delete lspRange->front();
                    lspRange->erase(lspRange->begin());
                }

                if (memcmp(lspRange->front(), tmpLspID, ISIS_SYSTEM_ID + 2) == 0)
                {
                    delete lspRange->front();
                    lspRange->erase(lspRange->begin());
                }
            }

            //getLspBySysID
            LSPRecord *lspRec;
            lspRec = this->getLSPFromDbByID(tmpLspID, circuitType);
            if(lspRec != NULL){
                //if values are same
                if(seqNum == lspRec->LSP->getSeqNumber() && (remLife == lspRec->LSP->getRemLifeTime() || (remLife != 0 && lspRec->LSP->getRemLifeTime() !=0))){
                    //if non-broadcast -> clear SRMflag for C
                    if(!intf->network){
                        this->clearSRMflag(lspRec, gateIndex, circuitType);
                    }
                }
                //else if received is older
                else if (seqNum < lspRec->LSP->getSeqNumber()){
                    //clean SSN and set SRM
                    this->clearSSNflag(lspRec, gateIndex, circuitType);
                    this->setSRMflag(lspRec, gateIndex, circuitType);
                }
                //else if newer
                else if(seqNum > lspRec->LSP->getSeqNumber() || (seqNum == lspRec->LSP->getSeqNumber() && lspRec->LSP->getRemLifeTime() != 0) ){
                    //setSSNflag AND if C is non-broadcast clearSRM
                    this->setSSNflag(lspRec, gateIndex, circuitType);
                    if(!intf->network){
                        this->clearSRMflag(lspRec, gateIndex, circuitType);
                    }
                }
            }
            /* 7.3.15.2 b) 5) */
            else{
                //if remLifetime, checksum, seqNum are all non-zero
                if(remLife != 0 && seqNum != 0){
                    this->printSysId((unsigned char *) this->sysId);
                    std::cout << "Received new LSP in CSNP";
                    this->printLspId(tmpLspID);
                    //create LSP with seqNum 0 and set SSNflag for C
                    //DO NOT SET SRMflag!!!!!!!
                    ISISLSPPacket *lsp = new ISISLSPPacket("LSP Packet");
                    lsp->setType(L1_LSP);
                    //remLifeTime
                    lsp->setRemLifeTime(remLife);
                    //lspID[8]
                    this->setLspID(lsp, tmpLspID);

                    //set seqNum
                    lsp->setSeqNumber(0);

                    //set PATTLSPDBOLIS
                    lsp->setPATTLSPDBOLIS(0x01);


                    //install new "empty" LSP and set SSNflag
                    this->setSSNflag( this->installLSP(lsp, circuitType), gateIndex, circuitType);

                }
            }
            delete tmpLspID;
        }

    }

    while(!lspRange->empty()){
        this->setSRMflag(this->getLSPFromDbByID(lspRange->front(), circuitType), gateIndex, circuitType);
        delete lspRange->front();
        lspRange->erase(lspRange->begin());

    }
    delete lspRange;
    //if lsp-entry equals
    delete csnp;
}
void ISIS::handleL1CSNP ( ISISMessage inMsg) [private]

Handle received L1 CSNP packet. Check for existing LSPs in LSP table. Those with lower sequence number number or missing are asked for using PSNP packets. This method is deprecated.

Parameters:
inMsgrecived L1 CSNP packet

Definition at line 4608 of file ISIS.cc.

{
    ISISCSNPL1Packet *msg = check_and_cast<ISISCSNPL1Packet *>(inMsg);

    for(unsigned int i=0; i<msg->getTLVArraySize(); i++)
    {
        //find LSP_ENTRIES TLV
        if(msg->getTLV(i).type == LSP_ENTRIES)
        {

            /*
             * TLV Value Multiples of LSP summaries, each consisting of the remaining lifetime (2 bytes), LSP ID (ID length + 2 bytes),
             * LSP sequence number(4 bytes), and LSP checksum (2 bytes). But we ignore LSP checksum so length of each LSP record in CSNP is
             * 2 bytes smaller, which give us 14 bytes of data per LSP entry.
             */

            //list of LSP to be asked for using PSNP packets
            std::vector<unsigned char *> LSPlist;

            //parse each LSP entry separatly
            for(unsigned int j=0; j<msg->getTLV(i).length / 14; j++)
            {
                unsigned char *lspEntry  = new unsigned char[14];
                this->copyArrayContent(msg->getTLV(i).value, lspEntry, 14, j*14, 0);

                //ignore time remaining for now
                //copy and compare for existing LSP id in L1LSP
                unsigned char lspid[8];
                this->copyArrayContent(lspEntry, lspid, 8, 2, 0);

                bool found = false;
                unsigned int k;
                for(k=0; k<L1LSP.size(); k++)
                {
                    if(this->compareArrays(lspid, L1LSP.at(k).LSPid, 8))
                    {
                        found = true;
                        break;

                    }
                }

                //LSP ID exists
                if(found)
                {
                    //compare sequence numbers
                    //we must built sequence number from received unsigned char array using bitshifting
                    unsigned long seqNum = (( lspEntry[10] << 24)
                            + (lspEntry[11] << 16)
                            + (lspEntry[12] << 8)
                            + (lspEntry[13] ));


                    //request update if DIS is holding newer version of LSP
                    if(seqNum > L1LSP.at(k).seq)
                    {
                         LSPlist.push_back(lspEntry);
                    }
                    else
                    {
                        //In case I received LSP with older seq number than I have stored in my db,
                        //flood my newer version
                        if(seqNum < L1LSP.at(k).seq)
                            this->sendSpecificL1LSP(lspid);
                    }
                }

                //LSP entry not found
                else
                {
                    LSPlist.push_back(lspEntry);
                }
            }


            //send PSNP packets if I have missing/outdated LSP entry/entries
            if(LSPlist.size() > 0)
            {
                this->sendL1PSNP(&LSPlist, msg->getArrivalGate()->getIndex());
            }

            break;
        }
    }
}
void ISIS::handleL1HelloMsg ( ISISMessage inMsg) [private]

Handle L1 hello messages. Insert new neighbours into L1 adjacency table (this->adjL1Table) and update status of existing neighbours.

Parameters:
inMsgincoming L1 hello packet

Definition at line 1845 of file ISIS.cc.

Referenced by handleMessage().

{

    //duplicate system ID check
    if(this->checkDuplicateSysID(inMsg))
    {
        //TODO schedule event duplicitSystemID
        return;
    }

    ISISL1HelloPacket *msg = check_and_cast<ISISL1HelloPacket *>(inMsg);


    //check if at least one areaId matches our areaId (don't do this for L2)
    bool areaOK = false;
    TLV_t* tmpTLV;
    for (int i = 0; (tmpTLV = this->getTLVByType(msg, AREA_ADDRESS, i)) != NULL; i++)
    {
        areaOK = areaOK || this->isAreaIDOK(tmpTLV);
    }

    if (!areaOK)
    {
        //TODO schedule event AreaIDMismatch
        EV << "ISIS: Warning: L1_LAN_HELLO doesn't contain Area address TLV." << endl;
        return;
    }




    //if remote system ID is contained in adjL1Table
    ISISadj *tmpAdj;
    if((tmpAdj = this->getAdj(inMsg)) != NULL)
    {

        //reset timer
        cancelEvent(tmpAdj->timer);

        //TODO use this->schedule()
        //scheduleAt(simTime() + msg->getHoldTime(), tmpAdj->timer);
        this->schedule(tmpAdj->timer, msg->getHoldTime());

        //DONT update the interface, if the gateIndex has changed, then declare the adjacency as down or at least init and then change gateIndex
        //update interface
        //tmpAdj->gateIndex = msg->getArrivalGate()->getIndex();

        //check for DIS priority and eventually set new DIS if needed; do it only if exists adjacency with state "UP"
        if(tmpAdj->state)
            electL1DesignatedIS(msg);

        //find neighbours TLV
        if ((tmpTLV = this->getTLVByType(msg, IS_NEIGHBOURS_HELLO)) != NULL)
        {
            unsigned char *tmpRecord = new unsigned char[ISIS_SYSTEM_ID];
            //walk through all neighbour identifiers contained in TLV
            for (unsigned int r = 0; r < (tmpTLV->length / ISIS_SYSTEM_ID); r++)
            {
                //check if my system id is contained in neighbour's adjL1Table
                this->copyArrayContent(tmpTLV->value, tmpRecord, ISIS_SYSTEM_ID, r * ISIS_SYSTEM_ID, 0);

                int gateIndex = inMsg->getArrivalGate()->getIndex();
                ISISinterface *tmpIntf = this->getIfaceByGateIndex(gateIndex);
                MACAddress tmpMAC = tmpIntf->entry->getMacAddress();
                if (compareArrays(tmpMAC.getAddressBytes(), tmpRecord, 6))
                {
                    //store previous state
                    bool changed = tmpAdj->state;
                    tmpAdj->state = true;

                    //if state changed, flood new LSP
                    if (changed != tmpAdj->state /*&& simTime() > 35.0*/) //TODO use at least some kind of ISIS_INITIAL_TIMER
                        //this->sendMyL1LSPs();
                    //generate event adjacencyStateChanged

                    break;
                }

            }
            delete tmpRecord;


        } else {
            //TODO Delete after debugging

            EV << "ISIS: Warning: Didn't find IS_NEIGHBOURS_HELLO TLV in LAN_L1_HELLO" << endl;
            return;
        }

    }

    //else create new record in adjL1Table
    else
    {
        //EV << "CREATING NEW ADJ RECORD\n";

        //find area ID TLV

        //create new neighbour record and set parameters
        ISISadj neighbour;
        neighbour.state = false; //set state to initial

        //set timeout of neighbour
        neighbour.timer = new ISISTimer("Neighbour_timeout");
        neighbour.timer->setTimerKind(NEIGHBOUR_DEAD);
        neighbour.timer->setIsType(L1_TYPE);
        neighbour.timer->setInterfaceIndex(this->getIfaceIndex(this->getIfaceByGateIndex(neighbour.gateIndex)));
        //set source system ID in neighbour record & in timer to identify it
        //set also lspId for easier purging LSPs
        for (unsigned int the_game = 0; the_game < msg->getSourceIDArraySize(); the_game++)
        {
            neighbour.sysID[the_game] = msg->getSourceID(the_game);
            neighbour.timer->setSysID(the_game, msg->getSourceID(the_game));
            neighbour.timer->setLSPid(the_game, msg->getSourceID(the_game));
        }
        neighbour.timer->setLSPid(ISIS_SYSTEM_ID, 0);
        neighbour.timer->setLSPid(ISIS_SYSTEM_ID + 1, 0);

        //TODO should be from message's TLV Area Addresses
        for (unsigned int i = 0; i < ISIS_AREA_ID; i++){
            neighbour.areaID[i] = this->areaId[i];
        }


        //get source MAC address of received frame
        Ieee802Ctrl *ctrl = check_and_cast<Ieee802Ctrl *>(msg->getControlInfo());
        neighbour.mac = ctrl->getSrc();

        //set gate index, which is neighbour connected to
        neighbour.gateIndex = msg->getArrivalGate()->getIndex();

        //set network type
        neighbour.network = this->getIfaceByGateIndex(neighbour.gateIndex)->network;

        this->schedule(neighbour.timer, msg->getHoldTime());
        //scheduleAt(simTime() + msg->getHoldTime(), neighbour.timer);

        //insert neighbour into adjL1Table
        adjL1Table.push_back(neighbour);
        std::sort(this->adjL1Table.begin(), this->adjL1Table.end());

        //EV << "deviceId " << deviceId << ": new adjacency\n";

   }
}
void ISIS::handleL1Lsp ( ISISLSPPacket lsp) [private]

Definition at line 3724 of file ISIS.cc.

Referenced by handleMessage().

                                        {

    /*
     * Verify that we have adjacency UP for Source-ID in lsp
     * if the lsp is received on broadcast circuit compare senders MAC address with MAC address in adjacency
     * We don't need to check Area address, it was done by verifying adjacency
     * if remainingLifetime == 0 -> purgeLSP
     * if lsp->getLspId() == this->sysID //if it's my LSP
     *  and i don't have it anymore in my lspDb, then init network wide purge ... purgeLSP()
     *  if it's my LSP and I have it in DB perform 7.3.16.1 -> they have old version so send new version to that link
     *  source is somebody else:
     * received lsp is newer or i don't have it in DB => installLSP
     *   set SRMflags and clear it for incomming interface
     *   if received on PTP set SSNflag for that interface and clear other
     * received lsp is equal(same lsp-ID, seqNumber, remLifetime both zero or both non-zero)
     *   clear SRM flag for C
     *   if C is PTP set SSN
     * received is older than in DB
     *   set SRM flag for C
     *   clear SSN flag for C
     *

     * Process PATT.. flag (IS Type, overload, etc.)

     *
     * this->updateLSP(lsp, L1_TYPE);
     */
    /* 7.3.15.1. */
    unsigned char *lspID;
    int circuitType = L1_TYPE;
    int gateIndex = lsp->getArrivalGate()->getIndex();
    /* 7.3.15.1. a) 6) */
    //returns true if for source-id in LSP there is adjacency with matching MAC address
    if(!this->isAdjUp(lsp, circuitType)){
        //no adjacency for source-id => discard lsp
        //generate event?

        EV <<"ISIS: Warning: Discarding LSP: didn't find adjacency in state UP for this LSP" <<endl;
        delete lsp;
        return;
    }

    lspID = this->getLspID(lsp);

    /* 7.3.15.1. b */
    if(lsp->getRemLifeTime() == 0){

        this->purgeLSP(lsp, circuitType);
        /* lsp is already deleted in purgeLSP */
        //delete lsp;
        delete lspID;
        return;


    }
    LSPRecord *lspRec;
    //is it my LSP?
    if(this->compareArrays(lspID, (unsigned char*) this->sysId, ISIS_SYSTEM_ID)){

        //if i don't have it anymore
        /* 7.3.15.1 c) i don't have it in DB */
        if((lspRec = this->getLSPFromDbByID(lspID, circuitType)) == NULL){
            //init network wide purge
            this->purgeLSP(lsp, circuitType);
            //delete lsp;
            delete lspID;
            return;
        }else{
            /* 7.3.15.1 c) OR no longer in the set of LSPs generated by this system */
            if (lspRec->deadTimer->getTimerKind() == LSP_DELETE) //TODO improve this
            {/*if the deadTimer is set to xxLSP_DELETE, then it's already purged
            * and in database is kept just header.
            */
                /* 7.3.15.1 c) */
                this->purgeLSP(lsp, circuitType);
                delete lspID;
                return;
            }
            /* 7.3.15.1 d) */
            //if we have it
            /* 7.3.16.1 sequence numbers */
            if(lsp->getSeqNumber() > lspRec->LSP->getSeqNumber()){
//                std::cout<<"handle seqNum: "<< lspRec->LSP->getSeqNumber() <<endl;
                lspRec->LSP->setSeqNumber(lsp->getSeqNumber() + 1); //TODO handle overflow of seqNumer
//                std::cout<<"handle seqNum: "<< lspRec->LSP->getSeqNumber() <<endl;
                this->setSRMflags(lspRec, circuitType);
                //TODO set new remaining lifetime
                //TODO reschedule deadTimer



            }else{

                delete lsp;
                delete lspID;
                return;
            }


        }
    }else{
        /* 7.3.15.1 e) 1) */
        lspRec = this->getLSPFromDbByID(lspID, circuitType);
        if(lspRec == NULL ){
            /* 7.3.15.1 e) 1) i. */
            this->installLSP(lsp, circuitType);
            delete lspID;
            return;

        }else{
            if(lsp->getSeqNumber() > lspRec->LSP->getSeqNumber()){
                /* 7.3.15.1 e) 1) i. */
                this->replaceLSP(lsp, lspRec, circuitType);
                delete lspID;
                return;

            }
            /* 7.3.15.1 e) 2) */
            /* should check also lsp->getRemLifetime != 0  OR both zero, but this is handled in purgeLSP*/
            else if(lsp->getSeqNumber() == lspRec->LSP->getSeqNumber() && lspRec->LSP->getRemLifeTime() != 0){

                /* 7.3.15.1 e) 2) i. */
                this->clearSRMflag(lspRec, gateIndex, circuitType);

                if (!this->ISISIft.at(gateIndex).network)
                {
                    /* 7.3.15.1 e) 2) ii. */
                    this->setSSNflag(lspRec, gateIndex, circuitType);
                }


            }
            /* 7.3.15.1 e) 3) */
            else if (lsp->getSeqNumber() < lspRec->LSP->getSeqNumber()){
                /* 7.3.15.1 e) 3) i. */
                this->setSRMflag(lspRec, gateIndex, circuitType);
                /* 7.3.15.1 e) 3) ii. */
                this->clearSSNflag(lspRec, gateIndex, circuitType);
            }
        }


    }
    delete lsp;
    delete lspID;
}
void ISIS::handleL1LSP ( ISISMessage inMsg) [private]

Handle received L1 LSP packet. Create new LSP records in L1 link-state database (this->L1LSP) for each additional LSP contained in TLV of LSP packet. Update existing LSP records (update sequence number and content). Flood packet further to all other neighbours if seq number of LSP > mine LSP seq number in link-state db. If packet LSP seq num < mine LSP seq number, flood mine version of LSP to all neighbours. If packet LSP seq num == 0, reflood packet further and delete dead LSP.

Parameters:
inMsgreceived L1 LSP packet

Definition at line 3549 of file ISIS.cc.

{
    EV << "ISIS: Warning: Running deprecated method" << endl;
    ISISLSPL1Packet *msg = check_and_cast<ISISLSPL1Packet *>(inMsg);

    //TODO if the Remaining Life Time is 0 a.k.a purge LSP then no TLV is present and this check should be omitted
    //check if area IDs match
    for(unsigned int i = 0; i<msg->getTLVArraySize(); i++)
    {
        if(msg->getTLV(i).type == AREA_ADDRESS && this->compareArrays((unsigned char *) this->areaId, msg->getTLV(i).value, msg->getTLV(i).length))
        {

            //area address is OK
            //try to find LSDP ID in L1 LSP DB
            bool match = false;
            unsigned int j;
            for(j=0; j<L1LSP.size(); j++)
            {
                bool found = true;
                //compare LSP IDs
                for(unsigned int k=0; k<msg->getLspIDArraySize(); k++)
                {
                    if(msg->getLspID(k) != L1LSP.at(j).LSPid[k])
                        found = false;
                }

                if(found)
                {
                    match = true;
                    break;

                }
            }

            //update record
            if(match)
            {

                //update record only if we receiver LSP with higher sequence number
                if(msg->getSeqNumber() > L1LSP.at(j).seq)
                {

                    //update timer
                    cancelEvent(L1LSP.at(j).deadTimer);
                    scheduleAt(simTime() + msg->getRemLifeTime(), L1LSP.at(j).deadTimer);   //should be 1200 secs.

                    //update sequence number
                    L1LSP.at(j).seq = msg->getSeqNumber();

                    //update neighbour records
                    std::vector<LSPneighbour> neighbours;

                    //find IS_NEIGHBOURS_LSP  TLV
                    for(unsigned int a = 0; a<msg->getTLVArraySize(); a++)
                    {
                        if(msg->getTLV(a).type == IS_NEIGHBOURS_LSP)
                        {

                            unsigned int size = (msg->getTLV(a).length - 1)/11;
                            for(unsigned int b=0; b<size; b++)
                            {
                                //neighbour record
                                LSPneighbour neighbour;

                                //set metrics
                                neighbour.metrics.defaultMetric = msg->getTLV(a).value[(b*11)+1];
                                neighbour.metrics.delayMetric = msg->getTLV(a).value[(b*11)+2];
                                neighbour.metrics.expenseMetric = msg->getTLV(a).value[(b*11)+3];
                                neighbour.metrics.errortMetric = msg->getTLV(a).value[(b*11)+4];


                                //copy LAN id
                                this->copyArrayContent(msg->getTLV(a).value, neighbour.LANid, 7, (b*11)+5, 0 );

                                //store to neighbours vector
                                neighbours.push_back(neighbour);
                            }

                            L1LSP.at(j).neighbours = neighbours;

                            break;
                        }
                    }

                    //flood msg further to other neighbours
                    this->floodFurtherL1LSP(msg);
                }
                else
                {
                    //if seqNumber is zero, purge that LSP and flood empty LSP ID with seqNumber 0 to other neighbour, so they can purge it too
                    if(msg->getSeqNumber() == 0)
                    {
                        //delete LSP
                        L1LSP.erase(L1LSP.begin() + j);
                        //send further message informing about LSP death
                        this->floodFurtherL1LSP(msg);
                    }
                    else
                    {
                        //we have received older version of LSP than we have in L1LSP DB
                        //our task is to transmit our newer version of LSP to all neighbours
                        if(msg->getSeqNumber() < L1LSP.at(j).seq)
                        {
                            this->sendSpecificL1LSP(L1LSP.at(j).LSPid);
                        }
                    }
                }
            }
            else    //create new LSP record
            {

                //don't create already dead LSP
                if(msg->getSeqNumber() > 0)
                {

                    //set timer
                    LSPrecord record;
                    record.deadTimer = new ISISTimer("L1 LSP dead");
                    record.deadTimer->setTimerKind(LSP_DEAD);

                    //set timer LSP ID and record LSP ID
                    for(unsigned int a=0; a<msg->getLspIDArraySize(); a++)
                    {
                        record.LSPid[a] = msg->getLspID(a);
                        record.deadTimer->setLSPid(a, msg->getLspID(a));
                    }
                    scheduleAt(simTime() + msg->getRemLifeTime(), record.deadTimer);

                    //set sequence number
                    record.seq = msg->getSeqNumber();

                    //find IS_NEIGHBOURS_LSP  TLV
                    for(unsigned int a = 0; a<msg->getTLVArraySize(); a++)
                    {
                        if(msg->getTLV(a).type == IS_NEIGHBOURS_LSP)
                        {

                            unsigned int size = (msg->getTLV(a).length - 1)/11;
                            for(unsigned int b=0; b<size; b++)
                            {
                                //neighbour record
                                LSPneighbour neighbour;

                                //set metrics
                                neighbour.metrics.defaultMetric = msg->getTLV(a).value[(b*11)+1];
                                neighbour.metrics.delayMetric = msg->getTLV(a).value[(b*11)+2];
                                neighbour.metrics.expenseMetric = msg->getTLV(a).value[(b*11)+3];
                                neighbour.metrics.errortMetric = msg->getTLV(a).value[(b*11)+4];


                                //copy LAN id
                                this->copyArrayContent(msg->getTLV(a).value, neighbour.LANid, 7, (b*11)+5, 0 );

                                //store to neighbours vector
                                record.neighbours.push_back(neighbour);
                            }

                            L1LSP.push_back(record);

                            break;
                        }
                    }

                    this->floodFurtherL1LSP(msg);
                }
            }
        }
    }
}
void ISIS::handleL1Psnp ( ISISPSNPPacket psnp) [private]

Definition at line 4184 of file ISIS.cc.

Referenced by handleMessage().

                                           {

    short circuitType = L1_TYPE;
    int gateIndex = psnp->getArrivalGate()->getIndex();
    ISISinterface* intf = &(this->ISISIft.at(gateIndex));
    /* 7.3.15.2. a) If circuit C is a broadcast .. */
    if(intf->network && !this->amIL1DIS(gateIndex)){
        EV << "ISIS: Warning: Discarding PSNP. Received on nonDIS interface." <<endl;
        delete psnp;
        return;
    }
    
    /* 7.3.15.2 a) 6) */
    /* we handle broadcast and non-broadcast adjacencies same way */
    if (!this->isAdjUp(psnp, circuitType))
    {
        EV << "ISIS: Warning: Discarding PSNP. Didn't find matching adjacency." << endl;
        delete psnp;
        return;
    }

    /* 7.3.15.2 a) 7) */
    /* 7.3.15.2 a) 8) */
    /* Authentication is omitted */

    //for -> iterate over tlvArraySize and then iterate over TLV
//    for(int i = 0; i < psnp->getTLVArraySize(); i++)
    /* 7.3.15.2 b) */
    TLV_t * tmpTlv;
    unsigned char *tmpLspID;
    for(int offset = 0; (tmpTlv = this->getTLVByType(psnp, LSP_ENTRIES, offset)) != NULL; offset++){

        for(int i = 0; i < tmpTlv->length; i+=16)//TODO change 16 to something
        {
            tmpLspID = new unsigned char [ISIS_SYSTEM_ID + 2];
            this->copyArrayContent(tmpTlv->value, tmpLspID, (ISIS_SYSTEM_ID + 2), i + 2, 0);
            unsigned short remLife = tmpTlv->value[i] * 255 +tmpTlv->value[i + 1];
            /* this just makes me laugh */
            unsigned long seqNum = tmpTlv->value[i + 10] * 255 * 255 * 255 + tmpTlv->value[i + 11] * 255 *255 + tmpTlv->value[i + 12] * 255 + tmpTlv->value[i + 13];
            //getLspBySysID
            LSPRecord *lspRec;
            lspRec = this->getLSPFromDbByID(tmpLspID, circuitType);
            if(lspRec != NULL){
                /* 7.3.15.2 b) 2) */
                //if values are same
                if(seqNum == lspRec->LSP->getSeqNumber() && (remLife == lspRec->LSP->getRemLifeTime() || (remLife != 0 && lspRec->LSP->getRemLifeTime() !=0))){
                    //if non-broadcast -> clear SRMflag for C
                    if(!intf->network){
                        this->clearSRMflag(lspRec, gateIndex, circuitType);
                    }
                }
                /* 7.3.15.2 b) 3) */
                //else if received is older
                else if (seqNum < lspRec->LSP->getSeqNumber()){
                    //clean SSN and set SRM
                    this->clearSSNflag(lspRec, gateIndex, circuitType);
                    this->setSRMflag(lspRec, gateIndex, circuitType);
                }
                /* 7.3.15.2 b) 4) */
                //else if newer
                else if(seqNum > lspRec->LSP->getSeqNumber() || (seqNum == lspRec->LSP->getSeqNumber() && lspRec->LSP->getRemLifeTime() != 0) ){
                    //setSSNflag AND if C is non-broadcast clearSRM
                    this->setSSNflag(lspRec, gateIndex, circuitType);
                    if(!intf->network){
                        this->clearSRMflag(lspRec, gateIndex, circuitType);
                    }
                }
            }
            /* 7.3.15.2 b) 5) */
            else{
                //if remLifetime, checksum, seqNum are all non-zero
                if(remLife != 0 && seqNum != 0){
                    this->printSysId((unsigned char *)this->sysId);
                    std::cout<<"Received new LSP in PSNP";
                    this->printLspId(tmpLspID);
                    //create LSP with seqNum 0 and set SSNflag for C
                    //DO NOT SET SRMflag!!!!!!!
                    ISISLSPPacket *lsp = new ISISLSPPacket("LSP Packet");
                    lsp->setType(L1_LSP);
                    //remLifeTime
                    lsp->setRemLifeTime(remLife);
                    //lspID[8]
                    this->setLspID(lsp, tmpLspID);

                    //set seqNum
                    lsp->setSeqNumber(0);

                    //set PATTLSPDBOLIS
                    lsp->setPATTLSPDBOLIS(0x01);


                    //install new "empty" LSP and set SSNflag
                    this->setSSNflag( this->installLSP(lsp, circuitType), gateIndex, circuitType);

                }
            }
            delete tmpLspID;
        }

    }
    //if lsp-entry equals
    delete psnp;
}
void ISIS::handleL1PSNP ( ISISMessage inMsg) [private]

Handle PSNP received from another IS. Content of packet informs about LSPs which have to be sent.

Parameters:
inMsgreceived PSNP packet
See also:
sendL1PSNP(std::vector<unsigned char *> * LSPlist, int gateIndex)
handleL1CSNP(ISISMessage * inMsg)

Definition at line 4778 of file ISIS.cc.

{
    ISISPSNPL1Packet *msg = check_and_cast<ISISPSNPL1Packet *>(inMsg);


    //PSNP packets should process only DIS, therefore we need to check this

    //find interface which packet came from
    for(unsigned int i=0; i<ISISIft.size(); i++)
    {
        //we found dat interface
        if(ISISIft.at(i).gateIndex == msg->getArrivalGate()->getIndex())
        {
            unsigned char LanID[7];

            //set LAN ID which consists of system ID + pseudonode ID
            this->copyArrayContent((unsigned char *)this->sysId, LanID, 6, 0, 0);   //set system ID
            LanID[6] = ISISIft.at(i).gateIndex + 1;    //set pseudonode ID

            //compare Ift's DIS with LAN ID
            //if they don't match, I'm not DIS on dat LAN and no processing of PSNP packet is necessary
            if(!(this->compareArrays(LanID, ISISIft.at(i).L1DIS, 7)))
                return;
        }
    }

    for(unsigned int i=0; i<msg->getTLVArraySize(); i++)
    {
        //find LSP_ENTRIES TLV
        if(msg->getTLV(i).type == LSP_ENTRIES)
        {

            /*
             * TLV Value Multiples of LSP summaries, each consisting of the remaining lifetime (2 bytes), LSP ID (ID length + 2 bytes),
             * LSP sequence number(4 bytes), and LSP checksum (2 bytes). But we ignore LSP checksum so length of each LSP record in CSNP is
             * 2 bytes smaller, which give us 14 bytes of data per LSP entry.
             */

            //parse each LSP entry separately
            for(unsigned int j=0; j<msg->getTLV(i).length / 14; j++)
            {
                unsigned char lspEntry[14];
                this->copyArrayContent(msg->getTLV(i).value, lspEntry, 14, j*14, 0);

                //ignore time remaining for now
                //copy and compare for existing LSP id in L1LSP
                unsigned char lspid[8];
                this->copyArrayContent(lspEntry, lspid, 8, 2, 0);

                //send LSP packet containing relevant data
                this->sendSpecificL1LSP(lspid);
            }
        }

        break;
    }
}
void ISIS::handleL2CSNP ( ISISMessage msg) [private]

Not implemented yet

Definition at line 4697 of file ISIS.cc.

{
    //TODO
}
void ISIS::handleL2HelloMsg ( ISISMessage inMsg) [private]

Handle L2 hello messages. Insert new neighbours into L2 adjacency table (this->adjL2Table) and update status of existing neighbours.

Parameters:
inMsgincoming L2 hello packet

Definition at line 1996 of file ISIS.cc.

Referenced by handleMessage().

{

    //duplicate system ID check
    if(this->checkDuplicateSysID(inMsg))
    {
        //TODO schedule event duplicitSystemID
        return;
    }


    ISISL2HelloPacket *msg = check_and_cast<ISISL2HelloPacket *>(inMsg);
    bool idMatch = false;

    //check for DIS priority and eventually set new DI if needed

    //TODO enable L2 election when it's implemented ^_^
    //electL2DesignatedIS(msg);


    unsigned int i;
    //walk through adjacency table and look for existing L2 neighbours
    for(i=0;i<adjL2Table.size();i++)
    {

        bool found = true;
        //try to find match in system ID
        for(unsigned int j=0; j<msg->getSourceIDArraySize();j++)
        {
            if(msg->getSourceID(j) != adjL2Table.at(i).sysID[j])
                found = false;
        }

        //area ID must also match
        for(unsigned int j=0; j<msg->getTLVArraySize();j++)
        {
            if(msg->getTLV(j).type == AREA_ADDRESS)
            {
                if(!(this->compareArrays(msg->getTLV(j).value, adjL2Table.at(i).areaID, ISIS_AREA_ID)))
                {
                    found = false;
                }
            }
        }

        //if we found match
        if(found)
        {
            idMatch = true;
            break;
        }
     }

    //if remote system ID is contained in adjL2Table
    if(idMatch)
    {

        //reset timer
        cancelEvent(adjL2Table.at(i).timer);
        scheduleAt(simTime() + msg->getHoldTime(), adjL2Table.at(i).timer);

        //update interface
        adjL2Table.at(i).gateIndex = msg->getArrivalGate()->getIndex();

        //find neighbours TLV
        for(unsigned int j = 0; j< msg->getTLVArraySize(); j++)
        {
            //we found it!
            if(msg->getTLV(j).type == IS_NEIGHBOURS_HELLO)
            {

                unsigned char *tmpRecord = new unsigned char [6];
                //walk through all neighbour identifiers contained in TLV

                //EV<< "TLV Length " << msg->getTLV(j).length <<endl;
                for(unsigned int r = 0; r < (msg->getTLV(j).length / 6); r++)
                {
                    //check if my system id is contained in neighbour's adjL1Table
                    this->copyArrayContent(msg->getTLV(j).value, tmpRecord, 6, r*6, 0);

                    EV << "MAC: ";
                    for(unsigned int hh = 0; hh < 6; hh++)
                    {
                        EV << setfill('0') << setw(2) << hex << (unsigned int)tmpRecord[hh] << ":";
                    }
                    EV <<endl;

                    //check if TLV contains one of my own MAC addresses
                    for(unsigned int o = 0; o<ISISIft.size(); o++)
                    {
                        MACAddress tmpMAC = ISISIft.at(o).entry->getMacAddress();
                        if(compareArrays(tmpMAC.getAddressBytes(), tmpRecord, 6))
                        {
                            adjL2Table.at(i).state = true;
                            break;
                        }
                    }
                }
                delete tmpRecord;
                break;  //break finding cycle
            }
        }
    }

    //else create new record in adjL1Table
    else
    {
        //EV << "CREATING NEW ADJ RECORD\n";

        //find area ID TLV
        unsigned int k;
        for(k = 0; k<msg->getTLVArraySize(); k++)
        {
            //we found area ID TLV
            //area IDs have to be different!!
            if(msg->getTLV(k).type == AREA_ADDRESS)
            {

                //create new neighbour record and set parameters
                ISISadj neighbour;
                neighbour.state = false;                    //set state to initial

                //set timeout of neighbour
                neighbour.timer = new ISISTimer("Neighbour_timeout");
                neighbour.timer->setTimerKind(NEIGHBOUR_DEAD);
                //TODO set interfaceIndex
                neighbour.timer->setIsType(L2_TYPE);
                //set source system ID in neighbour record & in timer to identify it

                //set neighbours system ID
                for(unsigned int the_game = 0; the_game<msg->getSourceIDArraySize(); the_game++)
                {
                    neighbour.sysID[the_game] = msg->getSourceID(the_game);
                    neighbour.timer->setSysID(the_game, msg->getSourceID(the_game));
                }

                //set neighbours area ID
                this->copyArrayContent(msg->getTLV(k).value, neighbour.areaID, msg->getTLV(k).length, 0, 0);

                for(unsigned int z=0; z<msg->getTLV(k).length; z++)
                {
                    neighbour.timer->setAreaID(z, msg->getTLV(k).value[z]);
                }

                //get source MAC address of received frame
                Ieee802Ctrl *ctrl = check_and_cast <Ieee802Ctrl *> (msg->getControlInfo());
                neighbour.mac = ctrl->getSrc();

                //set gate index, which is neighbour connected to
                neighbour.gateIndex = msg->getArrivalGate()->getIndex();

                //set network type
                neighbour.network = this->getIfaceByGateIndex(neighbour.gateIndex)->network;

                this->schedule(neighbour.timer, msg->getHoldTime());
                //scheduleAt(simTime() + msg->getHoldTime(), neighbour.timer);

                //insert neighbour into adjL1Table
                adjL2Table.push_back(neighbour);
                std::sort(this->adjL2Table.begin(), this->adjL2Table.end());

                //EV << "deviceId " << deviceId << ": new adjacency\n";
                 break;  //end cycle
            }
        }
   }
}
void ISIS::handleL2LSP ( ISISMessage msg) [private]

Not implemented yet

See also:
handleL1LSP(ISISMessage * inMsg)

Definition at line 3892 of file ISIS.cc.

{
    //TODO
}
void ISIS::handleL2PSNP ( ISISMessage msg) [private]

Not implemented yet

Definition at line 4839 of file ISIS.cc.

{
    //TODO
}
void ISIS::handleMessage ( cMessage *  msg) [protected, virtual]

Handle incoming messages: Method differs between self messages and external messages and executes appropriate function.

Parameters:
msgincoming message

Definition at line 1009 of file ISIS.cc.

{

    if (msg->isSelfMessage())
    {
        ISISTimer *timer = check_and_cast<ISISTimer *>(msg);
        switch (timer->getTimerKind())
            {
            case (ISIS_START):
                this->initISIS();
                delete timer;
                break;

            case (HELLO_TIMER):
                this->sendHelloMsg(timer);
                break;

            case (NEIGHBOUR_DEAD):
                this->removeDeadNeighbour(timer);
                delete timer;
                break;

            case (GENERATE_LSP_TIMER):
                this->generateLSP(timer);
                break;

            case (LSP_REFRESH):
                this->refreshLSP(timer);
                break;

            case (LSP_DEAD):
                this->purgeLSP(this->getLspID(timer), timer->getIsType());

                //delete timer; don't delete timer, it's re-used for LSP_DELETE
                break;

            case (LSP_DELETE):
                this->deleteLSP(timer);
                this->drop(timer);
                delete timer;
                break;

            case (CSNP_TIMER):
                if (timer->getIsType() == L1_TYPE)
                {
                    this->sendL1Csnp(timer);
                }
                else if (timer->getIsType() == L2_TYPE)
                {
                    EV << "ISIS: Warning: Discarding CSNP_TIMER for level 2" << endl;
                    delete timer;
                }
                else
                {
                    EV << "ISIS: Warning: Discarding CSNP_TIMER for L1L2." << endl;
                    delete timer;
                }
                break;

            case (PSNP_TIMER):
                if (timer->getIsType() == L1_TYPE)
                {
                    this->sendL1Psnp(timer);
                }
                else if (timer->getIsType() == L2_TYPE)
                {
                    delete timer;
                    EV << "ISIS: Warning: Discarding PSNP_TIMER for level 2" << endl;
                }
                else
                {
                    delete timer;
                    EV << "ISIS: Warning: Discarding PSNP_TIMER for L1L2." << endl;
                }
                break;

            case (PERIODIC_SEND):
                this->periodicSend(timer, timer->getIsType());
                break;

            case (SPF_FULL):
                    this->fullSPF(timer);
            break;

            default:
                EV<< "ISIS: Warning: Received unsupported Timer type in handleMessage" <<endl;
                delete timer;
                break;
        }
    }
    else
    {

        //every (at least all Hello) message should be checked for matching system-ID length

        //shouldn't check this->isType, but rather circuitType on incoming interface
        ISISMessage *inMsg = check_and_cast<ISISMessage *>(msg);
        if(!this->isMessageOK(inMsg)){
            EV<< "ISIS: Warning: discarding message" <<endl;
            //TODO schedule event discarding message
            delete msg;
            return;
        }

        //get arrival interface
        int gateIndex = inMsg->getArrivalGate()->getIndex();
        ISISinterface * tmpIntf = this->getIfaceByGateIndex(gateIndex);
        if(tmpIntf == NULL){
            EV << "ISIS: ERROR: Couldn't find interface by gate index when ISIS::handleMessage" << endl;
            delete msg;
            return;
        }

        //get circuit type for arrival interface
        short circuitType = tmpIntf->circuitType;

        /* Usually we shouldn't need to check matching circuit type with arrived message,
         * and these messages should be filtered based on destination MAC address.
         * Since we use broadcast MAC address, IS(router) cannot determine if it's
         * for ALL L1 or ALL L2 systems. Therefore wee need to check manually.
         * If appropriate Level isn't enabled on interface, then the message is dicarded.
        */

        switch (inMsg->getType())
        {
            case (LAN_L1_HELLO):
                if (circuitType == L1_TYPE || circuitType == L1L2_TYPE)
                {
                    this->handleL1HelloMsg(inMsg);

                    //comment if printing of the adjacency table is too disturbing
                    this->printAdjTable();

                }else{
                    EV << "deviceId " << deviceId
                                          << ": ISIS: WARNING: Discarding LAN_L1_HELLO message on unsupported circuit type interface "<< inMsg->getId() << endl;
                }
                delete inMsg;
                break;
            case (LAN_L2_HELLO):
                if (circuitType == L2_TYPE || circuitType == L1L2_TYPE)
                {
                    this->handleL2HelloMsg(inMsg);
                    this->printAdjTable();

                }
                else
                {
                    EV << "deviceId "
                                    << deviceId
                                    << ": ISIS: WARNING: Discarding LAN_L2_HELLO message on unsupported circuit type interface "
                                    << inMsg->getId() << endl;
                }
                delete inMsg;
                break;
            case (PTP_HELLO):
                    //On PTP link process all Hellos
                if (circuitType != RESERVED_TYPE)
                {
                    this->handlePTPHelloMsg(inMsg);
                    this->printAdjTable();
                }
                else
                {
                    EV
                                    << "deviceId "
                                    << deviceId
                                    << ": ISIS: WARNING: Discarding PTP_HELLO message. Received RESERVED_TYPE circuit type "
                                    << inMsg->getId() << endl;
                }
                delete inMsg;
                break;

            case (L1_LSP):
                if (circuitType == L1_TYPE || circuitType == L1L2_TYPE)
                {
                    //this->handleL1LSP(inMsg);
                    //this->printLSPDB();
//                    std::cout<<"Handle LSP on: ";
//                        this->printSysId((unsigned char *)this->sysId);
//                        std::cout<< endl;
                    //this->printLSP(check_and_cast<ISISLSPPacket *>(msg), "Handle L1_LSP");
                    this->handleL1Lsp(check_and_cast<ISISLSPPacket *>(msg));


                    //comment if printing of the link-state database is too disturbing
                    this->printLSPDB();
                }
                else
                {
                    EV
                                    << "deviceId "
                                    << deviceId
                                    << ": ISIS: WARNING: Discarding LAN_L1_HELLO message on unsupported circuit type interface "
                                    << inMsg->getId() << endl;
                }
                //delete inMsg; //TODO don't delete inMsg in new version
                break;

            case (L1_CSNP):
                if (circuitType == L1_TYPE || circuitType == L1L2_TYPE)
                {
                    //this->handleL1CSNP(inMsg);
                    this->handleL1Csnp(check_and_cast<ISISCSNPPacket *>(msg));
                    this->printLSPDB();
                }
                else
                {
                    EV
                                    << "deviceId "
                                    << deviceId
                                    << ": ISIS: WARNING: Discarding LAN_L1_HELLO message on unsupported circuit type interface\n"
                                    << inMsg->getId() << endl;
                }
                //delete inMsg;
                break;
            case (L1_PSNP):
                if (circuitType == L1_TYPE || circuitType == L1L2_TYPE)
                {
                    this->handleL1Psnp(check_and_cast<ISISPSNPPacket *>(msg));
                    this->printLSPDB();
                    //delete inMsg;
                }
                break;
            default:
                EV  << "deviceId " << deviceId << ": ISIS: WARNING: Discarding unknown message type. Msg id: "
                                << inMsg->getId() << endl;
                delete inMsg;
                break;

        }
    }
}
void ISIS::handlePTPHelloMsg ( ISISMessage inMsg) [private]

Handle PTP hello messages. If necessary creates new adjacency. Handles both L1, L2 and L1L2 PtP Hellos. Update status of existing neighbours.

Parameters:
inMsgincoming PtP hello packet

Definition at line 2170 of file ISIS.cc.

Referenced by handleMessage().

                                              {
    //duplicate system ID check
    if (this->checkDuplicateSysID(inMsg))
    {
        //TODO schedule event duplicitSystemID
        return;
    }

    ISISPTPHelloPacket *msg = check_and_cast<ISISPTPHelloPacket *>(inMsg);

    //check if at least one areaId matches our areaId (don't do this for L2)
    TLV_t* tmpTLV;
    if (msg->getCircuitType() != L2_TYPE)
    {
        bool areaOK = false;
        tmpTLV = this->getTLVByType(msg, AREA_ADDRESS, 0);
        for (int i = 0; (tmpTLV) != NULL; i++)
        {
            areaOK = areaOK || this->isAreaIDOK(tmpTLV);
            tmpTLV = this->getTLVByType(msg, AREA_ADDRESS, i);
        }

        if (!areaOK)
        {
            //TODO schedule event AreaIDMismatch
            EV << "ISIS: Warning: PTP_HELLO doesn't contain Area address TLV." << endl;
            return;
        }
    }
    //if remote system ID is contained in adjL1Table
    ISISadj *tmpAdj;
    if (msg->getCircuitType() == L1_TYPE || msg->getCircuitType() == L1L2_TYPE)
    {

        if ((tmpAdj = this->getAdj(inMsg, L1_TYPE)) != NULL)
        {

            //reset timer
            cancelEvent(tmpAdj->timer);

            //TODO use this->schedule()
            scheduleAt(simTime() + msg->getHoldTime(), tmpAdj->timer);

            //find neighbours TLV
            if ((tmpTLV = this->getTLVByType(msg, PTP_HELLO_STATE)) != NULL)
            {
                if (tmpTLV->length == 1)
                {

                    if (tmpAdj->state) //UP
                    {

                        if (tmpTLV->value[0] == PTP_UP)
                        {
                            //OK do nothing
                        }
                        else if(tmpTLV->value[0] == PTP_DOWN)
                        {
                            //state init
                            //TODO
                            tmpAdj->state = false;

                        }else{
                            //state accept
                        }

                    }
                    else // INIT
                    {
                        if (tmpTLV->value[0] == PTP_UP || tmpTLV->value[0] == PTP_INIT)
                        {
                            //OK
                            tmpAdj->state = true;
//                            if (simTime() > 35.0){ //TODO use at least some kind of ISIS_INITIAL_TIMER
                            //this->sendMyL1LSPs();
//                            }
                            //TODO
                            //schedule adjacencyStateChange(up);
                        }
                        else
                        {
                            //stay init
                        }
                    }
                }

            }
            else
            {
                //TODO Delete after debugging
                EV << "ISIS: Warning: Didn't find PTP_HELLO_STATE TLV in PTP_HELLO L2" << endl;
                return;
            }

        }

        //else create new record in adjL1Table
        else
        {
            //EV << "CREATING NEW ADJ RECORD\n";

            //find area ID TLV

            //create new neighbour record and set parameters
            ISISadj neighbour;
            neighbour.state = false; //set state to initial

            //set timeout of neighbour
            neighbour.timer = new ISISTimer("Neighbour_timeout");
            neighbour.timer->setTimerKind(NEIGHBOUR_DEAD);
            neighbour.timer->setIsType(L1_TYPE);
            neighbour.timer->setInterfaceIndex(this->getIfaceIndex(this->getIfaceByGateIndex(neighbour.gateIndex)));
            //set source system ID in neighbour record & in timer to identify it

            for (unsigned int the_game = 0; the_game < msg->getSourceIDArraySize(); the_game++)
            {
                neighbour.sysID[the_game] = msg->getSourceID(the_game);
                neighbour.timer->setSysID(the_game, msg->getSourceID(the_game));
            }

            //TODO should be from message's TLV Area Addresses
            for (unsigned int i = 0; i < ISIS_AREA_ID; i++)
            {
                neighbour.areaID[i] = this->areaId[i];
            }

            //get source MAC address of received frame
            Ieee802Ctrl *ctrl = check_and_cast<Ieee802Ctrl *>(msg->getControlInfo());
            neighbour.mac = ctrl->getSrc();

            //set gate index, which is neighbour connected to
            neighbour.gateIndex = msg->getArrivalGate()->getIndex();

            //set network type
            neighbour.network = this->getIfaceByGateIndex(neighbour.gateIndex)->network;

            this->schedule(neighbour.timer, msg->getHoldTime());
            //scheduleAt(simTime() + msg->getHoldTime(), neighbour.timer);

            //insert neighbour into adjL1Table
            adjL1Table.push_back(neighbour);
            std::sort(this->adjL1Table.begin(), this->adjL1Table.end());

            //EV << "deviceId " << deviceId << ": new adjacency\n";

        }
    }

    if (msg->getCircuitType() == L2_TYPE || msg->getCircuitType() == L1L2_TYPE)
    {
        if ((tmpAdj = this->getAdj(inMsg, L2_TYPE)) != NULL)
        {
            //reset timer
            cancelEvent(tmpAdj->timer);

            //TODO use this->schedule()
            scheduleAt(simTime() + msg->getHoldTime(), tmpAdj->timer);

            //find neighbours TLV
            if ((tmpTLV = this->getTLVByType(msg, PTP_HELLO_STATE)) != NULL)
            {
                if (tmpTLV->length == 1)
                {
                    if (tmpAdj->state) //UP
                    {
                        if (tmpTLV->value[0] == PTP_UP)
                        {
                            //OK do nothing
                        }
                        else if (tmpTLV->value[0] == PTP_DOWN)
                        {
                            //state init
                            //TODO
                            tmpAdj->state = false;

                        }
                        else
                        {
                            //state accept
                        }

                    }
                    else // INIT
                    {
                        if (tmpTLV->value[0] == PTP_UP || tmpTLV->value[0] == PTP_INIT)
                        {
                            //OK
                            tmpAdj->state = true;
//                            if (simTime() > 35.0)
//                            { //TODO use at least some kind of ISIS_INITIAL_TIMER
                                //this->sendMyL2LSPs();
//                            }
                            //TODO
                            //schedule adjacencyStateChange(up);
                        }
                        else
                        {
                            //stay init
                        }
                    }
                }

            }
            else
            {
                //TODO Delete after debugging
                EV << "ISIS: Warning: Didn't find PTP_HELLO_STATE TLV in PTP_HELLO" << endl;
                return;
            }

        }

        //else create new record in adjL2Table
        else
        {
            //EV << "CREATING NEW ADJ RECORD\n";

            //find area ID TLV

            //create new neighbour record and set parameters
            ISISadj neighbour;
            neighbour.state = false; //set state to initial

            //set timeout of neighbour
            neighbour.timer = new ISISTimer("Neighbour_timeout");
            neighbour.timer->setTimerKind(NEIGHBOUR_DEAD);
            neighbour.timer->setIsType(L2_TYPE);
            neighbour.timer->setInterfaceIndex(this->getIfaceIndex(this->getIfaceByGateIndex(neighbour.gateIndex)));

            //set source system ID in neighbour record & in timer to identify it
            for (unsigned int the_game = 0; the_game < msg->getSourceIDArraySize(); the_game++)
            {
                neighbour.sysID[the_game] = msg->getSourceID(the_game);
                neighbour.timer->setSysID(the_game, msg->getSourceID(the_game));
            }
            //set neighbours area ID
            tmpTLV = this->getTLVByType(msg, AREA_ADDRESS);

             this->copyArrayContent(tmpTLV->value, neighbour.areaID, tmpTLV->length, 0, 0);

             for(unsigned int z=0; z<tmpTLV->length; z++)
             {
                 neighbour.timer->setAreaID(z, tmpTLV->value[z]);
             }

            //get source MAC address of received frame
            Ieee802Ctrl *ctrl = check_and_cast<Ieee802Ctrl *>(msg->getControlInfo());
            neighbour.mac = ctrl->getSrc();

            //set gate index, which is neighbour connected to
            neighbour.gateIndex = msg->getArrivalGate()->getIndex();

            //set network type
            neighbour.network = this->getIfaceByGateIndex(neighbour.gateIndex)->network;

            this->schedule(neighbour.timer, msg->getHoldTime());
            //scheduleAt(simTime() + msg->getHoldTime(), neighbour.timer);

            //insert neighbour into adjL2Table
            adjL2Table.push_back(neighbour);
            std::sort(this->adjL2Table.begin(), this->adjL2Table.end());

            //EV << "deviceId " << deviceId << ": new adjacency\n";

        }

    }

}
void ISIS::initCsnp ( ) [private]

Definition at line 888 of file ISIS.cc.

Referenced by initISIS().

{

    ISISTimer *timerMsg;
    ISISinterface *iface;
    for (unsigned int k = 0; k < this->ISISIft.size(); k++)
    {
        iface = &(this->ISISIft.at(k));

        //don't schedule sending CSNP PDU on passive or not ISIS-enabled interface
        if (!iface->ISISenabled || iface->passive)
        {
            continue;
        }

        if (iface->network && iface->circuitType == L1L2_TYPE)
        {
            timerMsg = new ISISTimer("CSNP L1");
            timerMsg->setTimerKind(CSNP_TIMER);
            timerMsg->setIsType(L1_TYPE);
            timerMsg->setInterfaceIndex(k);
            this->schedule(timerMsg);

            timerMsg = new ISISTimer("CSNP L2");
            timerMsg->setTimerKind(CSNP_TIMER);
            timerMsg->setIsType(L2_TYPE);
            timerMsg->setInterfaceIndex(k);
            this->schedule(timerMsg);

        }
        else
        {
            timerMsg = new ISISTimer("CSNP");
            timerMsg->setTimerKind(CSNP_TIMER);
            timerMsg->setIsType(iface->circuitType);
            timerMsg->setInterfaceIndex(k);
            this->schedule(timerMsg);

        }
    }
}
void ISIS::initGenerate ( ) [private]

Definition at line 814 of file ISIS.cc.

Referenced by initISIS().

{
    ISISTimer *timerMsg;

    if (this->isType == L1L2_TYPE)
    {
        timerMsg = new ISISTimer("Generate LSPs timer");
        timerMsg->setTimerKind(GENERATE_LSP_TIMER);
        timerMsg->setIsType(L1_TYPE);
        this->schedule(timerMsg);

        timerMsg = new ISISTimer("Generate LSPs timer");
        timerMsg->setTimerKind(GENERATE_LSP_TIMER);
        timerMsg->setIsType(L2_TYPE);
        this->schedule(timerMsg);

    }
    else
    {
        timerMsg = new ISISTimer("Generate LSPs timer");
        timerMsg->setTimerKind(GENERATE_LSP_TIMER);
        timerMsg->setIsType(this->isType);
        this->schedule(timerMsg);

    }
    EV << "ISIS: initGenerate()" << endl;

}
void ISIS::initHello ( ) [private]

Definition at line 768 of file ISIS.cc.

Referenced by initISIS().

                    {
    ISISTimer *timerMsg;
    ISISinterface *iface;
    for (unsigned int k = 0; k < this->ISISIft.size(); k++)
    {

        //schedule Hello timer per level => check if L1L2 on broadcast => schedule two timers
        //on PTP is L1L2 Hello valid timer
        iface = &(this->ISISIft.at(k));

        //don't schedule sending hello PDU on passive or not ISIS-enabled interface
        if(!iface->ISISenabled || iface->passive){
            continue;
        }


        if (iface->network && iface->circuitType == L1L2_TYPE)
        {
            timerMsg = new ISISTimer("Hello_L1_timer");
            timerMsg->setTimerKind(HELLO_TIMER);
            timerMsg->setIsType(L1_TYPE);
            timerMsg->setInterfaceIndex(k);
            this->schedule(timerMsg);

            timerMsg = new ISISTimer("Hello_L2_timer");
            timerMsg->setTimerKind(HELLO_TIMER);
            timerMsg->setIsType(L2_TYPE);
            timerMsg->setInterfaceIndex(k);
            this->schedule(timerMsg);

        }
        else
        {
            timerMsg = new ISISTimer("Hello_timer");
            timerMsg->setTimerKind(HELLO_TIMER);
            timerMsg->setIsType(iface->circuitType);
            timerMsg->setInterfaceIndex(k);
            this->schedule(timerMsg);

        }
    }
}
void ISIS::initialize ( int  stage) [protected, virtual]

Initialization function called at the start of simulation. This method provides initial parsing of XML config file and configuration of whole module including network interfaces. NED address is validated and after it's loaded. Initial timers for hello and LSP packets are also set.

See also:
insertIft(InterfaceEntry *entry, cXMLElement *intElement)
parseNetAddr()
Parameters:
stagedefines stage(step) of global initialization

Definition at line 200 of file ISIS.cc.

                               {
    //interface init at stage 2
    if (stage == 3) {

        deviceType = par("deviceType");
        deviceId = par("deviceId");
        configFile = par("configFile");

        ift = AnsaInterfaceTableAccess().get();
        if (ift == NULL) {
            throw cRuntimeError("AnsaInterfaceTable not found");
        }

        cXMLElement *device = xmlParser::GetDevice(deviceType, deviceId,
                configFile);
        if (device == NULL) {
            EV << "deviceId " << deviceId
                      << ": ISIS is not enabled on this device\n";
            return;
        }

        //load IS-IS routing info from config file
        cXMLElement *isisRouting = xmlParser::GetIsisRouting(device);
        if (isisRouting == NULL) {
            EV << "deviceId " << deviceId
                      << ": ISIS is not enabled on this device\n";
            return;
        }
        //TODO: multiple NETs for migrating purposes (merging, splitting areas)
        cXMLElement *net = isisRouting->getFirstChildWithTag("NET");
        if (net == NULL) {
            EV << "deviceId " << deviceId
                      << ": Net address wasn't specified in IS-IS routing\n";
            return;
        }

        netAddr = net->getNodeValue();
        if (netAddr == NULL || strcmp("", netAddr) == 0) {
            EV << "deviceId " << deviceId
                      << ": Net address wasn't specified in IS-IS routing\n";
            return;
        } else {
            if (!parseNetAddr()) {
                EV << "deviceId " << deviceId
                          << ": Invalid net address format\n";
                return;
            } else {
                EV << "deviceId " << deviceId << ": Net address set to: "
                          << netAddr << "\n";
            }
        }

        //set router IS type {L1 | L2 | L1L2 (default)}
        cXMLElement *routertype = isisRouting->getFirstChildWithTag("IS-Type");
        if (routertype == NULL) {
            this->isType = L1L2_TYPE;
        } else {
            const char* routerTypeValue = routertype->getNodeValue();
            if (routerTypeValue == NULL) {
                this->isType = L1L2_TYPE;
            } else {
                if (strcmp(routerTypeValue, "level-1") == 0) {
                    this->isType = L1_TYPE;
                } else {
                    if (strcmp(routerTypeValue, "level-2") == 0) {
                        this->isType = L2_TYPE;
                    } else {
                        this->isType = L1L2_TYPE;
                    }
                }
            }
        }

        //set L1 hello interval in seconds
        cXMLElement *L1HelloInt = isisRouting->getFirstChildWithTag(
                "L1-Hello-Interval");
        if (L1HelloInt == NULL || L1HelloInt->getNodeValue() == NULL) {
            this->L1HelloInterval = ISIS_HELLO_INTERVAL;
        } else {
            this->L1HelloInterval = atoi(L1HelloInt->getNodeValue());
        }

        //set L1 hello multiplier
        cXMLElement *L1HelloMult = isisRouting->getFirstChildWithTag(
                "L1-Hello-Multiplier");
        if (L1HelloMult == NULL || L1HelloMult->getNodeValue() == NULL) {
            this->L1HelloMultiplier = ISIS_HELLO_MULTIPLIER;
        } else {
            this->L1HelloMultiplier = atoi(L1HelloMult->getNodeValue());
        }

        //set L2 hello interval in seconds
        cXMLElement *L2HelloInt = isisRouting->getFirstChildWithTag(
                "L2-Hello-Interval");
        if (L2HelloInt == NULL || L2HelloInt->getNodeValue() == NULL) {
            this->L2HelloInterval = ISIS_HELLO_INTERVAL;
        } else {
            this->L2HelloInterval = atoi(L2HelloInt->getNodeValue());
        }

        //set L2 hello multiplier
        cXMLElement *L2HelloMult = isisRouting->getFirstChildWithTag(
                "L2-Hello-Multiplier");
        if (L2HelloMult == NULL || L2HelloMult->getNodeValue() == NULL) {
            this->L2HelloMultiplier = ISIS_HELLO_MULTIPLIER;
        } else {
            this->L2HelloMultiplier = atoi(L2HelloMult->getNodeValue());
        }

        //set lspInterval
        cXMLElement *cxlspInt = isisRouting->getFirstChildWithTag("LSP-Interval");
        if (cxlspInt == NULL || cxlspInt->getNodeValue() == NULL)
        {
            this->lspInterval = ISIS_LSP_INTERVAL;
        }
        else
        {
            this->lspInterval = atoi(cxlspInt->getNodeValue());
        }

        //set lspRefreshInterval
        cXMLElement *cxlspRefInt = isisRouting->getFirstChildWithTag("LSP-Refresh-Interval");
        if (cxlspRefInt == NULL || cxlspRefInt->getNodeValue() == NULL)
        {
            this->lspRefreshInterval = ISIS_LSP_REFRESH_INTERVAL;
        }
        else
        {
            this->lspRefreshInterval = atoi(cxlspRefInt->getNodeValue());
        }

        //set lspMaxLifetime
        cXMLElement *cxlspMaxLife = isisRouting->getFirstChildWithTag("LSP-Max-Lifetime");
        if (cxlspMaxLife == NULL || cxlspMaxLife->getNodeValue() == NULL)
        {
            this->lspMaxLifetime = ISIS_LSP_MAX_LIFETIME;
        }
        else
        {
            this->lspMaxLifetime = atoi(cxlspMaxLife->getNodeValue());
        }

        //set L1LspGenInterval (CISCO's
        cXMLElement *cxL1lspGenInt = isisRouting->getFirstChildWithTag("L1-LSP-Gen-Interval");
        if (cxL1lspGenInt == NULL || cxL1lspGenInt->getNodeValue() == NULL)
        {
            this->L1LspGenInterval = ISIS_LSP_GEN_INTERVAL;
        }
        else
        {
            this->L1LspGenInterval = atoi(cxL1lspGenInt->getNodeValue());
        }

        //set L2LspGenInterval
        cXMLElement *cxL2lspGenInt = isisRouting->getFirstChildWithTag("L2-LSP-Gen-Interval");
        if (cxL2lspGenInt == NULL || cxL2lspGenInt->getNodeValue() == NULL)
        {
            this->L2LspGenInterval = ISIS_LSP_GEN_INTERVAL;
        }
        else
        {
            this->L2LspGenInterval = atoi(cxL2lspGenInt->getNodeValue());
        }

        //set L1LspSendInterval
        cXMLElement *cxL1lspSendInt = isisRouting->getFirstChildWithTag("L1-LSP-Send-Interval");
        if (cxL1lspSendInt == NULL || cxL1lspSendInt->getNodeValue() == NULL)
        {
            this->L1LspSendInterval = ISIS_LSP_SEND_INTERVAL;
        }
        else
        {
            this->L1LspSendInterval = atoi(cxL1lspSendInt->getNodeValue());
        }

        //set L2LspSendInterval
        cXMLElement *cxL2lspSendInt = isisRouting->getFirstChildWithTag("L2-LSP-Send-Interval");
        if (cxL2lspSendInt == NULL || cxL2lspSendInt->getNodeValue() == NULL)
        {
            this->L2LspSendInterval = ISIS_LSP_SEND_INTERVAL;
        }
        else
        {
            this->L2LspSendInterval = atoi(cxL2lspSendInt->getNodeValue());
        }

        //set L1LspInitWait
        cXMLElement *cxL1lspInitWait = isisRouting->getFirstChildWithTag("L1-LSP-Init-Wait");
        if (cxL1lspInitWait == NULL || cxL1lspInitWait->getNodeValue() == NULL)
        {
            this->L1LspInitWait = ISIS_LSP_INIT_WAIT;
        }
        else
        {
            this->L1LspInitWait = atoi(cxL1lspInitWait->getNodeValue());
        }
        //set L2LspInitWait
        cXMLElement *cxL2lspInitWait = isisRouting->getFirstChildWithTag("L2-LSP-Init-Wait");
        if (cxL2lspInitWait == NULL || cxL2lspInitWait->getNodeValue() == NULL)
        {
            this->L2LspInitWait = ISIS_LSP_INIT_WAIT;
        }
        else
        {
            this->L2LspInitWait = atoi(cxL2lspInitWait->getNodeValue());
        }

        //set L1CsnpInterval
        cXMLElement *cxL1CsnpInt = isisRouting->getFirstChildWithTag("L1-CSNP-Interval");
        if (cxL1CsnpInt == NULL || cxL1CsnpInt->getNodeValue() == NULL)
        {
            this->L1CsnpInterval = ISIS_CSNP_INTERVAL;
        }
        else
        {
            this->L1CsnpInterval = atoi(cxL1CsnpInt->getNodeValue());
        }

        //set L2PsnpInterval
        cXMLElement *cxL2CsnpInt = isisRouting->getFirstChildWithTag("L2-CSNP-Interval");
        if (cxL2CsnpInt == NULL || cxL2CsnpInt->getNodeValue() == NULL)
        {
            this->L2CsnpInterval = ISIS_CSNP_INTERVAL;
        }
        else
        {
            this->L2CsnpInterval = atoi(cxL2CsnpInt->getNodeValue());
        }

        //set L1PsnpInterval
        cXMLElement *cxL1PsnpInt = isisRouting->getFirstChildWithTag("L1-PSNP-Interval");
        if (cxL1PsnpInt == NULL || cxL1PsnpInt->getNodeValue() == NULL)
        {
            this->L1PsnpInterval = ISIS_CSNP_INTERVAL;
        }
        else
        {
            this->L1PsnpInterval = atoi(cxL1PsnpInt->getNodeValue());
        }

        //set L2PsnpInterval
        cXMLElement *cxL2PsnpInt = isisRouting->getFirstChildWithTag("L2-PSNP-Interval");
        if (cxL2PsnpInt == NULL || cxL2PsnpInt->getNodeValue() == NULL)
        {
            this->L2PsnpInterval = ISIS_CSNP_INTERVAL;
        }
        else
        {
            this->L2PsnpInterval = atoi(cxL2PsnpInt->getNodeValue());
        }


        cXMLElement *interfaces = device->getFirstChildWithTag("Interfaces");
        if (interfaces == NULL) {
            EV
                      << "deviceId "
                      << deviceId
                      << ": <Interfaces></Interfaces> tag is missing in configuration file: \""
                      << configFile << "\"\n";
            return;
        }

        // add all interfaces to ISISIft vector containing additional information
        InterfaceEntry *entryIFT = new InterfaceEntry();
        for (int i = 0; i < ift->getNumInterfaces(); i++) {
            entryIFT = ift->getInterface(i);
            //EV << entryIFT->getNetworkLayerGateIndex() << " " << entryIFT->getName() << " " << entryIFT->getFullName() << "\n";
            insertIft(
                    entryIFT,
                    interfaces->getFirstChildWithAttribute("Interface", "name",
                            entryIFT->getName()));
        }

        //TODO passive-interface


        //create SRMQueue for each interface (even though it would be used only for broadcast interfaces)
        for(std::vector<ISISinterface>::iterator it = this->ISISIft.begin(); it != this->ISISIft.end(); ++it){
            this->L1SRMBQueue->push_back(new std::vector<FlagRecord *>);
        }

        for(std::vector<ISISinterface>::iterator it = this->ISISIft.begin(); it != this->ISISIft.end(); ++it){
            this->L1SRMPTPQueue->push_back(new std::vector<FlagRecord *>);
        }

        //SSNflags
        for(std::vector<ISISinterface>::iterator it = this->ISISIft.begin(); it != this->ISISIft.end(); ++it){
            this->L1SSNBQueue->push_back(new std::vector<FlagRecord *>);
        }

        for(std::vector<ISISinterface>::iterator it = this->ISISIft.begin(); it != this->ISISIft.end(); ++it){
            this->L1SSNPTPQueue->push_back(new std::vector<FlagRecord *>);
        }


        //create SRMQueue for each interface (even though it would be used only for broadcast interfaces)
        for(std::vector<ISISinterface>::iterator it = this->ISISIft.begin(); it != this->ISISIft.end(); ++it){
            this->L2SRMBQueue->push_back(new std::vector<FlagRecord *>);
        }

        for(std::vector<ISISinterface>::iterator it = this->ISISIft.begin(); it != this->ISISIft.end(); ++it){
            this->L2SRMPTPQueue->push_back(new std::vector<FlagRecord *>);
        }

        //SSNflags
        for(std::vector<ISISinterface>::iterator it = this->ISISIft.begin(); it != this->ISISIft.end(); ++it){
            this->L2SSNBQueue->push_back(new std::vector<FlagRecord *>);
        }

        for(std::vector<ISISinterface>::iterator it = this->ISISIft.begin(); it != this->ISISIft.end(); ++it){
            this->L2SSNPTPQueue->push_back(new std::vector<FlagRecord *>);
        }

        //TODO
        this->L1SPFFullInterval = ISIS_SPF_FULL_INTERVAL;
        this->L2SPFFullInterval = ISIS_SPF_FULL_INTERVAL;


    }else if(stage == 4){
        this->initISIS();
        //        ISISTimer *timerMsg = new ISISTimer("ISIS Start", ISIS_START);
        //        this->schedule(timerMsg);
    }

}
void ISIS::initISIS ( ) [private]

Initiate scheduling timers.

Definition at line 753 of file ISIS.cc.

Referenced by handleMessage(), and initialize().

{
    this->initHello();
    this->initGenerate();
    this->initRefresh(); //this could be called after at least one adjcency becomes UP
    this->initPeriodicSend();
    this->initCsnp(); //this could be called within initRefresh();
    this->initPsnp(); //see above
    this->initSPF();

}
void ISIS::initPeriodicSend ( ) [private]

Definition at line 860 of file ISIS.cc.

Referenced by initISIS().

{
    ISISTimer *timerMsg;

    if (this->isType == L1L2_TYPE)
    {
        timerMsg = new ISISTimer("Periodic send");
        timerMsg->setTimerKind(PERIODIC_SEND);
        timerMsg->setIsType(L1_TYPE);
        this->schedule(timerMsg);

        timerMsg = new ISISTimer("Periodic send");
        timerMsg->setTimerKind(PERIODIC_SEND);
        timerMsg->setIsType(L2_TYPE);
        this->schedule(timerMsg);
    }
    else
    {
        timerMsg = new ISISTimer("Periodic send");
        timerMsg->setTimerKind(PERIODIC_SEND);
        timerMsg->setIsType(this->isType);
        this->schedule(timerMsg);
    }
}
void ISIS::initPsnp ( ) [private]

Definition at line 933 of file ISIS.cc.

Referenced by initISIS().

{

    ISISTimer *timerMsg;
    ISISinterface *iface;
    for (unsigned int k = 0; k < this->ISISIft.size(); k++)
    {
        iface = &(this->ISISIft.at(k));

        //don't schedule sending PSNP on passive or not ISIS-enabled interface
        if (!iface->ISISenabled || iface->passive)
        {
            continue;
        }

        if (iface->network && iface->circuitType == L1L2_TYPE)
        {
            timerMsg = new ISISTimer("PSNP L1");
            timerMsg->setTimerKind(PSNP_TIMER);
            timerMsg->setIsType(L1_TYPE);
            timerMsg->setInterfaceIndex(k);
            this->schedule(timerMsg);

            timerMsg = new ISISTimer("PSNP L2");
            timerMsg->setTimerKind(PSNP_TIMER);
            timerMsg->setIsType(L2_TYPE);
            timerMsg->setInterfaceIndex(k);
            this->schedule(timerMsg);

        }
        else
        {
            timerMsg = new ISISTimer("PSNP");
            timerMsg->setTimerKind(PSNP_TIMER);
            timerMsg->setIsType(iface->circuitType);
            timerMsg->setInterfaceIndex(k);
            this->schedule(timerMsg);

        }
    }
}
void ISIS::initRefresh ( ) [private]

Definition at line 845 of file ISIS.cc.

Referenced by initISIS().

{
    ISISTimer *timerMsg;

    timerMsg = new ISISTimer("Refresh LSPs timer");
    timerMsg->setTimerKind(LSP_REFRESH);
    timerMsg->setIsType(this->isType);
    this->schedule(timerMsg);
    EV << "ISIS: initRefresh()" << endl;

}
void ISIS::initSPF ( ) [private]

Definition at line 978 of file ISIS.cc.

Referenced by initISIS().

{
    ISISTimer *timerMsg;

    if (this->isType == L1L2_TYPE)
    {
        timerMsg = new ISISTimer("L1 SPF Full");
        timerMsg->setTimerKind(SPF_FULL);
        timerMsg->setIsType(L1_TYPE);
        this->schedule(timerMsg);

        timerMsg = new ISISTimer("L2 SPF Full");
        timerMsg->setTimerKind(SPF_FULL);
        timerMsg->setIsType(L2_TYPE);
        this->schedule(timerMsg);
    }
    else
    {
        timerMsg = new ISISTimer("SPF Full");
        timerMsg->setTimerKind(SPF_FULL);
        timerMsg->setIsType(this->isType);
        this->schedule(timerMsg);
    }
}
void ISIS::insertIft ( InterfaceEntry entry,
cXMLElement *  intElement 
) [private]

Set initial parameters of network interfaces.

Parameters:
entryPointer to interface record in interfaceTable
intElementXML element of current interface in XML config file

Definition at line 532 of file ISIS.cc.

Referenced by initialize().

{

    if(intElement == NULL){
        return;
    }
    ISISinterface newIftEntry;
    newIftEntry.intID = entry->getInterfaceId();

    newIftEntry.gateIndex = entry->getNetworkLayerGateIndex();
    EV <<"deviceId: " << this->deviceId << "ISIS: adding interface, gateIndex: " <<newIftEntry.gateIndex <<endl;

    //set interface priority
    newIftEntry.priority = ISIS_DIS_PRIORITY;  //default value

    /* Interface is NOT enabled by default. If ANY IS-IS related property is configured on interface then it's enabled. */
    newIftEntry.ISISenabled = false;

    cXMLElement *priority = intElement->getFirstChildWithTag("ISIS-Priority");
    if (priority != NULL && priority->getNodeValue() != NULL)
    {
        newIftEntry.priority = (unsigned char) atoi(priority->getNodeValue());
        newIftEntry.ISISenabled = true;
    }


    //set network type (point-to-point vs. broadcast)

    newIftEntry.network = true; //default value

    cXMLElement *network = intElement->getFirstChildWithTag("ISIS-Network");
    if (network != NULL && network->getNodeValue() != NULL)
    {
        if (!strcmp(network->getNodeValue(), "point-to-point"))
        {
            newIftEntry.network = false;
            EV << "Interface network type is point-to-point " << network->getNodeValue() << endl;
        }
        else if (!strcmp(network->getNodeValue(), "broadcast"))
        {
            EV << "Interface network type is broadcast " << network->getNodeValue() << endl;
        }
        else
        {
            EV << "ERORR: Unrecognized interface's network type: " << network->getNodeValue() << endl;

        }
        newIftEntry.ISISenabled = true;

    }



    //set interface metric

    newIftEntry.metric = ISIS_METRIC;    //default value

        cXMLElement *metric = intElement->getFirstChildWithTag("ISIS-Metric");
        if(metric != NULL && metric->getNodeValue() != NULL)
        {
            newIftEntry.metric = (unsigned char) atoi(metric->getNodeValue());
            newIftEntry.ISISenabled = true;
        }




    //set interface type according to global router configuration
    switch(this->isType)
    {
        case(L1_TYPE):
                 newIftEntry.circuitType = L1_TYPE;
                 break;
        case(L2_TYPE):
                 newIftEntry.circuitType = L2_TYPE;
                 break;
        //if router is type is equal L1L2, then interface configuration sets the type
        default: {

            newIftEntry.circuitType = L1L2_TYPE;

            cXMLElement *circuitType = intElement->getFirstChildWithTag("ISIS-Circuit-Type");
            if (circuitType != NULL && circuitType->getNodeValue() != NULL)
            {
                if (strcmp(circuitType->getNodeValue(), "L2") == 0){
                    newIftEntry.circuitType = L2_TYPE;
                }
                else
                {
                    if (strcmp(circuitType->getNodeValue(), "L1") == 0)
                        newIftEntry.circuitType = L1_TYPE;
                }
                newIftEntry.ISISenabled = true;
            }
            else
            {
                newIftEntry.circuitType = L1L2_TYPE;
            }

            break;
        }
    }

    //set L1 hello interval in seconds
    cXMLElement *L1HelloInt = intElement->getFirstChildWithTag(
            "ISIS-L1-Hello-Interval");
    if (L1HelloInt == NULL || L1HelloInt->getNodeValue() == NULL) {
        newIftEntry.L1HelloInterval = this->L1HelloInterval;
    } else {
        newIftEntry.L1HelloInterval = atoi(L1HelloInt->getNodeValue());
    }

    //set L1 hello multiplier
    cXMLElement *L1HelloMult = intElement->getFirstChildWithTag(
            "ISIS-L1-Hello-Multiplier");
    if (L1HelloMult == NULL || L1HelloMult->getNodeValue() == NULL) {
        newIftEntry.L1HelloMultiplier = this->L1HelloMultiplier;
    } else {
        newIftEntry.L1HelloMultiplier = atoi(L1HelloMult->getNodeValue());
    }

    //set L2 hello interval in seconds
    cXMLElement *L2HelloInt = intElement->getFirstChildWithTag(
            "ISIS-L2-Hello-Interval");
    if (L2HelloInt == NULL || L2HelloInt->getNodeValue() == NULL) {
        newIftEntry.L2HelloInterval = this->L2HelloInterval;
    } else {
        newIftEntry.L2HelloInterval = atoi(L2HelloInt->getNodeValue());
    }

    //set L2 hello multiplier
    cXMLElement *L2HelloMult = intElement->getFirstChildWithTag(
            "ISIS-L2-Hello-Multiplier");
    if (L2HelloMult == NULL || L2HelloMult->getNodeValue() == NULL) {
        newIftEntry.L2HelloMultiplier = this->L2HelloMultiplier;
    } else {
        newIftEntry.L2HelloMultiplier = atoi(L2HelloMult->getNodeValue());
    }

    //set lspInterval
    cXMLElement *cxlspInt = intElement->getFirstChildWithTag("ISIS-LSP-Interval");
    if (cxlspInt == NULL || cxlspInt->getNodeValue() == NULL)
    {
        newIftEntry.lspInterval = ISIS_LSP_INTERVAL;
    }
    else
    {
        newIftEntry.lspInterval = atoi(cxlspInt->getNodeValue());
    }

    //set L1CsnpInterval
    cXMLElement *cxL1CsnpInt = intElement->getFirstChildWithTag("ISIS-L1-CSNP-Interval");
    if (cxL1CsnpInt == NULL || cxL1CsnpInt->getNodeValue() == NULL)
    {
        newIftEntry.L1CsnpInterval = ISIS_CSNP_INTERVAL;
    }
    else
    {
        newIftEntry.L1CsnpInterval = atoi(cxL1CsnpInt->getNodeValue());
    }

    //set L2CsnpInterval
    cXMLElement *cxL2CsnpInt = intElement->getFirstChildWithTag("ISIS-L2-CSNP-Interval");
    if (cxL2CsnpInt == NULL || cxL2CsnpInt->getNodeValue() == NULL)
    {
        newIftEntry.L2CsnpInterval = ISIS_CSNP_INTERVAL;
    }
    else
    {
        newIftEntry.L2CsnpInterval = atoi(cxL2CsnpInt->getNodeValue());
    }

    //set L1PsnpInterval
    cXMLElement *cxL1PsnpInt = intElement->getFirstChildWithTag("ISIS-L1-PSNP-Interval");
    if (cxL1PsnpInt == NULL || cxL1PsnpInt->getNodeValue() == NULL)
    {
        newIftEntry.L1PsnpInterval = ISIS_CSNP_INTERVAL;
    }
    else
    {
        newIftEntry.L1PsnpInterval = atoi(cxL1PsnpInt->getNodeValue());
    }

    //set L2PsnpInterval
    cXMLElement *cxL2PsnpInt = intElement->getFirstChildWithTag("ISIS-L2-PSNP-Interval");
    if (cxL2PsnpInt == NULL || cxL2PsnpInt->getNodeValue() == NULL)
    {
        newIftEntry.L2PsnpInterval = ISIS_CSNP_INTERVAL;
    }
    else
    {
        newIftEntry.L2PsnpInterval = atoi(cxL2PsnpInt->getNodeValue());
    }


    //TODO  priority is not needed for point-to-point
    //set priority of current DIS = me at start
    newIftEntry.L1DISpriority = newIftEntry.priority;
    newIftEntry.L2DISpriority = newIftEntry.priority;

    //set initial designated IS as himself
    this->copyArrayContent((unsigned char*)this->sysId, newIftEntry.L1DIS, ISIS_SYSTEM_ID, 0, 0);
    //set LAN identifier; -99 is because, OMNeT starts numbering interfaces from 100 -> interfaceID 100 means LAN ID 0; and we want to start numbering from 1
    //newIftEntry.L1DIS[6] = entry->getInterfaceId() - 99;
    newIftEntry.L1DIS[ISIS_SYSTEM_ID] = newIftEntry.gateIndex + 1;
    //do the same for L2 DIS
    this->copyArrayContent((unsigned char*)this->sysId, newIftEntry.L2DIS, ISIS_SYSTEM_ID, 0, 0);
    //newIftEntry.L2DIS[6] = entry->getInterfaceId() - 99;
    newIftEntry.L2DIS[ISIS_SYSTEM_ID] = newIftEntry.gateIndex + 1;

    newIftEntry.passive = false;
    newIftEntry.entry = entry;
    this->ISISIft.push_back(newIftEntry);
}
LSPRecord * ISIS::installLSP ( ISISLSPPacket lsp,
short  circuitType 
) [private]

Definition at line 6218 of file ISIS.cc.

Referenced by generateLSP(), handleL1Csnp(), handleL1Lsp(), and handleL1Psnp().

{

    LSPRecord * tmpLSPRecord = new LSPRecord;
    std::vector<LSPRecord*> * lspDb = this->getLSPDb(circuitType);

    tmpLSPRecord->LSP = lsp;
    //TODO
    /* if lsp is my LSP
     *   then set all flags
     * else
     *   set all BUT the received circuts
     */

    if(lsp->getArrivalGate() !=NULL){
        int gateIndex = lsp->getArrivalGate()->getIndex();
        /* 7.3.15.1 e) 1) ii. */
        this->setSRMflagsBut(tmpLSPRecord, gateIndex, circuitType);
        /*TODO 7.3.15.1 e) 1) iii. -> redundant?? */
        //this->clearSRMflag(tmpLSPRecord, lsp->getArrivalGate()->getIndex(), circuitType);

        /* change from specification */
        /* iv. and v. are "switched */
        /* 7.3.15.1 e) 1) v. */
        this->clearSSNflags(tmpLSPRecord, circuitType);

        if (!this->ISISIft.at(gateIndex).network)
        {
            /* 7.3.15.1 e) 1) iv. */
            this->setSSNflag(tmpLSPRecord, gateIndex, circuitType);
        }

    }else{
        /* Never set SRM flag for lsp with seqNum == 0 */
        if(lsp->getSeqNumber() > 0){
        /* installLSP is called from genLSP */
            this->setSRMflags(tmpLSPRecord, circuitType);
        }
        //TODO what about SSNflags?
        //this->clearSSNflags(tmpLSPRecord, circuitType);
    }


    tmpLSPRecord->deadTimer = new ISISTimer("LSP Dead Timer");
    tmpLSPRecord->deadTimer->setTimerKind(LSP_DEAD);
    tmpLSPRecord->deadTimer->setIsType(circuitType);
    for (unsigned int i = 0; i < tmpLSPRecord->deadTimer->getLSPidArraySize(); i++)
    {
        tmpLSPRecord->deadTimer->setLSPid(i, tmpLSPRecord->LSP->getLspID(i));
    }

    tmpLSPRecord->simLifetime = simTime().dbl() + tmpLSPRecord->LSP->getRemLifeTime();

    this->schedule(tmpLSPRecord->deadTimer, lsp->getRemLifeTime());

    lspDb->push_back(tmpLSPRecord);

    return lspDb->back();
}
bool ISIS::isAdjBySystemID ( unsigned char *  systemID,
short  circuitType 
) [private]

Definition at line 2440 of file ISIS.cc.

{
    if (ciruitType == L1_TYPE)
    {
        //walk through adjacency table and look for existing neighbours
        for (std::vector<ISISadj>::iterator it = this->adjL1Table.begin(); it != adjL1Table.end(); ++it)
        {
            if (compareArrays(systemID, (*it).sysID, ISIS_SYSTEM_ID))
            {
                return true;
            }

        }
    }else if(ciruitType == L2_TYPE)
    {
        //walk through adjacency table and look for existing neighbours
        for (std::vector<ISISadj>::iterator it = this->adjL2Table.begin(); it != adjL2Table.end(); ++it)
        {
            if (compareArrays(systemID, (*it).sysID, ISIS_SYSTEM_ID))
            {
                return true;
            }

        }
    }

    return false;
}
bool ISIS::isAdjUp ( short  circuitType) [private]

Definition at line 7381 of file ISIS.cc.

Referenced by genLSP(), handleL1Csnp(), handleL1Lsp(), and handleL1Psnp().

{
    std::vector<ISISadj>* adjTable = this->getAdjTab(circuitType);

    for (std::vector<ISISadj>::iterator it = adjTable->begin(); it != adjTable->end(); ++it)
    {
        if ((*it).state)
        {
            return true;
        }
    }
    return false;
}
bool ISIS::isAdjUp ( ISISMessage msg,
short  circuitType 
) [private]

Definition at line 7423 of file ISIS.cc.

{
    /* Pretty messy code, please clean up */
    std::vector<ISISadj> *adjTable = this->getAdjTab(circuitType);
    int gateIndex = msg->getArrivalGate()->getIndex();

    //TODO for truly point-to-point link there would not be MAC address
    Ieee802Ctrl *ctrl = check_and_cast<Ieee802Ctrl *>(msg->getControlInfo());
    MACAddress tmpMac = ctrl->getSrc();
    unsigned char * systemID;

    systemID = this->getSysID(msg);
    for (std::vector<ISISadj>::iterator it = adjTable->begin(); it != adjTable->end(); ++it)
    {
        //System-ID match?
        /* Exception for LSP is here because to satisfy  7.3.15.1 a) 6) is enough to check SNPA and interface e.g gateIndex */
        if (compareArrays(systemID, (*it).sysID, ISIS_SYSTEM_ID) || msg->getType() == L1_LSP || msg->getType() == L2_LSP)
        {
            //MAC Address and gateIndex
            //we need to check source (tmpMac) and destination interface thru we received this hello
            if (tmpMac.compareTo((*it).mac) == 0 && gateIndex == (*it).gateIndex && (*it).state)
            {

                delete systemID;
                return true;

            }
        }
    }
    delete systemID;

    return false;
}
bool ISIS::isAreaIDOK ( TLV_t areaAddressTLV,
unsigned char *  compare = NULL 
) [private]

Definition at line 7101 of file ISIS.cc.

Referenced by getAdj(), handleL1HelloMsg(), and handlePTPHelloMsg().

{
    if(compare == NULL){
        compare = (unsigned char *) this->areaId;
    }

    if(areaAddressTLV->length == 0){
        return false;
    }
    for(unsigned int i = 0; i < areaAddressTLV->length / ISIS_AREA_ID; i++){
        if(this->compareArrays(compare, &areaAddressTLV->value[i * ISIS_AREA_ID], ISIS_AREA_ID)){
            //if one address match return false
            return true;
        }

    }
    //not even single areaID match, so return false
    return false;
}
bool ISIS::isCon ( ISISCons_t cons,
unsigned char *  from,
unsigned char *  to 
) [private]

Definition at line 7836 of file ISIS.cc.

Referenced by twoWayCheck().

                                                                        {

    for (ISISCons_t::iterator it = cons->begin(); it != cons->end(); ++it)
    {
        if(this->compareArrays((*it)->from, from, ISIS_SYSTEM_ID + 2) && this->compareArrays((*it)->to, to, ISIS_SYSTEM_ID + 2)){
            return true;
        }
    }
    return false;
}
bool ISIS::isMessageOK ( ISISMessage inMsg) [private]

Definition at line 7080 of file ISIS.cc.

Referenced by handleMessage().

{

    if (inMsg->getIdLength() != ISIS_SYSTEM_ID && inMsg->getIdLength() != 0)
    {
        return false;
    }

    if (inMsg->getMaxAreas() != ISIS_MAX_AREAS && inMsg->getMaxAreas() != 0)
    {
        return false;
    }

    return true;
}
bool ISIS::isUp ( int  gateIndex,
short  circuitType 
) [private]

Definition at line 7402 of file ISIS.cc.

Referenced by genLSP(), setSRMflag(), and setSSNflag().

{
    std::vector<ISISadj> *adjTable;

    adjTable = this->getAdjTab(circuitType);
    for (std::vector<ISISadj>::iterator it = adjTable->begin(); it != adjTable->end(); ++it)
    {
        if ((*it).gateIndex == gateIndex && (*it).state)
        {
            return true;
        }
    }
    return false;

}
void ISIS::moveToPath ( ISISPath path) [private]
void ISIS::moveToTent ( ISISCons_t initial,
unsigned char *  from,
uint32_t  metric,
ISISPaths_t ISISTent 
) [private]

Definition at line 7661 of file ISIS.cc.

Referenced by bestToPath().

                                                                                                     {

    ISISPath *tmpPath;
    ISISCons_t *cons = this->getCons(initial, from);
/*       if(cons->empty()){
           EV <<"ISIS: Error during SPF. Didn't find my own LSP"<<endl;
           //TODO clean
//           delete cons;
  //         return;
       }*/


       //add my connections as a starting point
       for(ISISCons_t::iterator it = cons->begin(); it != cons->end(); ++it){
           if ((tmpPath = this->getPath(ISISTent, (*it)->to)) == NULL)
           {
               //path to this destination doesn't exist, co create new
               tmpPath = new ISISPath;
               tmpPath->to = new unsigned char[ISIS_SYSTEM_ID + 2];
               this->copyArrayContent((*it)->to, tmpPath->to, ISIS_SYSTEM_ID + 2, 0, 0);
               tmpPath->metric = (*it)->metric + metric;

               ISISNeighbour *neighbour = new ISISNeighbour;

               neighbour->id = new unsigned char[ISIS_SYSTEM_ID + 2];
               if(this->compareArrays((*it)->from,(unsigned char *) this->sysId, ISIS_SYSTEM_ID)){
                   this->copyArrayContent((*it)->to, neighbour->id, ISIS_SYSTEM_ID + 2, 0, 0);
               }else{
                   this->copyArrayContent((*it)->from, neighbour->id, ISIS_SYSTEM_ID + 2, 0, 0);
               }
               neighbour->type = false; //not a leaf
               tmpPath->from.push_back(neighbour);

               ISISTent->push_back(tmpPath);
           }
           else
           {
               if(tmpPath->metric >= (*it)->metric + metric){
                   if(tmpPath->metric > (*it)->metric + metric){
                       //we got better metric so clear "from" neighbours
                       tmpPath->from.clear();
                   }
                   //append
                   tmpPath->metric = (*it)->metric + metric;
                   ISISNeighbour *neighbour = new ISISNeighbour;
                   neighbour->id = new unsigned char[ISIS_SYSTEM_ID + 2];
                   this->copyArrayContent((*it)->from, neighbour->id, ISIS_SYSTEM_ID + 2, 0, 0);
                   neighbour->type = false; //not a leaf
                   tmpPath->from.push_back(neighbour);

               }

           }

       }
}
virtual int ISIS::numInitStages ( ) const [inline, protected, virtual]

Definition at line 316 of file ISIS.h.

        {
            return 5;
        }
bool ISIS::parseNetAddr ( ) [private]

Parse NET address stored in this->netAddr into areaId, sysId and NSEL. Method is used in initialization.

See also:
initialize(int stage)
Returns:
Return true if NET address loaded from XML file is valid. Otherwise return false.

Definition at line 1761 of file ISIS.cc.

Referenced by initialize().

{
    std::string net = netAddr;
    unsigned int dots = 0;
    size_t found;

    //net address (in this module - not according to standard O:-) MUST have this format:
    //49.0001.1921.6801.2003.00

    found=net.find_first_of(".");
    if(found != 2 || net.length()!=25)
    {
        return false;
    }


    unsigned char *area = new unsigned char[3];
    unsigned char *systemId = new unsigned char[6];
    unsigned char *nsel = new unsigned char[1];

    while (found!=string::npos)
    {

        switch(found){
            case 2:
                dots++;
                area[0] = (unsigned char)(atoi(net.substr(0,2).c_str()));
                EV<<"BEZ ATOI" << net.substr(0,2).c_str() <<endl;
                break;
            case 7:
                dots++;
                area[1] = (unsigned char)(atoi(net.substr(3,2).c_str()));
                area[2] = (unsigned char)(atoi(net.substr(5,2).c_str()));
                break;
            case 12:
                dots++;
                systemId[0] = (unsigned char)(atoi(net.substr(8,2).c_str()));
                systemId[1] = (unsigned char)(atoi(net.substr(10,2).c_str()));
                break;
            case 17:
                dots++;
                systemId[2] = (unsigned char)(atoi(net.substr(13,2).c_str()));
                systemId[3] = (unsigned char)(atoi(net.substr(15,2).c_str()));
                break;
            case 22:
                dots++;
                systemId[4] = (unsigned char)(atoi(net.substr(18,2).c_str()));
                systemId[5] = (unsigned char)(atoi(net.substr(20,2).c_str()));
                break;
            default:
                return false;
                break;

        }

        found=net.find_first_of(".",found+1);
    }

    if(dots!=5)
    {
         return false;
    }

    nsel[0] = (unsigned char)(atoi(net.substr(23,2).c_str()));

    //49.0001.1921.6801.2003.00

    areaId = area;
    EV <<"ISIS: AreaID: "<< areaId[0] <<endl;
    EV <<"ISIS: AreaID: "<< areaId[1] <<endl;
    EV <<"ISIS: AreaID: "<< areaId[2] <<endl;
    sysId = systemId;
    EV <<"ISIS: SystemID: "<< sysId <<endl;
    NSEL = nsel;
    EV <<"ISIS: NSEL: "<< NSEL <<endl;

    return true;
}
void ISIS::periodicSend ( ISISTimer timer,
short  circuitType 
) [private]

Sends LSPs on interfaces with SRMflag every ISIS_LSP_GEN_INTERVAL.

< Index to circuit's SRMQueue

Definition at line 4952 of file ISIS.cc.

Referenced by handleMessage().

{
    /*
     * TODO improvement: don't scan whole database, but instead
     *  create queue "toBeSend" with lspRec* and index to SRMflags vector
     *  and when setting SRMflag (in any method) put a record in mentioned queue
     *  When doing periodicSend we don't have to check whole database (but should
     *   at least in the beginning to check that it works correctly), but just this queue
     *  We could have two queues (for PTP and broadcast).
     *  PTP queue would be simply send out.
     *  Broadcast queue would be subject of random picking.
     *
     */
/*
    std::vector<LSPRecord *> *lspDb = this->getLSPDb(circuitType);
    std::vector<ISISadj> * adjTable = this->getAdjTab(circuitType);
    std::vector<ISISinterface>::iterator itIface = this->ISISIft.begin();
*/

    std::vector<std::vector<FlagRecord*>* > * SRMPTPQueue = getSRMPTPQueue(circuitType);
    std::vector<std::vector<FlagRecord*>* > * SRMBQueue = getSRMBQueue(circuitType);

    //std::cout << "Starting Periodic send for: ";
    //this->printSysId((unsigned char *) this->sysId);
    //std::cout << endl;

    //PTP circuits
    for(std::vector<std::vector<FlagRecord*>* >::iterator it = SRMPTPQueue->begin(); it != SRMPTPQueue->end(); ++it){
       for(std::vector<FlagRecord*>::iterator itRec = (*it)->begin(); itRec != (*it)->end(); ++itRec){

           //std::cout<<"sendLsp to:" << (*itRec)->index <<" : ";
               //this->printLspId(this->getLspID((*itRec)->lspRec->LSP));

               this->sendLSP((*itRec)->lspRec, (*itRec)->index);
               
           //DON'T clear SRMflag for PtP

           /* when the below code is commented:
            * it might be necessary to incorporate retransmit interval and
            * when checking if the SRM flag is not already set.
            * setting the flag multiple times may cause bloating appropriate flag queue.
            */
           //delete (*itRec);
           //itRec = (*it)->erase(itRec); //instead of ++itRec in for()!!!!!!
       }

    }


    //broadcast circuits
    //for each queue(interface) pick one LSP and send it
    for(std::vector<std::vector<FlagRecord*>* >::iterator it = SRMBQueue->begin(); it != SRMBQueue->end(); ++it){
        int queueSize = (*it)->size();
        if(queueSize == 0){
            continue;
        }
        int index = floor(uniform(0, queueSize)); 

        //send random LSP from queue
        //TODO if queue.size() > 10 pick two LSPs (or something like it)
        //TODO maybe? better version would be with this->ISISIft.at((*it)->at(index)->index)
        this->sendLSP((*it)->at(index)->lspRec, (*it)->at(index)->index);

        //clear SRMflag
        this->clearSRMflag((*it)->at(index)->lspRec, (*it)->at(index)->index, circuitType);
/*        (*it)->at(index)->lspRec->SRMflags.at((*it)->at(index)->index);

        delete (*it)->at(index);
        //and remove FlagRecord from queue
        (*it)->erase((*it)->begin() + index);
        */
        queueSize = (*it)->size();
        int a = 5;

    }
    //reschedule PERIODIC_SEND timer
    this->schedule(timer);
}

Print L1 and L2 adjacency tables to EV. This function is currently called every time hello packet is received and processed.

See also:
handleMessage(cMessage* msg)

Definition at line 2786 of file ISIS.cc.

Referenced by handleMessage().

{
    std::sort(this->adjL1Table.begin(), this->adjL1Table.end());
    EV << "L1 adjacency table of IS ";

    //print area id
    for(unsigned int i=0; i<3; i++)
    {
        EV << setfill('0') << setw(2) << dec << (unsigned int)areaId[i];
        if(i % 2 == 0)
            EV << ".";

    }

    //print system id
    for(unsigned int i=0; i<6; i++)
    {
        EV << setfill('0') << setw(2) << dec << (unsigned int)sysId[i];
        if(i % 2 == 1)
            EV << ".";
    }

    //print NSEL
    EV << setfill('0') << setw(2) << dec << (unsigned int) NSEL[0] << "\tNo. of records in Table: " << adjL1Table.size() << endl;

    //print neighbour records
    for(unsigned int j=0; j<adjL1Table.size(); j++)
    {
        EV << "\t";
        //print neighbour system id
        for(unsigned int i=0; i<6; i++)
        {
            EV <<  setfill('0') << setw(2) << dec << (unsigned int)adjL1Table.at(j).sysID[i];
            if(i == 1 || i ==3)
                        EV << ".";
        }
        EV << "\t";


        //print neighbour MAC address
        for(unsigned int i=0; i<6; i++)
        {
            EV <<  setfill('0') << setw(2) << hex << (unsigned int)adjL1Table.at(j).mac.getAddressByte(i);
            if(i <5)
                 EV << ":";
        }
        EV << "\t";


        if(!adjL1Table.at(j).state)
            EV << "Init\n";
        else
            EV << "Up\n";
    }

    EV << "--------------------------------------------------------------------\n";

    EV << "L2 adjacency table of IS ";

        //print area id
        for(unsigned int i=0; i<3; i++)
        {
            EV << setfill('0') << setw(2) << dec << (unsigned int)areaId[i];
            if(i % 2 == 0)
                EV << ".";

        }

        //print system id
        for(unsigned int i=0; i<6; i++)
        {
            EV << setfill('0') << setw(2) << dec << (unsigned int)sysId[i];
            if(i % 2 == 1)
                EV << ".";
        }

        //print NSEL
        EV << setfill('0') << setw(2) << dec << (unsigned int) NSEL[0] << "\tNo. of records in Table: " << adjL2Table.size() << endl;

        //print neighbour records
        for(unsigned int j=0; j<adjL2Table.size(); j++)
        {
            EV << "\t";
            //print neighbour area id and system id
            for(unsigned int i=0; i<3; i++)
            {
                EV << setfill('0') << setw(2) << dec << (unsigned int)adjL2Table.at(j).areaID[i];
                if(i % 2 == 0)
                    EV << ".";

            }


            for(unsigned int i=0; i<6; i++)
            {
                EV <<  setfill('0') << setw(2) << dec << (unsigned int)adjL2Table.at(j).sysID[i];
                if(i == 1 || i ==3)
                            EV << ".";
            }
            EV << "\t";


            //print neighbour MAC address
            for(unsigned int i=0; i<6; i++)
            {
                EV <<  setfill('0') << setw(2) << hex << (unsigned int)adjL2Table.at(j).mac.getAddressByte(i);
                if(i <5)
                     EV << ":";
            }
            EV << "\t";


            if(!adjL2Table.at(j).state)
                EV << "Init\n";
            else
                EV << "Up\n";
        }
}
void ISIS::printLSP ( ISISLSPPacket lsp,
char *  from 
) [private]

Definition at line 3055 of file ISIS.cc.

                                                 {
    std::cout<<"PrintLSP called from: " << from << endl;
    unsigned char * lspId = this->getLspID(lsp);
    std::cout << "Printing LSP: ";
    this->printLspId(lspId);
    std::cout << "Print LSP->test:";
    this->printLspId((unsigned char *)lsp->getTest());
    std::cout << "seqNum: " << lsp->getSeqNumber() <<endl;
    std::cout << "Length of TLVarray: " << lsp->getTLVArraySize()<<endl;
    std::cout << "TLV: " <<endl;
    for(unsigned int i = 0; i < lsp->getTLVArraySize(); i++){
        std::cout<< "Type: "<< (unsigned short) lsp->getTLV(i).type <<endl;
        std::cout<< "Length: "<< (unsigned short) lsp->getTLV(i).length <<endl;
    }


    TLV_t *tmpTlv;
    for (unsigned int k = 0; (tmpTlv = this->getTLVByType(lsp, IS_NEIGHBOURS_LSP, k)) != NULL; k++)
    {
        std::cout <<"Start printing TLV of length: "<< (unsigned int)tmpTlv->length << endl;
        for (unsigned int m = 0; (m + 11) < tmpTlv->length; m += 11)
        {
            std::cout << "LAN-ID:";
            for (unsigned int l = 0; l < 7; l++)
            {
                //1 = virtual flag, m = current neighbour record, 4 is offset in current neigh. record(start LAN-ID)
                std::cout << (unsigned short) tmpTlv->value[1 + m + 4 + l];
                if (l % 2 == 1)
                    std::cout << ".";
            }

            std::cout << "\t metric: " << (unsigned short) tmpTlv->value[1 + m + 0] << endl;
        }
    }
}
void ISIS::printLSPDB ( )

Print content of L1 LSP database to EV.

Definition at line 2911 of file ISIS.cc.

Referenced by handleMessage().

{
    short circuitType = L1_TYPE;
    std::vector<LSPRecord *> *lspDb = this->getLSPDb(circuitType);
    EV << "L1 LSP database of IS ";

    //print area id
    for (unsigned int i = 0; i < 3; i++)
    {
        EV << setfill('0') << setw(2) << dec << (unsigned int) areaId[i];
        if (i % 2 == 0)
            EV << ".";

    }

    //print system id
    for (unsigned int i = 0; i < 6; i++)
    {
        EV << setfill('0') << setw(2) << dec << (unsigned int) sysId[i];
        if (i % 2 == 1)
            EV << ".";
    }

    //print NSEL
    EV
            << setfill('0') << setw(2) << dec << (unsigned int) NSEL[0] << "\tNo. of records in database: "
                    << lspDb->size() << endl;
    unsigned char *lspId;
    std::vector<LSPRecord *>::iterator it = lspDb->begin();
    for (; it != lspDb->end(); ++it)
    {
        EV << "\t";
        //print LSP ID
        for (unsigned int j = 0; j < 8; j++)
        {
            EV << setfill('0') << setw(2) << dec << (unsigned int) (*it)->LSP->getLspID(j);
            if (j == 1 || j == 3 || j == 5)
                EV << ".";
            if (j == 6)
                EV << "-";
        }
        EV << "\t0x";

        //print sequence number
        EV << setfill('0') << setw(8) << hex << (*it)->LSP->getSeqNumber();
        EV<< "\t" << setfill('0') << setw(5) << dec << (*it)->LSP->getRemLifeTime() <<endl;
        //EV <<"SeqNum: " << (*it)->LSP->getSeqNumber()<<endl;

        TLV_t *tmpTlv;

        //print neighbours
        for (unsigned int k = 0; (tmpTlv = this->getTLVByType((*it)->LSP, IS_NEIGHBOURS_LSP, k)) != NULL; k++)
        {
            for (unsigned int m = 1; m + 11 <= tmpTlv->length; m += 11)
            {
                EV << "\t\t";
                for (unsigned int l = 0; l < 7; l++)
                {
                    //1 = virtual flag, m = current neighbour record, 4 is offset in current neigh. record(start LAN-ID)
                    EV << setfill('0') << setw(2) << dec << (unsigned int) tmpTlv->value[m + 4 + l];
                    if (l % 2 == 1)
                        EV << ".";
                }

                EV
                        << "\tmetric: " << setfill('0') << setw(2) << dec
                                << (unsigned int) tmpTlv->value[m + 0] << endl;
            }

        }

    }

    /* EV << "L1 LSP database of IS ";

    //print area id
    for(unsigned int i=0; i<3; i++)
    {
        EV << setfill('0') << setw(2) << dec << (unsigned int)areaId[i];
        if(i % 2 == 0)
            EV << ".";

    }

    //print system id
    for(unsigned int i=0; i<6; i++)
    {
        EV << setfill('0') << setw(2) << dec << (unsigned int)sysId[i];
        if(i % 2 == 1)
            EV << ".";
    }

    //print NSEL
    EV << setfill('0') << setw(2) << dec << (unsigned int) NSEL[0] << "\tNo. of records in database: " << L1LSP.size() << endl;


    for(unsigned int i=0;i<L1LSP.size();i++)
    {
        EV << "\t";
        //print LSP ID
        for(unsigned int j=0; j<8; j++)
        {
            EV <<  setfill('0') << setw(2) << dec << (unsigned int)L1LSP.at(i).LSPid[j];
            if(j == 1 || j == 3 || j == 5)
                        EV << ".";
            if(j==6)
                EV<<"-";
        }
        EV << "\t0x";

        //print sequence number
        EV << setfill('0') << setw(8) << hex << L1LSP.at(i).seq << endl;



        //print neighbours
        for(unsigned int k=0; k<L1LSP.at(i).neighbours.size(); k++)
        {
            EV <<"\t\t";
            for(unsigned int l=0; l<7; l++)
            {
                EV <<  setfill('0') << setw(2) << dec << (unsigned int)L1LSP.at(i).neighbours.at(k).LANid[l];
                if(l % 2 == 1)
                    EV << ".";
            }

            EV << "\tmetric: " << setfill('0') << setw(2) << dec << (unsigned int)L1LSP.at(i).neighbours.at(k).metrics.defaultMetric << endl;


        }

    }


 *
 */

    //TODO print L2 LSP DB
}
void ISIS::printLspId ( unsigned char *  lspId) [private]

Definition at line 3091 of file ISIS.cc.

Referenced by handleL1Csnp(), handleL1Psnp(), and printLSP().

                                         {

    this->printSysId(lspId);
    std::cout << setfill('0') << setw(2) << dec << (unsigned int) lspId[ISIS_SYSTEM_ID] ;
    std::cout << "-";
    std::cout << setfill('0') << setw(2) << dec << (unsigned int) lspId[ISIS_SYSTEM_ID + 1] << endl ;
}
void ISIS::printPaths ( ISISPaths_t paths) [private]

Definition at line 7571 of file ISIS.cc.

Referenced by fullSPF().

                                       {


        std::cout << "Best paths of IS: ";
        //print area id
            for (unsigned int i = 0; i < 3; i++)
            {
                std::cout << setfill('0') << setw(2) << dec << (unsigned int) this->areaId[i];
                if (i % 2 == 0)
                    std::cout << ".";

            }

            //print system id
            for (unsigned int i = 0; i < 6; i++)
            {
                std::cout << setfill('0') << setw(2) << dec << (unsigned int) this->sysId[i];
                if (i % 2 == 1)
                    std::cout << ".";
            }

            //print NSEL
            std::cout
                    << setfill('0') << setw(2) << dec << (unsigned int) this->NSEL[0] << "\tNo. of paths: "
                            << paths->size() << endl;
    for(ISISPaths_t::iterator it = paths->begin(); it != paths->end(); ++it){
        this->printSysId((*it)->to);
        std::cout << setfill('0') << setw(2) << dec <<(unsigned short)(*it)->to[6]<< endl;;
        std::cout <<"\t\t metric: "<< (*it)->metric <<"\t via:"<<endl;;
        for(ISISNeighbours_t::iterator nIt = (*it)->from.begin(); nIt != (*it)->from.end(); ++nIt){
            std::cout<<"\t\t\t\t\t";
            this->printSysId((*nIt)->id);
            std::cout  << setfill('0') << setw(2) << dec <<(unsigned short)(*nIt)->id[6]<< endl;;
        }
    }
}
void ISIS::printSysId ( unsigned char *  sysId) [private]

Definition at line 3099 of file ISIS.cc.

Referenced by handleL1Csnp(), handleL1Psnp(), printLspId(), and printPaths().

                                         {


    //print system id
        for (unsigned int i = 0; i < 6; i++)
        {
            std::cout << setfill('0') << setw(2) << dec << (unsigned int) sysId[i];
            if (i % 2 == 1)
                std::cout << ".";
        }
}
void ISIS::purgeLSP ( unsigned char *  lspId,
short  circuitType 
) [private]

Definition at line 5592 of file ISIS.cc.

Referenced by handleL1Lsp(), handleMessage(), purgeMyLSPs(), and purgeRemainLSP().

                                                          {

    LSPRecord * lspRec;
    if((lspRec = this->getLSPFromDbByID(lspId, circuitType)) != NULL){
        //std::cout<<"purgeLSP seqNum: " << lspRec->LSP->getSeqNumber() <<endl;
        //lspRec->LSP->setSeqNumber(0);
        //TODO do we need to increment seqNum or equal seqNum with remLife == 0 will replace that LSP?
        //lspRec->LSP->setSeqNumber(lspRec->LSP->getSeqNumber() + 1);
        //std::cout<<"purgeLSP seqNum: " << lspRec->LSP->getSeqNumber() <<endl;
        /* 7.3.16.4.  */
        lspRec->LSP->setRemLifeTime(0);
        //delete all TLV from lspRec-LSP and set TLVArraySize = 0
        //TODO check if area address TLV is necessary
        //add only Area Address
/*        for(unsigned int i = 0; i < lspRec->LSP->getTLVArraySize(); i++){
            if(lspRec->LSP->getTLV(i).value != NULL){
                delete lspRec->LSP->getTLV(i).value;
            }
        }*/

        lspRec->LSP->setTLVArraySize(0);
        //if TLV Area Addresses should be present even in purge LSP than add it
        //this->addTLV(lspRec->LSP, AREA_ADDRESS);

        this->setSRMflags(lspRec, circuitType);


        //simLifetime now express the time when the LSP has been purged so after "N" seconds it can be removed completely
        lspRec->simLifetime = simTime().dbl();

        //remove the deadTimer from future events
        cancelEvent(lspRec->deadTimer);
        //change timer type
        lspRec->deadTimer->setTimerKind(LSP_DELETE);
        //and reschedule it again
        this->schedule(lspRec->deadTimer);
    }

}
void ISIS::purgeLSP ( ISISLSPPacket lsp,
short  circuitType 
) [private]

Definition at line 5638 of file ISIS.cc.

                                                        {
    LSPRecord *lspRec;
    int gateIndex = lsp->getArrivalGate()->getIndex();
    //std::vector<LSPRecord *> * lspDb = this->getLSPDb(circuitType);
    unsigned char * lspId = this->getLspID(lsp);

    //if lsp is not in memory
    if((lspRec = this->getLSPFromDbByID(lspId, circuitType)) == NULL){

        //send an ack of the LSP on circuit C
        if(!this->getIfaceByGateIndex(gateIndex)->network){
            /* TODO uncomment warning when sending ack for lsp NOT in db is implemented */
            EV<<"ISIS: Warning: Should send ACK for purged LSP over non-broadcast circuit. (Not yet implemented)."<<endl;
            //explicit ack are only on non-broadcast circuits
            //this->setSSNflag(lspRec, gateIndex, circuitType);
        }
    }else

    {   /*7.3.16.4. b) LSP from S is in the DB */
        if (!this->compareArrays(this->getSysID(lsp), (unsigned char *) this->sysId, ISIS_SYSTEM_ID))
        {
            //if received LSP is newer
            //7.3.16.4 b) 1)
            if (lsp->getSeqNumber() > lspRec->LSP->getSeqNumber()
                    || (lsp->getSeqNumber() == lspRec->LSP->getSeqNumber() && lspRec->LSP->getRemLifeTime() != 0))
            {
                //store the new LSP in DB, overwriting existing LSP
                //replaceLSP
                this->replaceLSP(lsp, lspRec, circuitType);
                //lsp is installed in DB => don't delete it, so early return
                delete lspId;
                return;
            }
            /* 7.3.16.4. b) 2)*/
            else if (lsp->getSeqNumber() == lspRec->LSP->getSeqNumber() && lsp->getRemLifeTime() == 0
                    && lspRec->LSP->getRemLifeTime() == 0)
            {
                /* clear SRMflag for C and
                 * if C is non-broadcast circuit, set SSNflag for C
                 */
                /* 7.3.16.4. b) 2) i.*/
                this->clearSRMflag(lspRec, gateIndex, circuitType);
                if (!this->getIfaceByGateIndex(gateIndex)->network)
                {
                    /* 7.3.16.4. b) 2) ii.*/
                    //explicit ack are only on non-broadcast circuits
                    this->setSSNflag(lspRec, gateIndex, circuitType);
                }

            }
            /* 7.3.16.4. b) 3).*/
            else if (lsp->getSeqNumber() < lspRec->LSP->getSeqNumber())
            {
                /* 7.3.16.4. b) 3) i.*/
                this->setSRMflag(lspRec, gateIndex, circuitType);
                /* 7.3.16.4. b) 3) ii.*/
                this->clearSSNflag(lspRec, gateIndex, circuitType);
            }


        }
        /*7.3.16.4. c) it's our own LSP */
        else{
            if(lspRec->LSP->getRemLifeTime() != 0){
                if(lsp->getSeqNumber() >= lspRec->LSP->getSeqNumber()){
                    //std::cout<<"purgeLSP seqNum: " << lspRec->LSP->getSeqNumber() <<endl;
                    lspRec->LSP->setSeqNumber(lsp->getSeqNumber() + 1);
                    //std::cout<<"purgeLSP seqNum: " << lspRec->LSP->getSeqNumber() <<endl;
                }
                /*7.3.16.4. c) 4) set SRMflags for all circuits */
                this->setSRMflags(lspRec, circuitType);
            }
        }
    }
    delete lsp;
    delete lspId;
}
void ISIS::purgeMyLSPs ( short  circuitType) [private]

Definition at line 5574 of file ISIS.cc.

Referenced by generateLSP().

                                       {

    std::vector<LSPRecord *>* lspDb;

    lspDb = this->getLSPDb(circuitType);
    unsigned char *lspId;
    for(std::vector<LSPRecord*>::iterator it = lspDb->begin(); it != lspDb->end(); ++it){
        lspId = this->getLspID((*it)->LSP);
        if(this->compareArrays(lspId, (unsigned char *) this->sysId, ISIS_SYSTEM_ID)){
            this->purgeLSP(lspId, circuitType);
        }
        delete lspId;
    }
}
void ISIS::purgeRemainLSP ( unsigned char *  lspId,
short  circuitType 
) [private]

Definition at line 5558 of file ISIS.cc.

Referenced by electL1DesignatedIS(), generateLSP(), and removeDeadNeighbour().

                                                                {

    //lspId[ISIS_SYSTEM_ID + 1] = lspId[ISIS_SYSTEM_ID + 1] + 1;

    while(this->getLSPFromDbByID(lspId, circuitType) != NULL){
        this->purgeLSP(lspId, circuitType);
        //this should increment fragment-ID for the next round check
        lspId[ISIS_SYSTEM_ID + 1] = lspId[ISIS_SYSTEM_ID + 1] + 1;

    }
}
void ISIS::refreshLSP ( ISISTimer timer) [private]

Definition at line 5371 of file ISIS.cc.

Referenced by handleMessage().

                                     {
    //this->printLSPDB();

    if (this->isType == L1_TYPE || this->isType == L1L2_TYPE)
    {
        this->refreshLSP(L1_TYPE);
    }
    if (this->isType == L2_TYPE || this->isType == L1L2_TYPE)
    {
        this->refreshLSP(L2_TYPE);
    }
    //this->printLSPDB();

    this->schedule(timer);

}
void ISIS::refreshLSP ( short  circuitType) [private]

Definition at line 5393 of file ISIS.cc.

{
    std::vector<LSPRecord*>* lspDb = this->getLSPDb(circuitType);
    std::vector<LSPRecord*>::iterator it = lspDb->begin();
    unsigned char *lspId;
    for(; it != lspDb->end(); ++it){
        lspId = this->getLspID((*it)->LSP);
        if(this->compareArrays(lspId, (unsigned char *) this->sysId, ISIS_SYSTEM_ID) && (*it)->deadTimer->getTimerKind() != LSP_DELETE && (*it)->LSP->getRemLifeTime() != 0 ){
            //this->printLSP((*it)->LSP, "print from refreshLSP");
            //std::cout<<"RefreshLSP: seqNum: " <<(*it)->LSP->getSeqNumber() << endl;
            (*it)->LSP->setSeqNumber((*it)->LSP->getSeqNumber() + 1);
            //std::cout<<"RefreshLSP: seqNum: " <<(*it)->LSP->getSeqNumber() << endl;
           // this->printLSP((*it)->LSP, "print from refreshLSP");
            (*it)->LSP->setRemLifeTime(this->lspMaxLifetime);
            //cancel original deadTimer
            cancelEvent((*it)->deadTimer);

            this->setSRMflags((*it), circuitType);
            //TODO what about SSNflags?
            //this->clearSSNflags((*it), circuitType);

            (*it)->simLifetime = simTime().dbl() + (*it)->LSP->getRemLifeTime();

            //re-schedule dead timer
            this->schedule((*it)->deadTimer, (*it)->LSP->getRemLifeTime());
        }
        delete lspId;
    }
}
void ISIS::removeDeadLSP ( ISISTimer timer) [private]

Remove LSP which wasn't refreshed for 900 sec. Flood LSP packet with sequence ID = 0 indicating dead LSP.

Parameters:
timerTimer associated with dead LSP

Definition at line 4915 of file ISIS.cc.

{
    for(unsigned int i=0; i<L1LSP.size(); i++)
    {
        //find dead LSP ID
        bool found = true;
        for(unsigned int j=0; j<timer->getLSPidArraySize(); j++)
        {
            if(timer->getLSPid(j) != L1LSP.at(i).LSPid[j])
                found = false;
        }

        //we found it!
        if(found)
        {

            //mark with sequence number 0
            L1LSP.at(i).seq = 0;
            L1LSP.at(i).neighbours.clear();
            //send empty LSP informing about expiration
            this->sendSpecificL1LSP(L1LSP.at(i).LSPid);
            //now completely delete
            L1LSP.erase(L1LSP.begin() + i);
            break;
        }
    }
}
void ISIS::removeDeadNeighbour ( ISISTimer msg) [private]

Remove dead neighbour, when timer expires. Remove neighbour from adjacency table (L1 or L2) and start new DIS election process.

Parameters:
msgTimer associated with dead neighbour.

Definition at line 3152 of file ISIS.cc.

Referenced by handleMessage().

{

    /* Check it and rewrite it */
    EV << "ISIS: Warning: RemoveDeadNeighbour: If everything is working correctly, this method shoudn't be called" <<endl;

    //L1 neighbour dead
    // * remove from adjL1Table
    // * reset DIS on Ift

    if(msg->getIsType() == L1_TYPE)
    {
        for(unsigned int i=0; i<adjL1Table.size();)
        {
            bool found = true;
            for(unsigned int j = 0; j<msg->getSysIDArraySize(); j++)
            {
                if(msg->getSysID(j) != adjL1Table.at(i).sysID[j])
                    found = false;
            }

            if(found)
            {
                adjL1Table.erase(adjL1Table.begin() + i);
            }else{
                i++;
            }
        }
        std::sort(this->adjL1Table.begin(), this->adjL1Table.end());

        unsigned char *lspId = this->getLspID(msg);
        this->purgeRemainLSP(lspId, msg->getIsType());


        if(this->ISISIft.at(msg->getInterfaceIndex()).network){
            //lspId has two bytes more than we need (that does no harm)
            this->resetDIS(lspId, msg->getInterfaceIndex(), msg->getIsType());
        }
        delete lspId;

    }

    //else it's L2 dead neighbour
    // * remove from adjL2Table
    else
    {
        for(unsigned int i=0; i<adjL2Table.size(); i++)
        {
            bool found = true;
            for(unsigned int j = 0; j<msg->getSysIDArraySize(); j++)
            {
                if(msg->getSysID(j) != adjL2Table.at(i).sysID[j])
                    found = false;
            }

            // WHY must area ID also match??

            //area ID must also match
            for(unsigned int j=0; j<msg->getAreaIDArraySize();j++)
            {
                if(msg->getAreaID(j) != adjL2Table.at(i).areaID[j])
                {
                    found = false;
                }
            }

            if(found)
            {
                adjL2Table.erase(adjL2Table.begin()+i);
            }
        }
        std::sort(this->adjL2Table.begin(), this->adjL2Table.end());

        unsigned char *lspId = this->getLspID(msg);
        this->purgeRemainLSP(lspId, msg->getIsType());

        if(this->ISISIft.at(msg->getInterfaceIndex()).network){
            //lspId has two bytes more than we need (that does no harm)
            this->resetDIS(lspId, msg->getInterfaceIndex(), msg->getIsType());
        }

        delete lspId;


    }

}
void ISIS::replaceLSP ( ISISLSPPacket lsp,
LSPRecord lspRecord,
short  circuitType 
) [private]

Definition at line 6125 of file ISIS.cc.

Referenced by generateLSP(), handleL1Lsp(), and purgeLSP().

                                                                                {

    //increase sequence number
    //std::cout<<"replaceLSP seqNum: "<< lspRecord->LSP->getSeqNumber() <<endl;
    /*if(lsp->getSeqNumber() < lspRecord->LSP->getSeqNumber()){
        lsp->setSeqNumber(lspRecord->LSP->getSeqNumber() + 1);
    }else{
        lsp->setSeqNumber(lsp->getSeqNumber() + 1);
    }*/
    lsp->setSeqNumber(lspRecord->LSP->getSeqNumber() + 1);
    //now we can delete the previous LSP

    delete lspRecord->LSP;

    //set new lsp
    lspRecord->LSP = lsp;
    //std::cout<<"replaceLSP seqNum: "<< lspRecord->LSP->getSeqNumber() <<endl;
    //create new timer
    //lspRecord->deadTimer = new ISISTimer("LSP Dead Timer");
    //select appropriate type (this could be performed based on lsp)
    this->cancelEvent(lspRecord->deadTimer);

    lspRecord->deadTimer->setTimerKind(LSP_DEAD);


    lspRecord->deadTimer->setIsType(circuitType);
    for (unsigned int i = 0; i < lspRecord->deadTimer->getLSPidArraySize(); i++)
    {
        lspRecord->deadTimer->setLSPid(i, lspRecord->LSP->getLspID(i));
    }

    /* need to check  this for replacing LSP from genLSP */
    if(lsp->getArrivalGate() != NULL){
        //received so don't set SRM flag on that interface
//        int gateIndex = lsp->getArrivalGate()->getIndex();
//        /* 7.3.15.1 e) 1) ii. and iii. */ /* 7.3.16.4 b) 1) ii. and iii. */
//        this->setSRMflagsBut(lspRecord, gateIndex , circuitType);
//        /* 7.3.16.4 b) 1) v.  MODIFIED*/
//        this->clearSSNflags(lspRecord, circuitType);
//        //for non-broadcast /* 7.3.16.4 b) 1) iv. */
//        if(!this->ISISIft.at(gateIndex).network){
//            this->setSSNflag(lspRecord, gateIndex, circuitType);
//        }
        //received so don't set SRM flag on that interface
        int gateIndex = lsp->getArrivalGate()->getIndex();
        this->setSRMflagsBut(lspRecord, gateIndex , circuitType);
        //for non-broadcast /* 7.3.16.4 b) 1) iv. */
        if(!this->ISISIft.at(gateIndex).network){
            this->setSSNflag(lspRecord, gateIndex, circuitType);
        }
        /* 7.3.16.4 b) 1) v. */
        this->clearSSNflagsBut(lspRecord, gateIndex, circuitType);




    }else{
        //generated -> set SRM on all interfaces
        this->setSRMflags(lspRecord, circuitType);
        //TODO what with SSN?
        //this->clearSSNflags(lspRecord, circuitType);
    }



    //set simulation time when the lsp will expire
    lspRecord->simLifetime = simTime().dbl() + lspRecord->LSP->getRemLifeTime();

    this->schedule(lspRecord->deadTimer, lsp->getRemLifeTime());


}
void ISIS::resetDIS ( unsigned char *  systemID,
int  gateIndex,
short  circuitType 
) [private]

Reset DIS on all interfaces. New election occurs after reset.

See also:
electL1DesignatedIS(ISISL1HelloPacket *msg)
Parameters:
IStypeDefines IS type - L1 or L2

Definition at line 3398 of file ISIS.cc.

Referenced by removeDeadNeighbour().

{

ISISinterface *iface = &(this->ISISIft.at(gateIndex));
    if(circuitType == L1_TYPE || circuitType == L1L2_TYPE)
    {
        //if the systemID was DIS, then set DIS = me. if dead neighbour wasn't DIS do nothing.
        if(this->compareArrays(systemID, iface->L1DIS, ISIS_SYSTEM_ID + 1)){
            //set myself as DIS
            iface->L1DISpriority = iface->priority;
            //set initial designated IS as himself
            this->copyArrayContent((unsigned char*)this->sysId, iface->L1DIS, ISIS_SYSTEM_ID, 0, 0);
            //set LAN identifier; -99 is because, OMNeT starts numbering interfaces from 100 -> interfaceID 100 means LAN ID 0; and we want to start numbering from 1
            iface->L1DIS[ISIS_SYSTEM_ID] = iface->gateIndex + 1;
        }
    }

    if(circuitType == L2_TYPE || circuitType == L1L2_TYPE)
    {
        //if the systemID was DIS, then set DIS = me. if dead neighbour wasn't DIS do nothing.
        if(this->compareArrays(systemID, iface->L2DIS, ISIS_SYSTEM_ID + 1)){
            //set myself as DIS
            iface->L2DISpriority = iface->priority;
            //set initial designated IS as himself
            this->copyArrayContent((unsigned char*)this->sysId, iface->L2DIS, ISIS_SYSTEM_ID, 0, 0);
            //set LAN identifier; -99 is because, OMNeT starts numbering interfaces from 100 -> interfaceID 100 means LAN ID 0; and we want to start numbering from 1
            iface->L2DIS[ISIS_SYSTEM_ID] = iface->gateIndex + 1;
        }
    }
}
void ISIS::schedule ( ISISTimer timer,
double  timee = -1 
) [private]

Definition at line 1587 of file ISIS.cc.

Referenced by fullSPF(), generateLSP(), handleL1HelloMsg(), handleL2HelloMsg(), handlePTPHelloMsg(), initCsnp(), initGenerate(), initHello(), initPeriodicSend(), initPsnp(), initRefresh(), initSPF(), installLSP(), periodicSend(), purgeLSP(), refreshLSP(), replaceLSP(), sendHelloMsg(), sendL1Csnp(), and sendL1Psnp().

{

    double timeAt;
    double randomTime;


    switch (timer->getTimerKind())
    {
        case (ISIS_START):
            this->scheduleAt(0, timer);
            break;

        case (HELLO_TIMER):
            timeAt = this->getHelloInterval(timer->getInterfaceIndex(), timer->getIsType());
            randomTime = uniform(0, 0.25 * timeAt);
            this->scheduleAt(simTime() + timeAt - randomTime, timer);
            EV << "ISIS::schedule: timeAt: " << timeAt << " randomTime: " << randomTime << endl;
            break;

        case (NEIGHBOUR_DEAD):
        if(timee < 0){
                            EV << "ISIS: Warning: You forgot provide additional time to schedule for NEIGHBOUR_DEAD" << endl;
                            timee = 0;
                        }
            timeAt = timee;
            randomTime = uniform(0, 0.25 * timeAt);
            this->scheduleAt(simTime() + timeAt - randomTime, timer);
            break;

        case (PERIODIC_SEND):
            if (timer->getIsType() == L1_TYPE)
            {
                timeAt = this->L1LspSendInterval;
            }
            else if (timer->getIsType() == L2_TYPE)
            {
                timeAt = this->L2LspSendInterval;
            }
            else
            {
                EV << "ISIS: Warning: Unsupported IS-Type in schedule for PERIODIC_SEND" << endl;
            }

            randomTime = uniform(0, 0.25 * timeAt);
            this->scheduleAt(simTime() + timeAt - randomTime, timer);
            break;

        case (LSP_REFRESH):
            timeAt = this->lspRefreshInterval;
            randomTime = uniform(0, 0.25 * timeAt);
            this->scheduleAt(simTime() + timeAt - randomTime, timer);
            break;

        case (LSP_DEAD):
                if(timee < 0){
                    EV << "ISIS: Warning: You forgot provide additional time to schedule for LSP_DEAD" << endl;
                    timee = 0;
                }
            timeAt = timee;
            //randomTime = uniform(0, 0.25 * timeAt);
            this->scheduleAt(simTime() + timeAt, timer);
            break;

        case (LSP_DELETE):
            timeAt = this->lspMaxLifetime * 2;
            this->scheduleAt(simTime() + timeAt, timer);
            break;

        case (CSNP_TIMER):
                if (timer->getIsType() == L1_TYPE)
                {
                    timeAt = this->ISISIft.at(timer->getInterfaceIndex()).L1CsnpInterval;
                }
                else if (timer->getIsType() == L2_TYPE)
                {
                    timeAt = this->ISISIft.at(timer->getInterfaceIndex()).L2CsnpInterval;
                }
                else
                {
                    EV << "ISIS: Warning: Unsupported IS-Type in schedule for CSNP_TIMER" << endl;
                }

                randomTime = uniform(0, 0.25 * timeAt);
                this->scheduleAt(simTime() + timeAt - randomTime, timer);
                break;
        case (PSNP_TIMER):
                if (timer->getIsType() == L1_TYPE)
                {
                    timeAt = this->ISISIft.at(timer->getInterfaceIndex()).L1PsnpInterval;
                }
                else if (timer->getIsType() == L2_TYPE)
                {
                    timeAt = this->ISISIft.at(timer->getInterfaceIndex()).L2PsnpInterval;
                }
                else
                {
                    EV << "ISIS: Warning: Unsupported IS-Type in schedule for PSNP_TIMER" << endl;
                }

                randomTime = uniform(0, 0.25 * timeAt);
                this->scheduleAt(simTime() + timeAt - randomTime, timer);
                break;

        case (L1_CSNP):
            timeAt = this->ISISIft.at(timer->getInterfaceIndex()).L1CsnpInterval;
            randomTime = uniform(0, 0.25 * timeAt);
            this->scheduleAt(simTime() + timeAt - randomTime, timer);

            break;

        case (L1_PSNP):
            timeAt = this->ISISIft.at(timer->getInterfaceIndex()).L1PsnpInterval;
            randomTime = uniform(0, 0.25 * timeAt);
            this->scheduleAt(simTime() + timeAt - randomTime, timer);

            break;

        case (GENERATE_LSP_TIMER):
            if (timer->getIsType() == L1_TYPE)
            {
                if ((simTime().dbl() + this->L1LspGenInterval) * 1000 < this->L1LspInitWait)
                {
                    timeAt = this->L1LspInitWait / 1000;
                }
                else
                {
                    timeAt = this->L1LspGenInterval;
                }
            }
            else if (timer->getIsType() == L2_TYPE)
            {
                if ((simTime().dbl() + this->L2LspGenInterval) * 1000 < this->L2LspInitWait)
                {
                    timeAt = this->L2LspInitWait / 1000;
                }
                else
                {
                    timeAt = this->L2LspGenInterval;
                }
            }else{
                EV << "ISIS: ERROR: Unsupported IS-Type in PERIODIC_SEND timer" << endl;
            }
            randomTime = uniform(0, 0.25 * timeAt);
            this->scheduleAt(simTime() + timeAt - randomTime, timer);

            break;

        case (SPF_FULL):
                if(timer->getIsType() == L1_TYPE){
                   timeAt = this->L1SPFFullInterval;
                }else if(timer->getIsType() == L2_TYPE){
                    timeAt = this->L2SPFFullInterval;
                }else{
                    EV<<"ISIS: Error Unsupported IS-Type in SPF_FULL timer" <<endl;
                }
                randomTime = uniform(0, 0.25 * timeAt);
                this->scheduleAt(simTime() + timeAt - randomTime, timer);
                break;

        default:
            EV << "ISIS: ERROR: Unsupported timer type in schedule" << endl;
            break;
    }


}
void ISIS::sendBroadcastHelloMsg ( int  interfaceIndex,
short  circuitType 
) [private]

Definition at line 1275 of file ISIS.cc.

Referenced by sendHelloMsg().

                                                        {
    // create L1 and L2 hello packets

    ISISL1HelloPacket *helloL1 = new ISISL1HelloPacket("L1 Hello");
    ISISL2HelloPacket *helloL2 = new ISISL2HelloPacket("L2 Hello");


    //set circuit type field
    helloL1->setCircuitType(L1_TYPE);
    helloL2->setCircuitType(L2_TYPE);


    //set source id
    for (unsigned int i = 0; i < 6; i++)
    {
        helloL1->setSourceID(i, sysId[i]);
        helloL2->setSourceID(i, sysId[i]);
    }
    EV << endl;



    /* TODO
     * They should have separate Ethernet control info but OMNeT++ simulation
     doesn't recognize 01:80:c2:00:00:14 and 01:80:c2:00:00:15 as multicast OSI
     MAC addresses. Therefore destination MAC address is always set to broadcast
     ff:ff:ff:ff:ff:ff
     */

    Ieee802Ctrl *ctrl = new Ieee802Ctrl();
    Ieee802Ctrl *ctrl2;

    // set DSAP & NSAP fields
    ctrl->setDsap(SAP_CLNS);
    ctrl->setSsap(SAP_CLNS);

    //set appropriate destination MAC addresses
    MACAddress ma;
    ma.setAddress("ff:ff:ff:ff:ff:ff");

    ctrl->setDest(ma);

    ctrl2 = ctrl->dup();

    //assign Ethernet control info
    helloL1->setControlInfo(ctrl);
    helloL2->setControlInfo(ctrl2);


    //set TLVs
    TLV_t myTLV;
    //helloL1->setTLVArraySize(0);

    //set area address
    myTLV.type = AREA_ADDRESS;
    myTLV.length = 3;
    myTLV.value = new unsigned char[3];
    this->copyArrayContent((unsigned char *) areaId, myTLV.value, 3, 0, 0);
    unsigned int tlvSize = helloL1->getTLVArraySize();
    helloL1->setTLVArraySize(tlvSize + 1); //resize array
    helloL1->setTLV(tlvSize, myTLV);

    tlvSize = helloL2->getTLVArraySize();
    helloL2->setTLVArraySize(tlvSize + 1); //resize array
    helloL2->setTLV(tlvSize, myTLV);


    //set NEIGHBOURS L1 TLV
    myTLV.type = IS_NEIGHBOURS_HELLO;
    myTLV.length = adjL1Table.size() * 6; //number of records * 6 (6 is size of system ID/MAC address)
    myTLV.value = new unsigned char[adjL1Table.size() * 6];

    for (unsigned int h = 0; h < adjL1Table.size(); h++)
    {
        this->copyArrayContent(adjL1Table.at(h).mac.getAddressBytes(), myTLV.value, 6, 0, h * 6);
    }

    tlvSize = helloL1->getTLVArraySize();
    helloL1->setTLVArraySize(tlvSize + 1);
    helloL1->setTLV(tlvSize, myTLV);

    //L2 neighbours
    myTLV.type = IS_NEIGHBOURS_HELLO;
    myTLV.length = adjL2Table.size() * 6; //number of records * 6 (6 is size of system ID/MAC address)
    myTLV.value = new unsigned char[adjL2Table.size() * 6];
    //L2 neighbours
    for (unsigned int h = 0; h < adjL2Table.size(); h++)
    {
        this->copyArrayContent(adjL2Table.at(h).mac.getAddressBytes(), myTLV.value, 6, 0, h * 6);
    }

    tlvSize = helloL2->getTLVArraySize();
    helloL2->setTLVArraySize(tlvSize + 1);
    helloL2->setTLV(tlvSize, myTLV);


    //PADDING TLV is omitted

    //TODO Authentication TLV

    //TODO add eventually another TLVs (eg. from RFC 1195)

    //don't send hello packets from passive interfaces
    if (!ISISIft.at(k).passive && ISISIft.at(k).ISISenabled)
    {
        // if this interface is DIS for LAN, hellos are sent 3-times faster (3.33sec instead of 10.0)
        // decision is made according to global hello counter (dirty hax - don't blame me pls, but i don't have time to code it nice way :)

        switch (ISISIft.at(k).circuitType)
            {
            case (L1_TYPE): {
                //copy packet with control info
                ISISL1HelloPacket *copy1 = helloL1->dup();
                Ieee802Ctrl *ctrlCopy1 = ctrl->dup();
                copy1->setControlInfo(ctrlCopy1);

                //set LAN ID field (designated L1 IS)
                for (unsigned int j = 0; j < 7; j++)
                {
                    copy1->setLanID(j, ISISIft.at(k).L1DIS[j]);
                }

                copy1->setPriority(ISISIft.at(k).priority);
                send(copy1, "ifOut", ISISIft.at(k).gateIndex);
                EV
                        << "'devideId :" << deviceId << " ISIS: L1 Hello packet was sent from "
                                << ISISIft.at(k).entry->getName() << "\n";
                break;
            }
            case (L2_TYPE): { //copy packet with control info
                ISISL2HelloPacket *copy2 = helloL2->dup();
                Ieee802Ctrl *ctrlCopy2 = ctrl->dup();
                copy2->setControlInfo(ctrlCopy2);

                //set LAN ID field (designated L2 IS)
                for (unsigned int j = 0; j < 7; j++)
                {
                    copy2->setLanID(j, ISISIft.at(k).L2DIS[j]);
                }

                copy2->setPriority(ISISIft.at(k).priority);
                send(copy2, "ifOut", ISISIft.at(k).gateIndex);
                EV
                        << "deviceId " << deviceId << ": L2 Hello packet was sent from "
                                << ISISIft.at(k).entry->getName() << "\n";
                break;
            }
            case (L1L2_TYPE): {
                /*Newly this method should be called per circuit type so this "case" shouldn't be needed.
                * Before deletion, this behavior needs to be implemented on several places throughout the code.
                * Mainly in initISIS and rescheduling new events.
                */
                //send both - L1 & L2 hellos
                ISISL1HelloPacket *copy = helloL1->dup();
                Ieee802Ctrl *ctrlCopy = ctrl->dup();
                copy->setControlInfo(ctrlCopy);
                //set LAN ID field (designated L1 IS)
                for (unsigned int j = 0; j < 7; j++)
                {
                    copy->setLanID(j, ISISIft.at(k).L1DIS[j]);
                }
                copy->setPriority(ISISIft.at(k).priority);
                send(copy, "ifOut", ISISIft.at(k).gateIndex);
                EV
                        << "'devideId " << deviceId << ": L1 Hello packet was sent from "
                                << ISISIft.at(k).entry->getName() << "\n";

                ISISL2HelloPacket *copy2 = helloL2->dup();
                Ieee802Ctrl *ctrlCopy2 = ctrl->dup();
                copy2 = helloL2->dup();
                ctrlCopy2 = ctrl->dup();
                copy2->setControlInfo(ctrlCopy2);
                //set LAN ID field (designated L2 IS)
                for (unsigned int j = 0; j < 7; j++)
                {
                    copy2->setLanID(j, ISISIft.at(k).L2DIS[j]);
                }
                copy2->setPriority(ISISIft.at(k).priority);
                send(copy2, "ifOut", ISISIft.at(k).gateIndex);
                EV
                        << "deviceId " << deviceId << ": L2 Hello packet was sent from "
                                << ISISIft.at(k).entry->getName() << "\n";
                break;
            }
            default:
                EV << "deviceId " << deviceId << ": Warning: Unrecognized circuit type" << endl;
                break;


            }

    }

    delete helloL1;
    delete helloL2; //TODO
}
void ISIS::sendHelloMsg ( ISISTimer timer) [private]

Create hello packet and send it out to specified interface. This method handle LAN hello and PTP hello packets. Destination MAC address is broadcast (ff:ff:ff:ff:ff:ff).

Parameters:
timeris timer that triggered this action

Definition at line 1251 of file ISIS.cc.

Referenced by handleMessage().

{
    if (this->ISISIft.at(timer->getInterfaceIndex()).network)
    {
        EV << "ISIS: sendingBroadcastHello: " << endl;
        this->sendBroadcastHelloMsg(timer->getInterfaceIndex(), timer->getIsType());

    }
    else
    {
        EV << "ISIS: sendingPTPHello: " << endl;
        this->sendPTPHelloMsg(timer->getInterfaceIndex(), timer->getIsType());
    }
    //re-schedule timer
    this->schedule(timer);

}
void ISIS::sendL1Csnp ( ISISTimer timer) [private]

Definition at line 3902 of file ISIS.cc.

Referenced by handleMessage().

{
    //TODO don't know how to handle csnp over PtP yet (there is no periodic sending, but initial csnp is sent)
    /* Maybe send CSNP during some initial interval (or number of times, or just once) and then just don't re-schedule timer for this interface */
    if(!this->ISISIft.at(timer->getInterfaceIndex()).network || !this->amIL1DIS(timer->getInterfaceIndex())){
        this->schedule(timer);
        return;
    }
    short circuitType = L1_TYPE;

    std::vector<LSPRecord *> *lspDb = this->getLSPDb(circuitType);
    std::vector<LSPRecord *>::iterator it = lspDb->begin();
    for (int fragment = 0; it != lspDb->end(); fragment++)

    {
        ISISCSNPPacket *packet = new ISISCSNPPacket("L1 CSNP");
        packet->setType(L1_CSNP);
        packet->setLength(0); //TODO set to length of header

        //add Ethernet control info
        Ieee802Ctrl *ctrl = new Ieee802Ctrl();

        // set DSAP & NSAP fields
        ctrl->setDsap(SAP_CLNS);
        ctrl->setSsap(SAP_CLNS);

        //set destination broadcast address
        //It should be multicast 01-80-C2-00-00-14 MAC address, but it doesn't work in OMNeT
        MACAddress ma;
        ma.setAddress("ff:ff:ff:ff:ff:ff");
        ctrl->setDest(ma);
        packet->setControlInfo(ctrl);

        //set system ID field which consists of my system id + zero circuit id inc this case
        for (unsigned int i = 0; i < packet->getSourceIDArraySize() - 1; i++)
        {
            packet->setSourceID(i, this->sysId[i]);
        }
        packet->setSourceID(6, 0); //ORLY? have to be changed during sending according to interface this CSNP is being send on

        int lspCount = lspDb->end() - it;

        //TODO set start LSP-ID
        if (fragment != 0)
        {
            for (unsigned int i = 0; i < ISIS_SYSTEM_ID + 2; i++)
            {
                packet->setStartLspID(i, (*it)->LSP->getLspID(i));
            }
        }
        else
        {
            for (unsigned int i = 0; i < ISIS_SYSTEM_ID + 2; i++)
            {
                packet->setStartLspID(i, 0);
            }
        }

        for (; it != lspDb->end() && packet->getLength() < ISIS_LSP_MAX_SIZE;)
        {

            TLV_t myTLV;
            myTLV.type = LSP_ENTRIES;

            if (lspCount * 16 > 255)
            { //TODO replace "16" with something more appropriate
                myTLV.length = 255 - (255 % 16); //TODO minus size of header
            }
            else
            {
                myTLV.length = lspCount * 16;
            }
            myTLV.value = new unsigned char[myTLV.length];
            myTLV.length = 0;

            for (int i = 0;
                    (myTLV.length + 16) < 255 && it != lspDb->end()
                            && (packet->getLength() + (myTLV.length + 16) + 2) < ISIS_LSP_MAX_SIZE; ++it, i++)
            { //255 is maximum that can fit into Length field of TLV
                //add entry from lspDb
                //convert unsigned short to unsigned char array and insert to TLV
                myTLV.value[(i * 16)] = (((*it)->LSP->getRemLifeTime() >> 8) & 0xFF);
                myTLV.value[(i * 16) + 1] = ((*it)->LSP->getRemLifeTime() & 0xFF);

                //copy LSP ID to TLV
                unsigned char *lspId = this->getLspID((*it)->LSP);
                this->copyArrayContent(lspId, myTLV.value, ISIS_SYSTEM_ID + 2, 0, (i * 16) + 2);
                delete lspId;
                //convert unsigned long seq number to unsigned char array[4] and insert into TLV
                for (unsigned int j = 0; j < 4; j++)
                {
                    myTLV.value[(i * 16) + 10 + j] = ((*it)->LSP->getSeqNumber() >> (24 - (8 * j))) & 0xFF;
                }

                //set end LSP-ID

                myTLV.length += 16;
                //packet->setLength(packet->getLength() + 16);
            }
            //int tlvSize = packet->getTLVArraySize();
            this->addTLV(packet, &myTLV);
            packet->setLength(packet->getLength() + myTLV.length + 2);

            delete myTLV.value;

        }
        if (it != lspDb->end()) //if there is still another lsp in DB
        {
            for (unsigned int i = 0; i < ISIS_SYSTEM_ID + 2; i++)
            {
                packet->setEndLspID(i, (*it)->LSP->getLspID(i));
            }
        }
        else
        //this was last lsp, so mark it as last with LSP-ID FFFFF...
        {
            for (unsigned int i = 0; i < ISIS_SYSTEM_ID + 2; i++)
            {
                packet->setEndLspID(i, 255);
            }

        }

        if (timer->getInterfaceIndex() != this->getIfaceIndex(this->getIfaceByGateIndex(timer->getInterfaceIndex())))
        {
            EV << "ISIS: Warning: Houston, we got a problem! A BIG ONE!" << endl;
        }

        //send only on interface specified in timer
        send(packet, "ifOut", timer->getInterfaceIndex());

        /*
         //send packet on ALL interfaces with adjacency UP
         for(std::vector<ISISinterface>::iterator intIt = this->ISISIft.begin(); intIt != this->ISISIft.end(); ++intIt)
         {
         if(isUp((*intIt).gateIndex, circuitType) && (*intIt).network && this->compareArrays((unsigned char *)this->sysId, (*intIt).L1DIS, ISIS_SYSTEM_ID))//TODO L1DIS is not based on circuitType
         {
         ISISCSNPPacket *packetDup = packet->dup();
         Ieee802Ctrl *ctrlDup = ctrl->dup();
         packetDup->setControlInfo(ctrlDup);
         //set source LAN ID
         packetDup->setSourceID(ISIS_SYSTEM_ID, (*intIt).gateIndex);
         send(packetDup, "ifOut", (*intIt).gateIndex);
         }
         }
         delete ctrl;
         delete packet;
         */
    }

    //reschedule timer
    this->schedule(timer);

}
void ISIS::sendL1CSNP ( ) [private]

Send CSNP packet to each LAN, where this router represents DIS. Repeat every 10 seconds.

Definition at line 4490 of file ISIS.cc.

{
    EV << "ISIS: Warning: Running deprecated method" << endl;
    //update my own LSPs

    ISISCSNPL1Packet *packet = new ISISCSNPL1Packet("L1 CSNP");


    //add Ethernet controll info
    Ieee802Ctrl *ctrl = new Ieee802Ctrl();

    // set DSAP & NSAP fields
    ctrl->setDsap(SAP_CLNS);
    ctrl->setSsap(SAP_CLNS);

    //set destination broadcast address
    //It should be multicast 01-80-C2-00-00-14 MAC address, but it doesn't work in OMNeT
    MACAddress ma;
    ma.setAddress("ff:ff:ff:ff:ff:ff");
    ctrl->setDest(ma);

    //set system ID field which consists of my system id + zero circuit id inc this case
    for(unsigned int i=0; i<packet->getSourceIDArraySize()-1; i++)
    {
        packet->setSourceID(i, this->sysId[i]);
    }
    packet->setSourceID(6, 0);

    //set start LSP ID to zeros and end LSP ID to max value
    for(unsigned int i=0; i<packet->getStartLspIDArraySize(); i++)
    {
        packet->setStartLspID(i,0);
        packet->setEndLspID(i,255);
    }

    //set area address TLV
    TLV_t myTLV;
    myTLV.type = LSP_ENTRIES;
    myTLV.length = this->L1LSP.size()*14;
    myTLV.value = new unsigned char[myTLV.length];
    /*
     * Value Multiples of LSP summaries, each consisting of the remaining lifetime (2 bytes), LSP ID (ID length + 2 bytes),
     * LSP sequence number(4 bytes), and LSP checksum (2 bytes). But we ignore LSP checksum so length of each LSP record in CSNP is
     * 2 bytes smaller.
     */
    for(unsigned int i=0;i<L1LSP.size(); i++)
    {
        //get remaining lifetime //TODO change value to constant or something
        unsigned short remTime = 50 - ((unsigned short)(simTime().dbl()) - (unsigned short)(L1LSP.at(i).deadTimer->getCreationTime().dbl()));

        //convert unsigned short to unsigned char array and insert to TLV
        myTLV.value[(i*14)] = ((remTime >> 8) & 0xFF);
        myTLV.value[(i*14)+1] = (remTime & 0xFF);

        //copy LSP ID to TLV
        this->copyArrayContent(L1LSP.at(i).LSPid, myTLV.value, 8, 0, (i*14)+2);

        //convert unsigned long seq number to unsigned char array[4] and insert into TLV
        for(unsigned int j=0; j<4; j++)
        {
            myTLV.value[(i*14)+10+j] = (L1LSP.at(i).seq >> (24-(8*j))) & 0xFF;
        }
    }

    packet->setTLVArraySize(1);
    packet->setTLV(0, myTLV);


    /* - TODO Auth TLV
       - eventually implement ES neighbours TLV, but I don't think it's necessary
       - next TLVs from RFC 1195 if IP should be supported in future
    */

    //walk through all itnerfaces
    for(unsigned int a=0; a<ISISIft.size(); a++)
    {
        //if interface status meets condition
        if(!ISISIft.at(a).passive && ISISIft.at(a).ISISenabled && (ISISIft.at(a).circuitType == L1_TYPE || ISISIft.at(a).circuitType == L1L2_TYPE))
        {
            //check if this Ift represents DIS on associated LAN
            unsigned char myLANid[7];
            this->copyArrayContent((unsigned char *)this->sysId, myLANid, 7, 0, 0);
            myLANid[6] = ISISIft.at(a).gateIndex + 1;

            //if they match, send CSNP packet to that LAN
            if(this->compareArrays(myLANid, ISISIft.at(a).L1DIS, 7))
            {
                ISISCSNPL1Packet *packetCopy = packet->dup();
                Ieee802Ctrl *ctrlCopy = ctrl->dup();
                packetCopy->setControlInfo(ctrlCopy);
                send(packetCopy, "ifOut", ISISIft.at(a).gateIndex);
            }
        }
    }

    //set new CNSP timer (10s)
    ISISTimer *CSNPtimer =  new ISISTimer("Send CSNP packets");
    CSNPtimer->setTimerKind(CSNP_TIMER);
    scheduleAt(simTime() + 10.0, CSNPtimer);

    delete packet;
}
void ISIS::sendL1Psnp ( ISISTimer timer) [private]

Definition at line 4061 of file ISIS.cc.

Referenced by handleMessage().

                                     {

    if(this->amIL1DIS(timer->getInterfaceIndex())){
        //reschedule OR make sure that during DIS election/resignation this timer is handled correctly
        //this is a safer, but dumber, solution
        //TODO see above
        this->schedule(timer);
        return;

    }
    short circuitType = L1_TYPE; //TODO get type from timer
    ISISinterface * iface = &(this->ISISIft.at(timer->getInterfaceIndex()));
    std::vector<FlagRecord*> *SSNQueue = this->getSSNQ(iface->network, iface->gateIndex, circuitType);

    //if queue is empty reschedule timer
    if(SSNQueue->empty()){
        this->schedule(timer);
        return;
    }



    ISISPSNPPacket *packet = new ISISPSNPPacket("L1 PSNP");
    packet->setType(L1_PSNP);

    //add Ethernet controll info
    Ieee802Ctrl *ctrl = new Ieee802Ctrl();

    // set DSAP & NSAP fields
    ctrl->setDsap(SAP_CLNS);
    ctrl->setSsap(SAP_CLNS);

    //set destination broadcast address
    //It should be multicast 01-80-C2-00-00-14 MAC address, but it doesn't work in OMNeT
    MACAddress ma;
    ma.setAddress("ff:ff:ff:ff:ff:ff");
    ctrl->setDest(ma);

    packet->setControlInfo(ctrl);

    //set system ID field which consists of my system id + zero circuit id in this case
    for (unsigned int i = 0; i < packet->getSourceIDArraySize() - 1; i++)
    {
        packet->setSourceID(i, this->sysId[i]);
    }
    packet->setSourceID(6, 0);

    //TODO check that all fields of the packet are filled correctly

    unsigned int lspCount = SSNQueue->size();
    for(std::vector<FlagRecord*>::iterator it = SSNQueue->begin(); it != SSNQueue->end(); )
    {


        TLV_t myTLV;
        myTLV.type = LSP_ENTRIES;

        if (lspCount * 16 > 255)
        { //TODO replace "16" with something more appropriate
            myTLV.length = 255 - (255 % 16); //TODO minus size of header
        }
        else
        {
            myTLV.length = lspCount * 16;
        }
        myTLV.value = new unsigned char[myTLV.length];
        myTLV.length = 0;

        for (int i = 0;
                (myTLV.length + 16) < 255 && it != SSNQueue->end()
                        && (packet->getLength() + (myTLV.length + 16) + 2) < ISIS_LSP_MAX_SIZE; it = SSNQueue->begin(), i++)
        { //255 is maximum that can fit into Length field of TLV
            //add entry from lspDb

            //convert unsigned short to unsigned char array and insert to TLV
            myTLV.value[(i * 16)] = (((*it)->lspRec->LSP->getRemLifeTime() >> 8) & 0xFF);
            myTLV.value[(i * 16) + 1] = ((*it)->lspRec->LSP->getRemLifeTime() & 0xFF);


            //copy LSP ID to TLV
            unsigned char *lspId = this->getLspID((*it)->lspRec->LSP);
            this->copyArrayContent(lspId, myTLV.value, ISIS_SYSTEM_ID + 2, 0, (i * 16) + 2);
            delete lspId;
            //convert unsigned long seq number to unsigned char array[4] and insert into TLV
            for (unsigned int j = 0; j < 4; j++)
            {
                myTLV.value[(i * 16) + 10 + j] = ((*it)->lspRec->LSP->getSeqNumber() >> (24 - (8 * j))) & 0xFF;
            }

            //set end LSP-ID

            myTLV.length += 16;
            //packet->setLength(packet->getLength() + 16);

            //it should wait after sending the lsp, but let's just assume it will work fine
            //clear SSNflag, this should also remove the flagRecord from correct queue(vector
            this->clearSSNflag((*it)->lspRec, (*it)->index, circuitType);
        }
        //int tlvSize = packet->getTLVArraySize();
        this->addTLV(packet, &myTLV);
        packet->setLength(packet->getLength() + myTLV.length + 2);
        delete myTLV.value;




    }

    if (timer->getInterfaceIndex() != this->getIfaceIndex(this->getIfaceByGateIndex(timer->getInterfaceIndex())))
    {
        EV << "ISIS: Warning: Houston, we got a problem! A BIG ONE!" << endl;
    }

    //send only on interface specified in timer
    send(packet, "ifOut", timer->getInterfaceIndex());

    this->schedule(timer);
}
void ISIS::sendL1PSNP ( std::vector< unsigned char * > *  LSPlist,
int  gateIndex 
) [private]

Send PSNP packet after being found, that some LSP entry/entries are outdated or missing. Packet consists of LSP list to be asked for.

See also:
handleL1CSNP(ISISMessage * inMsg)
Parameters:
gateIndexindex of gate which is received CSNP packet came from (we will send PSNP packet out from this ift)
LSPlistlist of LSP entries to be asked for

Definition at line 4709 of file ISIS.cc.

Referenced by handleL1CSNP().

{
    ISISPSNPL1Packet *packet = new ISISPSNPL1Packet("L1 PSNP");

    //add Ethernet controll info
    Ieee802Ctrl *ctrl = new Ieee802Ctrl();

    // set DSAP & NSAP fields
    ctrl->setDsap(SAP_CLNS);
    ctrl->setSsap(SAP_CLNS);

    //set destination broadcast address
    //It should be multicast 01-80-C2-00-00-14 MAC address, but it doesn't work in OMNeT
    MACAddress ma;
    ma.setAddress("ff:ff:ff:ff:ff:ff");
    ctrl->setDest(ma);

    packet->setControlInfo(ctrl);

    //set system ID field which consists of my system id + zero circuit id in this case
    for(unsigned int i=0; i<packet->getSourceIDArraySize()-1; i++)
    {
        packet->setSourceID(i, this->sysId[i]);
    }
    packet->setSourceID(6, 0);

    //set area address TLV
    TLV_t myTLV;
    myTLV.type = LSP_ENTRIES;
    myTLV.length = LSPlist->size()*14;
    myTLV.value = new unsigned char[myTLV.length];
    /*
     * Value� Multiples of LSP summaries, each consisting of the remaining lifetime (2 bytes), LSP ID (ID length + 2 bytes),
     * LSP sequence number(4 bytes), and LSP checksum (2 bytes). But we ignore LSP checksum so length of each LSP record in CSNP is
     * 2 bytes smaller.
     */
    for(unsigned int i=0;i<LSPlist->size(); i++)
    {
        this->copyArrayContent(LSPlist->at(i), myTLV.value, 14, 0, i*14);
    }

    packet->setTLVArraySize(1);
    packet->setTLV(0, myTLV);


    /* - TODO Auth TLV
       - eventually implement ES neighbours TLV, but I don't think it's necessary
       - next TLVs from RFC 1195 if IP should be supported in future
    */

    //send packet to same interface as CSNP packet came in
    //DIS should receive this packet and handle it
    send(packet, "ifOut", gateIndex);
}
void ISIS::sendL2CSNP ( ) [private]

Not implemented yet

Definition at line 4596 of file ISIS.cc.

{
    //TODO
}
void ISIS::sendL2PSNP ( ) [private]

Not implemented yet

Definition at line 4767 of file ISIS.cc.

{
    //TODO
}
void ISIS::sendLSP ( LSPRecord lspRec,
int  gateIndex 
) [private]

Definition at line 5036 of file ISIS.cc.

Referenced by periodicSend().

                                                  {

    /* TODO
     * incorporate this->lspInterval ... Minimum delay in ms between sending two LSPs.
     *
     */
/*    std::cout<<"Sending LSP from: ";
    this->printSysId((unsigned char *)this->sysId);
    std::cout<< endl;
    std::cout<<"sendLsp to:" << gateIndex <<" : ";
    this->printLspId(this->getLspID(lspRec->LSP));

    this->printLSP(lspRec->LSP, "sendLSP");*/
    //update remainingLifeTime
    //TODO check if new remLifeTime is not 0 or smaller
    if(lspRec->deadTimer->getTimerKind() == LSP_DELETE){

    }else{
        double remLife = lspRec->simLifetime - simTime().dbl();
        if (remLife < 0)
        {
            EV << "ISIS: Warning: Remaining lifetime smaller than zero in senLSP" << endl;
            lspRec->LSP->setRemLifeTime(1);
        }
        else
        {
            unsigned short rem = floor(remLife);
            lspRec->LSP->setRemLifeTime(rem);
        }
    }

    ISISLSPPacket *tmpLSP = lspRec->LSP->dup();
    //TODO add proper control Info for point-to-point
    Ieee802Ctrl *tmpCtrl = new Ieee802Ctrl();

    // set DSAP & NSAP fields
    tmpCtrl->setDsap(SAP_CLNS);
    tmpCtrl->setSsap(SAP_CLNS);

    //set destination broadcast address
    //It should be multicast 01-80-C2-00-00-14 MAC address, but it doesn't work in OMNeT
    MACAddress ma;
    ma.setAddress("ff:ff:ff:ff:ff:ff");
    tmpCtrl->setDest(ma);

    tmpLSP->setControlInfo(tmpCtrl);

    send(tmpLSP, "ifOut", gateIndex);


}
void ISIS::sendMyL1LSPs ( ) [private]

Flood L1 LSP packets containing whole link-state database to neighbours. Set new timer (900s) after sending.

See also:
updateMyLSP()

Definition at line 3434 of file ISIS.cc.

{
    EV << "ISIS: Warning: Running deprecated method" << endl;
    //update my own LSPs
    this->updateMyLSP();

    ISISLSPL1Packet *LSP = new ISISLSPL1Packet("L1 LSP");

    //add Ethernet controll info
    Ieee802Ctrl *ctrl = new Ieee802Ctrl();

    // set DSAP & NSAP fields
    ctrl->setDsap(SAP_CLNS);
    ctrl->setSsap(SAP_CLNS);

    //set destination broadcast address
    //It should be multicast 01-80-C2-00-00-14 MAC address, but it doesn't work in OMNeT
    MACAddress ma;
    ma.setAddress("ff:ff:ff:ff:ff:ff");
    ctrl->setDest(ma);

    //set area address TLV
    TLV_t myTLV;
    myTLV.type = AREA_ADDRESS;
    myTLV.length = ISIS_AREA_ID;
    myTLV.value = new unsigned char[ISIS_AREA_ID];
    this->copyArrayContent((unsigned char*)this->areaId, myTLV.value, 3, 0, 0);

    LSP->setTLVArraySize(1);
    LSP->setTLV(0, myTLV);

    /* - TODO Auth TLV
       - eventually implement ES neighbours TLV, but I don't think it's necessary
       - next TLVs from RFC 1195 if IP should be supported
    */

    for(unsigned int a=0; a<ISISIft.size(); a++)
    {
        if(!ISISIft.at(a).passive && ISISIft.at(a).ISISenabled && (ISISIft.at(a).circuitType == L1_TYPE || ISISIft.at(a).circuitType == L1L2_TYPE))
        {
            //flood my LSP on links
            for(unsigned int i=0; i<L1LSP.size(); i++)
            {
                //if I find LSP of my own, send it out
                if(this->compareArrays(L1LSP.at(i).LSPid, (unsigned char*)this->sysId, ISIS_SYSTEM_ID))
                {
                    ISISLSPL1Packet *LSPcopy = LSP->dup();
                    Ieee802Ctrl *ctrlCopy = ctrl->dup();
                    LSPcopy->setControlInfo(ctrlCopy);

                    //set LSP ID field
                    for(unsigned int j=0; j<LSPcopy->getLspIDArraySize(); j++)
                    {
                        LSPcopy->setLspID(j, L1LSP.at(i).LSPid[j]);
                    }

                    //set sequence number
                    LSPcopy->setSeqNumber(L1LSP.at(i).seq);


                    myTLV.type = IS_NEIGHBOURS_LSP;
                    myTLV.length = 1 + L1LSP.at(i).neighbours.size()*11;
                    myTLV.value = new unsigned char [myTLV.length];
                    myTLV.value[0] = 0;                                     //reserved byte

                    //set neighbours
                    for(unsigned int k=0; k<L1LSP.at(i).neighbours.size(); k++)
                    {
                        myTLV.value[(k*11)+1] = L1LSP.at(i).neighbours.at(k).metrics.defaultMetric;
                        myTLV.value[(k*11)+2] = L1LSP.at(i).neighbours.at(k).metrics.delayMetric;
                        myTLV.value[(k*11)+3] = L1LSP.at(i).neighbours.at(k).metrics.expenseMetric;
                        myTLV.value[(k*11)+4] = L1LSP.at(i).neighbours.at(k).metrics.errortMetric;
                        this->copyArrayContent(L1LSP.at(i).neighbours.at(k).LANid, myTLV.value, 7, 0, (k*11)+5); //set system ID
                    }

                    //assign TLV
                    LSPcopy->setTLVArraySize(2);
                    LSPcopy->setTLV(1, myTLV);

                    send(LSPcopy, "ifOut", ISISIft.at(a).gateIndex);
                }
            }
        }
    }


    //schedule refresh timer (after 900s)
    ISISTimer *timer = new ISISTimer("LSP_Refresh");
    timer->setTimerKind(LSP_REFRESH);
    scheduleAt(simTime() + 18.0, timer);//TODO

    delete LSP;
}
void ISIS::sendMyL2LSPs ( ) [private]

Not implemented yet

See also:
sendMyL1LSPs()

Definition at line 3532 of file ISIS.cc.

{
    EV << "ISIS: Warning: Running deprecated method" << endl;
    //TODO
}
void ISIS::sendPTPHelloMsg ( int  interfaceIndex,
short  circuitType 
) [private]

Definition at line 1479 of file ISIS.cc.

Referenced by sendHelloMsg().

                                                  {
    //don't send hello packets from passive interfaces
    if(ISISIft.at(k).passive || !ISISIft.at(k).ISISenabled){
        return;
    }

    /* TODO
     * They should have separate Ethernet control info but OMNeT++ simulation
     doesn't recognize 01:80:c2:00:00:14 and 01:80:c2:00:00:15 as multicast OSI
     MAC addresses. Therefore destination MAC address is always set to broadcast
     ff:ff:ff:ff:ff:ff
     */

    //TODO change to appropriate layer-2 protocol
    Ieee802Ctrl *ctrlPtp = new Ieee802Ctrl();

    // set DSAP & NSAP fields
    ctrlPtp->setDsap(SAP_CLNS);
    ctrlPtp->setSsap(SAP_CLNS);

    //set appropriate destination MAC addresses
    MACAddress ma;
    ma.setAddress("ff:ff:ff:ff:ff:ff");

    ctrlPtp->setDest(ma);

    //type
    ISISPTPHelloPacket *ptpHello = new ISISPTPHelloPacket("PTP Hello");

    //assign Ethernet control info
    ptpHello->setControlInfo(ctrlPtp);
    //circuitType
    ptpHello->setCircuitType(ISISIft.at(k).circuitType);

    //sourceID
    //set source id
    for (unsigned int i = 0; i < 6; i++)
    {
        ptpHello->setSourceID(i, sysId[i]);
    }

    //holdTime
    //set holdTime
    ptpHello->setHoldTime(this->getHoldTime(k, ISISIft.at(k).circuitType));

    //pduLength

    //localCircuitID
    ptpHello->setLocalCircuitID(ISISIft.at(k).gateIndex);

    //TLV[]
    //set TLVs
    TLV_t myTLV;

    //set area address
    myTLV.type = AREA_ADDRESS;
    myTLV.length = 3;
    myTLV.value = new unsigned char[3];
    this->copyArrayContent((unsigned char *) areaId, myTLV.value, 3, 0, 0);

    unsigned int tlvSize = ptpHello->getTLVArraySize();
    ptpHello->setTLVArraySize(tlvSize + 1);
    ptpHello->setTLV(tlvSize, myTLV);

        //ptp adjacency state TLV #240

    myTLV.type = PTP_HELLO_STATE;
    myTLV.length = 1;
    myTLV.value = new unsigned char[myTLV.length];
    ISISadj* tempAdj;
    //if adjacency for this interface exists, then its state is either UP or INIT
    //we also assumes that on point-to-point link only one adjacency can exist
    //TODO we check appropriate level adjacency table, but what to do for L1L2? In such case there's should be adjacency in both tables so we check just L1
    if ((tempAdj = this->getAdjByGateIndex(ISISIft.at(k).gateIndex, circuitType) ) != NULL)
    {
        if (!tempAdj->state)
        {
            myTLV.value[0] = PTP_INIT;
            EV << "ISIS::sendPTPHello: sending state PTP_INIT "<< endl;
        }
        else
        {
            myTLV.value[0] = PTP_UP;
            EV << "ISIS::sendPTPHello: sending state PTP_UP "<< endl;
        }

    }
    else
    {
        //if adjacency doesn't exist yet, then it's for sure down
        myTLV.value[0] = PTP_DOWN;
        EV << "ISIS::sendPTPHello: sending state PTP_DOWN "<< endl;
    }
    tlvSize = ptpHello->getTLVArraySize();
    ptpHello->setTLVArraySize(tlvSize + 1);
    ptpHello->setTLV(tlvSize, myTLV);
    //TODO TLV #129 Protocols supported


    this->send(ptpHello,"ifOut", ISISIft.at(k).gateIndex);


}
void ISIS::sendSpecificL1LSP ( unsigned char *  LSPid) [private]

Send only specific LSP to all attached neighbours.

Parameters:
LSPidID of LSP which should be flooded using LSP packets

Definition at line 6671 of file ISIS.cc.

Referenced by handleL1CSNP(), handleL1LSP(), handleL1PSNP(), and removeDeadLSP().

{
    ISISLSPL1Packet *LSP = new ISISLSPL1Packet("L1 LSP");
    //add Ethernet controll info
    Ieee802Ctrl *ctrl = new Ieee802Ctrl();

    // set DSAP & NSAP fields
    ctrl->setDsap(SAP_CLNS);
    ctrl->setSsap(SAP_CLNS);

    //set destination broadcast address
    //It should be multicast 01-80-C2-00-00-14 MAC address, but it doesn't work in OMNeT
    MACAddress ma;
    ma.setAddress("ff:ff:ff:ff:ff:ff");
    ctrl->setDest(ma);

    //set LSP ID packet field
    for(unsigned int j=0; j<LSP->getLspIDArraySize(); j++)
    {
        LSP->setLspID(j, LSPid[j]);
    }


    //set area address TLV
    TLV_t myTLV;
    myTLV.type = AREA_ADDRESS;
    myTLV.length = 3;
    myTLV.value = new unsigned char[3];
    this->copyArrayContent((unsigned char*)this->areaId, myTLV.value, 3, 0, 0);

    LSP->setTLVArraySize(1);
    LSP->setTLV(0, myTLV);

    //find LSP
    bool found = false;
    unsigned int j;
    for(j=0; j<L1LSP.size(); j++)
    {
        if(this->compareArrays(LSPid, L1LSP.at(j).LSPid, 8))
        {
            found = true;
            break;
        }
    }

    if(found)
    {

        //set sequence number
        LSP->setSeqNumber(L1LSP.at(j).seq);

        //cout << "seq: " << LSP->getSeqNumber() << endl;


        //set neighbours TLV
        myTLV.type = IS_NEIGHBOURS_LSP;
        myTLV.length = 1 + L1LSP.at(j).neighbours.size()*11;
        myTLV.value = new unsigned char [myTLV.length];
        myTLV.value[0] = 0;                                     //reserved byte

        //set neighbours
        for(unsigned int k=0; k<L1LSP.at(j).neighbours.size(); k++)
        {
            myTLV.value[(k*11)+1] = L1LSP.at(j).neighbours.at(k).metrics.defaultMetric;
            myTLV.value[(k*11)+2] = L1LSP.at(j).neighbours.at(k).metrics.delayMetric;
            myTLV.value[(k*11)+3] = L1LSP.at(j).neighbours.at(k).metrics.expenseMetric;
            myTLV.value[(k*11)+4] = L1LSP.at(j).neighbours.at(k).metrics.errortMetric;
            this->copyArrayContent(L1LSP.at(j).neighbours.at(k).LANid, myTLV.value, 7, 0, (k*11)+5); //set LAN ID
        }

        LSP->setTLVArraySize(2);
        LSP->setTLV(1, myTLV);

        /* - TODO Auth TLV
           - eventually implement ES neighbours TLV, but I don't think it's necessary
           - next TLVs from RFC 1195 if IP should be supported
        */

        for(unsigned int a=0; a<ISISIft.size(); a++)
        {
            if(!ISISIft.at(a).passive && ISISIft.at(a).ISISenabled && (ISISIft.at(a).circuitType == L1_TYPE || ISISIft.at(a).circuitType == L1L2_TYPE))
            {
                ISISLSPL1Packet *LSPcopy = LSP->dup();
                Ieee802Ctrl *ctrlCopy = ctrl->dup();
                LSPcopy->setControlInfo(ctrlCopy);
                send(LSPcopy, "ifOut", ISISIft.at(a).gateIndex);
            }
        }
    }
    //cleanup
    delete LSP;
}
void ISIS::setLspID ( ISISLSPPacket msg,
unsigned char *  lspID 
) [private]

Definition at line 2772 of file ISIS.cc.

Referenced by genLSP(), handleL1Csnp(), and handleL1Psnp().

                                                            {

    for (int i = 0; i < ISIS_SYSTEM_ID + 2; i++)
    {
       msg->setLspID(i, lspId[i]);
    }

}
void ISIS::setSRMflag ( LSPRecord lspRec,
int  index,
short  circuitType 
) [private]

Definition at line 5854 of file ISIS.cc.

Referenced by clearSRMflagsBut(), handleL1Csnp(), handleL1Lsp(), handleL1Psnp(), purgeLSP(), setSRMflags(), and setSRMflagsBut().

{
    ISISinterface * iface = &(this->ISISIft.at(index));
    std::vector<FlagRecord*> *SRMQueue = this->getSRMQ(iface->network, index, circuitType);
    if(lspRec->SRMflags.size() == 0 ){
        this->addFlags(lspRec, circuitType);
    }
    /* This should prevent from adding multiple FlagRecord for the same LSP-gateIndex pair */
    if(lspRec->SRMflags.at(index) == true){
        return;
    }

    //set SRMflag on interface only if there is  at least one adjacency UP
    if (this->isUp(index, circuitType))
    {
        lspRec->SRMflags.at(index) = true; //setting true (Send Routing Message) on every interface
        FlagRecord *tmpSRMRec = new FlagRecord;
        tmpSRMRec->lspRec = lspRec;
        tmpSRMRec->index = index;
        SRMQueue->push_back(tmpSRMRec);
        /*
        if (this->ISISIft.at(index).network)
        {
            //TODO how do you know it's L1 and not L2
            this->L1SRMBQueue->at(index)->push_back(tmpSRMRec);
        }
        else
        {
            this->L1SRMPTPQueue->at(index)->push_back(tmpSRMRec);
        }*/
    }

}
void ISIS::setSRMflags ( LSPRecord lspRec,
short  circuitType 
) [private]

Definition at line 5888 of file ISIS.cc.

Referenced by handleL1Lsp(), installLSP(), purgeLSP(), refreshLSP(), and replaceLSP().

{
    if(lspRec->SRMflags.size() == 0 ){
        this->addFlags(lspRec, circuitType);
    }
    for (unsigned int i = 0; i < lspRec->SRMflags.size(); i++)
    {
        this->setSRMflag(lspRec, i, circuitType);
    }

}
void ISIS::setSRMflagsBut ( LSPRecord lspRec,
unsigned int  index,
short  circuitType 
) [private]

Definition at line 5900 of file ISIS.cc.

Referenced by installLSP(), and replaceLSP().

{
    if(lspRec->SRMflags.size() == 0 ){
        this->addFlags(lspRec, circuitType);
    }
    for (unsigned int i = 0; i < lspRec->SRMflags.size(); i++)
    {
        if(i == index){
            this->clearSRMflag(lspRec, i, circuitType);
        }else{
            this->setSRMflag(lspRec, i, circuitType);
        }
    }

}
void ISIS::setSSNflag ( LSPRecord lspRec,
int  index,
short  circuitType 
) [private]

Definition at line 5987 of file ISIS.cc.

Referenced by clearSSNflagsBut(), handleL1Csnp(), handleL1Lsp(), handleL1Psnp(), installLSP(), purgeLSP(), replaceLSP(), setSSNflags(), and setSSNflagsBut().

{

    ISISinterface * iface = &(this->ISISIft.at(index));
        std::vector<FlagRecord*> *SSNQueue = this->getSSNQ(iface->network, index, circuitType);

    if (lspRec->SSNflags.size() == 0)
        {
            this->addFlags(lspRec, circuitType);
        }

    /* This should prevent from adding multiple FlagRecord for the same LSP-gateIndex pair */
     if(lspRec->SSNflags.at(index) == true){
         return;
     }
    //set SSNflag on interface only if there is  at least one adjacency UP
    if (this->isUp(index, circuitType))
    {

        lspRec->SSNflags.at(index) = true; //setting true (Send Routing Message) on every interface
        FlagRecord *tmpSSNRec = new FlagRecord;
        tmpSSNRec->lspRec = lspRec;
        tmpSSNRec->index = index;
        SSNQueue->push_back(tmpSSNRec);
//        if (this->ISISIft.at(index).network)
//        {
//            this->L1SSNBQueue->at(index)->push_back(tmpSSNRec);
//        }
//        else
//        {
//            this->L1SSNPTPQueue->at(index)->push_back(tmpSSNRec);
//        }
    }

}
void ISIS::setSSNflags ( LSPRecord lspRec,
short  circuitType 
) [private]

Definition at line 6023 of file ISIS.cc.

{
    if (lspRec->SSNflags.size() == 0)
    {
        this->addFlags(lspRec, circuitType);
    }

    for (unsigned int i = 0; i < lspRec->SSNflags.size(); i++)
    {
        this->setSSNflag(lspRec, i, circuitType);
    }

}
void ISIS::setSSNflagsBut ( LSPRecord lspRec,
unsigned int  index,
short  circuitType 
) [private]

Definition at line 6037 of file ISIS.cc.

{
    if(lspRec->SSNflags.size() == 0 ){
        this->addFlags(lspRec, circuitType);
    }
    for (unsigned int i = 0; i < lspRec->SSNflags.size(); i++)
    {
        if(i == index){
            this->clearSSNflag(lspRec, i, circuitType);
        }else{
            this->setSSNflag(lspRec, i, circuitType);
        }
    }

}
void ISIS::twoWayCheck ( ISISCons_t cons) [private]

Definition at line 7801 of file ISIS.cc.

Referenced by extractISO().

                                      {
    ISISCons_t *tmpCons;
    for(ISISCons_t::iterator it = cons->begin(); it != cons->end(); ){
        //if there is not reverse connection
        //TODO is this enough? there could be two one-way connections between two ISs
        if(!this->isCon(cons, (*it)->to, (*it)->from)){
            it = cons->erase(it);
        }else{
            ++it;
        }
    }
}
void ISIS::updateLSP ( ISISLSPPacket lsp,
short  circuitType 
) [private]

Definition at line 3875 of file ISIS.cc.

                                                         {

    unsigned char *lspId;
    LSPRecord * tmpLSPRecord;
        lspId = this->getLspID(lsp);
    if((tmpLSPRecord = this->getLSPFromDbByID(lspId, circuitType)) == NULL){
        //installLSP
    }else{
        //we have that LSP
    }
}
void ISIS::updateMyLSP ( ) [private]

Create or update my own LSP.

See also:
ISIS::sendMyL1LSPs()

Definition at line 6369 of file ISIS.cc.

Referenced by sendMyL1LSPs().

{
    unsigned char myLSPid[8];

    //at first, we generate (or update existing) non-psudonode LSP with pesudonode ID (myLSPid[6]) equal to 0 according to ISO10859
    //myLSPid[7] is always 0 because omnet doesn't support packet fragmentation (or I don't want to solve that :D)
    this->copyArrayContent((unsigned char*)this->sysId, myLSPid, 6, 0, 0);
    myLSPid[6] = 0; myLSPid[7] = 0;


    bool found = false;

    //we try to find existing LSP with this ID
    for(unsigned int j=0; j<L1LSP.size(); j++)
    {
        //if we have found matching LSP ID
        if(this->compareArrays(myLSPid, L1LSP.at(j).LSPid, 8))
        {
            //update it

            //increment sequence number
            L1LSP.at(j).seq++;

            //reset dead timer
            cancelEvent(L1LSP.at(j).deadTimer);
            scheduleAt(simTime() + 50, L1LSP.at(j).deadTimer);   //should be 1200 secs.

            //set neighbours (pseudonode neighbours)
            std::vector<LSPneighbour> neighbours;

            //as we are using ethernet, which is multiaccess medium, we have to add pseudonodes as IS neighbours
            //at this point, network should be converged and assigned appropriate designated IS for each LAN

            for(unsigned int i=0; i<ISISIft.size(); i++)
            {
                if(ISISIft.at(i).ISISenabled && (ISISIft.at(i).circuitType == L1_TYPE || ISISIft.at(i).circuitType == L1L2_TYPE))
                {
                    LSPneighbour neighbour;
                    ISISadj *tmpAdj = this->getAdjByGateIndex(ISISIft.at(i).gateIndex, L1_TYPE);
                    //if there's not adjacency in state "UP" for specified interface, then skip this interface
                    if(tmpAdj == NULL || !tmpAdj->state){
                        continue;
                    }
                    //for broadcast network use DIS's System-ID
                    if (ISISIft.at(i).network)
                    {
                        this->copyArrayContent(ISISIft.at(i).L1DIS, neighbour.LANid, 7, 0, 0);
                    }
                    else
                        //for point-to-point links use actual System-ID padded with 0 byte
                    {
                        this->copyArrayContent(tmpAdj->sysID, neighbour.LANid, ISIS_SYSTEM_ID, 0, 0);
                        neighbour.LANid[ISIS_SYSTEM_ID] = 0;
                    }

                    //find interface which is DIS connected to and set metrics
                    neighbour.metrics.defaultMetric = ISISIft.at(i).metric;     //default = 10
                    neighbour.metrics.delayMetric = 128;    //disabled;
                    neighbour.metrics.expenseMetric = 128;  //disabled
                    neighbour.metrics.errortMetric = 128;   //disabled

                    neighbours.push_back(neighbour);
                }
            }

            //replace old neighbours
            L1LSP.at(j).neighbours = neighbours;


            found = true;
            break;
        }
    }

    //if LSP record doesn't exist, create it
    if(!found)
    {
        LSPrecord record;

        //set LSP ID
        this->copyArrayContent(myLSPid, record.LSPid, 8, 0, 0);

        //set dead timer
        record.deadTimer = new ISISTimer("L1 LSP dead");
        record.deadTimer->setTimerKind(LSP_DEAD);
        for(unsigned int x = 0; x < record.deadTimer->getLSPidArraySize(); x++)
        {
            record.deadTimer->setLSPid(x, myLSPid[x]);
        }
        scheduleAt(simTime() + 50.0, record.deadTimer);//TODO

        //initial sequence number = 1
        record.seq = 1;

        //set pseudonode neighbours
        std::vector<LSPneighbour> neighbours;

        for(unsigned int i=0; i<ISISIft.size(); i++)
        {
            if(ISISIft.at(i).ISISenabled && (ISISIft.at(i).circuitType == L1_TYPE || ISISIft.at(i).circuitType == L1L2_TYPE))
            {
                for(unsigned int f=0; f< this->adjL1Table.size(); f++)
                {
                    if(ISISIft.at(i).gateIndex == adjL1Table.at(f).gateIndex && adjL1Table.at(f).state)
                    {
                        LSPneighbour neighbour;
                        if(ISISIft.at(i).network){
                            this->copyArrayContent(ISISIft.at(i).L1DIS, neighbour.LANid, 7, 0, 0);
                        }else{
                            this->copyArrayContent(this->adjL1Table.at(f).sysID, neighbour.LANid, ISIS_SYSTEM_ID, 0, 0);
                            neighbour.LANid[6]=0;

                        }

                        //find interface which is DIS connected to and set metrics
                        neighbour.metrics.defaultMetric = ISISIft.at(i).metric;     //default = 10
                        neighbour.metrics.delayMetric = 128;    //disabled;
                        neighbour.metrics.expenseMetric = 128;  //disabled
                        neighbour.metrics.errortMetric = 128;   //disabled

                        neighbours.push_back(neighbour);
                        break;
                    }
                }
            }
        }

        if(neighbours.size() > 0)
        {
            record.neighbours = neighbours;
            L1LSP.push_back(record);
        }
     }


    //end of non-pseudonode LSP
    //####################################################################################################
    //start of pseudonode LSP

    for(unsigned int i=0; i<ISISIft.size(); i++)
    {
        //check if this interface is DIS for LAN AND if it is broadcast interface
        if(this->compareArrays((unsigned char*) this->sysId, ISISIft.at(i).L1DIS, 6) && ISISIft.at(i).network)
        {
            //check if LSP ID exists; update neighbours if record exists; create new record otherwise
            //I have already my system id contained in myLSPid; we have to set only pseudonode ID byte

            found = false;
            myLSPid[6] = ISISIft.at(i).L1DIS[6];
            for(unsigned int j=0; j< L1LSP.size(); j++)
            {
                //we found the match
                if(this->compareArrays(myLSPid, L1LSP.at(j).LSPid, 8))
                {

                    //update sequence number
                    L1LSP.at(j).seq++;

                    //reset dead timer
                    cancelEvent(L1LSP.at(j).deadTimer);
                    scheduleAt(simTime() + 50, L1LSP.at(j).deadTimer);   //should be 1200 secs.

                    //set neighbours (NON-pseudonode neighbours)
                    std::vector<LSPneighbour> neighbours;

                    //set every adjacent IS as neighbour
                    for(unsigned int k=0; k<adjL1Table.size(); k++)
                    {
                        //consider only directly connected neighbours in "UP" state
                        if(adjL1Table.at(k).state && adjL1Table.at(k).gateIndex == ISISIft.at(i).gateIndex)
                        {
                            LSPneighbour neighbour;
                            this->copyArrayContent(adjL1Table.at(k).sysID, neighbour.LANid, 6, 0, 0);
                            neighbour.LANid[6] = 0;
                            neighbour.metrics.defaultMetric = 0;     //metric to every neighbour in pseudonode LSP is always zero!!!
                            neighbour.metrics.delayMetric = 128;    //disabled;
                            neighbour.metrics.expenseMetric = 128;  //disabled
                            neighbour.metrics.errortMetric = 128;   //disabled

                            neighbours.push_back(neighbour);
                        }
                    }

                    //add also mine non-pseudonode interface as neighbour
                    LSPneighbour neighbour;
                    this->copyArrayContent((unsigned char*)this->sysId, neighbour.LANid, 6, 0, 0);
                    neighbour.LANid[6] = 0;
                    neighbour.metrics.defaultMetric = 0;     //metric to every neighbour in pseudonode LSP is always zero!!!
                    neighbour.metrics.delayMetric = 128;    //disabled;
                    neighbour.metrics.expenseMetric = 128;  //disabled
                    neighbour.metrics.errortMetric = 128;   //disabled

                    neighbours.push_back(neighbour);

                    //replace old neighbours
                    L1LSP.at(j).neighbours = neighbours;

                    found = true;
                    break;
                }
            }


            //create new pseudonode LSP record
            if(!found)
            {
                LSPrecord record;

                //set LSP ID
                this->copyArrayContent(myLSPid, record.LSPid, 8, 0, 0);

                //set dead timer
                record.deadTimer = new ISISTimer("L1 LSP dead");
                record.deadTimer->setTimerKind(LSP_DEAD);
                for(unsigned int x=0; x<record.deadTimer->getLSPidArraySize(); x++)
                {
                    record.deadTimer->setLSPid(x, myLSPid[x]);
                }
                scheduleAt(simTime() + 50.0, record.deadTimer);

                //initial sequence number = 1
                record.seq = 1;

                //set neighbours (NON-pseudonode neighbours)
                std::vector<LSPneighbour> neighbours;


                //set every adjacent IS as neighbour
                for(unsigned int k=0; k<adjL1Table.size(); k++)
                {
                    //consider only directly connected neighbours in "UP" state
                    if(adjL1Table.at(k).state && adjL1Table.at(k).gateIndex == ISISIft.at(i).gateIndex)
                    {
                        LSPneighbour neighbour;
                        this->copyArrayContent(adjL1Table.at(k).sysID, neighbour.LANid, 6, 0, 0);
                        neighbour.LANid[6] = 0;
                        neighbour.metrics.defaultMetric = 0;     //metric to every neighbour in pseudonode LSP is always zero!!!
                        neighbour.metrics.delayMetric = 128;    //disabled;
                        neighbour.metrics.expenseMetric = 128;  //disabled
                        neighbour.metrics.errortMetric = 128;   //disabled

                        neighbours.push_back(neighbour);
                    }
                }

                if(neighbours.size() > 0)
                {
                    //add also mine non-pseudonode interface as neighbour
                    LSPneighbour neighbour;
                    this->copyArrayContent((unsigned char*)this->sysId, neighbour.LANid, 6, 0, 0);
                    neighbour.LANid[6] = 0;
                    neighbour.metrics.defaultMetric = 0;     //metric to every neighbour in pseudonode LSP is always zero!!!
                    neighbour.metrics.delayMetric = 128;    //disabled;
                    neighbour.metrics.expenseMetric = 128;  //disabled
                    neighbour.metrics.errortMetric = 128;   //disabled

                    neighbours.push_back(neighbour);

                    record.neighbours = neighbours;

                    //replace old neighbours
                    L1LSP.push_back(record);
                }
            }
        }
    }
}

Member Data Documentation

const char* ISIS::configFile [private]

config file specified in simulation

Definition at line 60 of file ISIS.h.

Referenced by initialize().

const char* ISIS::deviceType [private]

device type specified in .ned when using this module

Definition at line 58 of file ISIS.h.

Referenced by initialize().

unsigned long ISIS::helloCounter [private]

my hax hello counter to sync DIS/non-DIS hellos. This variable is deprecated, but is kept for sentimental reasons.

Definition at line 105 of file ISIS.h.

pointer to interface table

Definition at line 56 of file ISIS.h.

Referenced by initialize().

short ISIS::isType [private]

defines router IS-IS operational mode (L1,L2,L1L2)

Definition at line 67 of file ISIS.h.

Referenced by generateLSP(), initGenerate(), initialize(), initPeriodicSend(), initRefresh(), initSPF(), insertIft(), and refreshLSP().

int ISIS::L1CsnpInterval [private]

Interval in seconds between generating CSNP message.

Definition at line 99 of file ISIS.h.

Referenced by initialize(), and schedule().

int ISIS::L1HelloInterval [private]

Hello interval for Level 1, 1 - 65535, 0 value causes the system to compute the hello interval based on the hello multiplier (specified by the L1HelloMultiplier ) so that the resulting hold time is 1 second. On designated intermediate system (DIS) interfaces, only one third of the configured value is used. Default is 10.

Definition at line 86 of file ISIS.h.

Referenced by initialize(), and insertIft().

short ISIS::L1HelloMultiplier [private]

Value between 3 - 1000. The advertised hold time in IS-IS hello packets will be set to the L1HelloMultiplier times the L1HelloInterval. Default is 3.

Definition at line 88 of file ISIS.h.

Referenced by initialize(), and insertIft().

std::vector<LSPrecord> ISIS::L1LSP [private]

L1 LSP database

Definition at line 68 of file ISIS.h.

Referenced by handleL1CSNP(), handleL1LSP(), removeDeadLSP(), sendL1CSNP(), sendMyL1LSPs(), sendSpecificL1LSP(), and updateMyLSP().

L1 LSP database

Definition at line 70 of file ISIS.h.

Referenced by getLSPDb(), ISIS(), and ~ISIS().

int ISIS::L1LspGenInterval [private]

Interval in seconds at which LSPs are generated.

Definition at line 93 of file ISIS.h.

Referenced by initialize(), and schedule().

int ISIS::L1LspInitWait [private]

Initial wait interval in ms before generating first LSP.

Definition at line 97 of file ISIS.h.

Referenced by initialize(), and schedule().

int ISIS::L1LspSendInterval [private]

Interval in seconds at which LSPs (with SRMflag set) are transmitted.

Definition at line 95 of file ISIS.h.

Referenced by initialize(), and schedule().

int ISIS::L1PsnpInterval [private]

Interval in seconds between generating PSNP message.

Definition at line 101 of file ISIS.h.

Referenced by initialize(), and schedule().

int ISIS::L1SPFFullInterval [private]

Definition at line 103 of file ISIS.h.

Referenced by initialize(), and schedule().

Vector with vector for each interface containing LSPRecords with SRMflag set

Definition at line 72 of file ISIS.h.

Referenced by getSRMBQueue(), getSRMQ(), initialize(), ISIS(), and ~ISIS().

Definition at line 73 of file ISIS.h.

Referenced by getSRMPTPQueue(), getSRMQ(), initialize(), ISIS(), and ~ISIS().

Vector with vector for each interface containing LSPRecords with SSNflag set

Definition at line 77 of file ISIS.h.

Referenced by getSSNBQueue(), getSSNQ(), initialize(), ISIS(), and ~ISIS().

Definition at line 78 of file ISIS.h.

Referenced by getSSNPTPQueue(), getSSNQ(), initialize(), ISIS(), and ~ISIS().

int ISIS::L2CsnpInterval [private]

Interval in seconds between generating CSNP message.

Definition at line 100 of file ISIS.h.

Referenced by initialize(), and schedule().

int ISIS::L2HelloInterval [private]

Hello interval for Level 1, 1 - 65535, 0 value causes the system to compute the hello interval based on the hello multiplier (specified by the L2HelloMultiplier ) so that the resulting hold time is 1 second. On designated intermediate system (DIS) interfaces, only one third of the configured value is used. Default is 10.

Definition at line 87 of file ISIS.h.

Referenced by initialize(), and insertIft().

short ISIS::L2HelloMultiplier [private]

Value between 3 - 1000. The advertised hold time in IS-IS hello packets will be set to the L2HelloMultiplier times the L2HelloInterval. Default is 3.

Definition at line 89 of file ISIS.h.

Referenced by initialize(), and insertIft().

std::vector<LSPrecord> ISIS::L2LSP [private]

L2 LSP database

Definition at line 69 of file ISIS.h.

L2 LSP database

Definition at line 71 of file ISIS.h.

Referenced by getLSPDb(), ISIS(), and ~ISIS().

int ISIS::L2LspGenInterval [private]

Interval in seconds at which LSPs are generated.

Definition at line 94 of file ISIS.h.

Referenced by initialize(), and schedule().

int ISIS::L2LspInitWait [private]

Initial wait interval in ms before generating first LSP.

Definition at line 98 of file ISIS.h.

Referenced by initialize(), and schedule().

int ISIS::L2LspSendInterval [private]

Interval in seconds at which LSPs (with SRMflag set) are transmitted.

Definition at line 96 of file ISIS.h.

Referenced by initialize(), and schedule().

int ISIS::L2PsnpInterval [private]

Interval in seconds between generating PSNP message.

Definition at line 102 of file ISIS.h.

Referenced by initialize(), and schedule().

int ISIS::L2SPFFullInterval [private]

Definition at line 104 of file ISIS.h.

Referenced by initialize(), and schedule().

Vector with vector for each interface containing LSPRecords with SRMflag set

Definition at line 74 of file ISIS.h.

Referenced by getSRMBQueue(), getSRMQ(), initialize(), ISIS(), and ~ISIS().

Definition at line 75 of file ISIS.h.

Referenced by getSRMPTPQueue(), getSRMQ(), initialize(), ISIS(), and ~ISIS().

Vector with vector for each interface containing LSPRecords with SSNflag set

Definition at line 79 of file ISIS.h.

Referenced by getSSNBQueue(), getSSNQ(), initialize(), ISIS(), and ~ISIS().

Definition at line 80 of file ISIS.h.

Referenced by getSSNPTPQueue(), getSSNQ(), initialize(), ISIS(), and ~ISIS().

int ISIS::lspInterval [private]

Minimum delay in ms between sending two successive LSPs.

Definition at line 90 of file ISIS.h.

Referenced by initialize().

int ISIS::lspMaxLifetime [private]

Interval in seconds during which is specified LSP valid. This value SHOULD be more than ISIS_LSP_REFRESH_INTERVAL

Definition at line 92 of file ISIS.h.

Referenced by genLSP(), initialize(), refreshLSP(), and schedule().

int ISIS::lspRefreshInterval [private]

Interval in seconds in at which LSPs are refreshed (1 to 65535). This value SHOULD be less than ISIS_LSP_MAX_LIFETIME

Definition at line 91 of file ISIS.h.

Referenced by initialize(), and schedule().

const char* ISIS::netAddr [private]

OSI network address in simplified NSAP format

Definition at line 61 of file ISIS.h.

Referenced by initialize(), and parseNetAddr().

const unsigned char* ISIS::NSEL [private]

last 1Byte of Netaddr as NSEL identifier

Definition at line 64 of file ISIS.h.

Referenced by parseNetAddr(), printAdjTable(), printLSPDB(), and printPaths().


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