NicEntryDebug.cc

00001 /* -*- mode:c++ -*- ********************************************************
00002  * file:        NicEntryDebug.cc
00003  *
00004  * author:      Daniel Willkomm
00005  *
00006  * copyright:   (C) 2005 Telecommunication Networks Group (TKN) at
00007  *              Technische Universitaet Berlin, Germany.
00008  *
00009  *              This program is free software; you can redistribute it
00010  *              and/or modify it under the terms of the GNU General Public
00011  *              License as published by the Free Software Foundation; either
00012  *              version 2 of the License, or (at your option) any later
00013  *              version.
00014  *              For further information see file COPYING
00015  *              in the top level directory
00016  ***************************************************************************
00017  * part of:     framework implementation developed by tkn
00018  * description: Class to store information about a nic for the
00019  *              ConnectionManager module
00020  **************************************************************************/
00021 
00022 #include "NicEntryDebug.h"
00023 #include "ChannelAccess.h"
00024 
00025 #include <cassert>
00026 
00027 #ifndef nicEV
00028 #define nicEV (ev.isDisabled()||!coreDebug) ? ev : ev << "NicEntry: "
00029 #endif
00030 
00031 
00032 void NicEntryDebug::connectTo(NicEntry* other) {
00033   nicEV<<"connecting nic #"<<nicId<< " and #"<<other->nicId<<endl;
00034 
00035   NicEntryDebug* otherNic = (NicEntryDebug*) other;
00036 
00037   cGate *localoutgate = requestOutGate();
00038   localoutgate->connectTo(otherNic->requestInGate());
00039   outConns[other] = localoutgate->getPathStartGate();
00040 }
00041 
00042 
00043 void NicEntryDebug::disconnectFrom(NicEntry* other) {
00044   nicEV<<"disconnecting nic #"<<nicId<< " and #"<<other->nicId<<endl;
00045 
00046   NicEntryDebug* otherNic = (NicEntryDebug*) other;
00047 
00048   //search the connection in the outConns list
00049   GateList::iterator p = outConns.find(other);
00050   //no need to check whether entry is valid; is already check by ConnectionManager isConnected
00051   //get the hostGate
00052   //order is phyGate->nicGate->hostGate
00053   cGate* hostGate = p->second->getNextGate()->getNextGate();
00054 
00055   // release local out gate
00056   freeOutGates.push_back(hostGate);
00057 
00058   // release remote in gate
00059   otherNic->freeInGates.push_back(hostGate->getNextGate());
00060 
00061   //reset gates
00062   //hostGate->getNextGate()->connectTo(0);
00063   hostGate->disconnect();
00064 
00065   //delete the connection
00066   outConns.erase(p);
00067 }
00068 
00069 int NicEntryDebug::collectGates(const char* pattern, GateStack& gates)
00070 {
00071   cModule* host = nicPtr->getParentModule();
00072   int i = 1;
00073   char gateName[20];
00074   //create the unique name for the gate (composed of the nic module id and a counter)
00075   sprintf(gateName, pattern, nicId, i);
00076   while(host->hasGate(gateName))
00077   {
00078     cGate* hostGate = host->gate(gateName);
00079     if(hostGate->isConnectedOutside()) {
00080       opp_error("Gate %s is still connected but not registered with this "
00081             "NicEntry. Either the last NicEntry for this NIC did not "
00082             "clean up correctly or another gate creation module is "
00083             "interfering with this one!", gateName);
00084     }
00085     assert(hostGate->isConnectedInside());
00086     gates.push_back(hostGate);
00087 
00088     ++i;
00089     sprintf(gateName, pattern, nicId, i);
00090   }
00091 
00092   return i - 1;
00093 }
00094 
00095 void NicEntryDebug::collectFreeGates()
00096 {
00097   if(!checkFreeGates)
00098     return;
00099 
00100   inCnt = collectGates("in%d-%d", freeInGates);
00101   nicEV << "found " << inCnt << " already existing usable in-gates." << endl;
00102 
00103 
00104   outCnt = collectGates("out%d-%d", freeOutGates);
00105   nicEV << "found " << inCnt << " already existing usable out-gates." << endl;
00106 
00107   checkFreeGates = false;
00108 }
00109 
00110 
00111 cGate* NicEntryDebug::requestInGate(void) {
00112   collectFreeGates();
00113 
00114   // gate of the host
00115   cGate *hostGate;
00116 
00117   if (!freeInGates.empty()) {
00118     hostGate = freeInGates.back();
00119     freeInGates.pop_back();
00120   } else {
00121     char gateName[20];
00122 
00123     // we will have one more in gate
00124     ++inCnt;
00125 
00126     //get a unique name for the gate (composed of the nic module id and a counter)
00127     sprintf(gateName, "in%d-%d", nicId, inCnt);
00128 
00129     // create a new gate for the host module
00130     nicPtr->getParentModule()->addGate(gateName, cGate::INPUT);
00131     hostGate = nicPtr->getParentModule()->gate(gateName);
00132 
00133     // gate of the nic
00134     cGate *nicGate;
00135 
00136     // create a new gate for the nic module
00137     nicPtr->addGate(gateName, cGate::INPUT);
00138     nicGate = nicPtr->gate(gateName);
00139 
00140     // connect the hist gate with the nic gate
00141     hostGate->connectTo(nicGate);
00142 
00143     // pointer to the phy module
00144     ChannelAccess* phyModule;
00145     // gate of the phy module
00146     cGate *phyGate;
00147 
00148     // to avoid unnecessary dynamic_casting we check for a "phy"-named submodule first
00149     if ((phyModule = static_cast<ChannelAccess *> (nicPtr->getSubmodule("phy"))) == NULL)
00150       phyModule = FindModule<ChannelAccess*>::findSubModule(nicPtr);
00151     assert(phyModule != 0);
00152 
00153     // create a new gate for the phy module
00154     phyModule->addGate(gateName, cGate::INPUT);
00155     phyGate = phyModule->gate(gateName);
00156 
00157     // connect the nic gate (the gate of the compound module) to
00158     // a "real" gate -- the gate of the phy module
00159     nicGate->connectTo(phyGate);
00160   }
00161 
00162   return hostGate;
00163 }
00164 
00165 cGate* NicEntryDebug::requestOutGate(void) {
00166   collectFreeGates();
00167 
00168   // gate of the host
00169   cGate *hostGate;
00170 
00171   if (!freeOutGates.empty()) {
00172     hostGate = freeOutGates.back();
00173     freeOutGates.pop_back();
00174   } else {
00175     char gateName[20];
00176 
00177     // we will have one more out gate
00178     ++outCnt;
00179 
00180     //get a unique name for the gate (composed of the nic module id and a counter)
00181     sprintf(gateName, "out%d-%d", nicId, outCnt);
00182 
00183     // create a new gate for the host module
00184     nicPtr->getParentModule()->addGate(gateName, cGate::OUTPUT);
00185     hostGate = nicPtr->getParentModule()->gate(gateName);
00186 
00187     // gate of the nic
00188     cGate *nicGate;
00189     // create a new gate for the nic module
00190     nicPtr->addGate(gateName, cGate::OUTPUT);
00191     nicGate = nicPtr->gate(gateName);
00192 
00193     // connect the hist gate with the nic gate
00194     nicGate->connectTo(hostGate);
00195 
00196     // pointer to the phy module
00197     ChannelAccess* phyModule;
00198     // gate of the phy module
00199     cGate *phyGate;
00200 
00201     // to avoid unnecessary dynamic_casting we check for a "phy"-named submodule first
00202     if ((phyModule = static_cast<ChannelAccess *> (nicPtr->getSubmodule("phy"))) == NULL)
00203       phyModule = FindModule<ChannelAccess*>::findSubModule(nicPtr);
00204     assert(phyModule != 0);
00205 
00206     // create a new gate for the phy module
00207     phyModule->addGate(gateName, cGate::OUTPUT);
00208     phyGate = phyModule->gate(gateName);
00209 
00210     // connect the nic gate (the gate of the compound module) to
00211     // a "real" gate -- the gate of the phy module
00212     phyGate->connectTo(nicGate);
00213   }
00214 
00215   return hostGate;
00216 }