FailureManager.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2005 Vojtech Janota
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser General Public License
00015 // along with this program; if not, see <http://www.gnu.org/licenses/>.
00016 //
00017 
00018 #include "FailureManager.h"
00019 
00020 Define_Module(FailureManager);
00021 
00022 void FailureManager::initialize()
00023 {
00024     // so far no initialization
00025 }
00026 
00027 void FailureManager::handleMessage(cMessage *msg)
00028 {
00029     ASSERT(false);
00030 }
00031 
00032 cModule *FailureManager::getTargetNode(const char *target)
00033 {
00034     cModule *mod = simulation.getModuleByPath(target);
00035     ASSERT(mod);
00036     return mod;
00037 }
00038 
00039 void FailureManager::processCommand(const cXMLElement& node)
00040 {
00041     cModule *target = getTargetNode(node.getAttribute("target"));
00042 
00043     if (!strcmp(node.getTagName(), "shutdown"))
00044     {
00045         target->getDisplayString().setTagArg("i2",0,"status/cross");
00046         if(!strcmp(target->getModuleType()->getName(), "RSVP_LSR"))
00047             replaceNode(target, "inet.nodes.mpls.RSVP_FAILED");
00048         else if(!strcmp(target->getModuleType()->getName(), "LDP_LSR"))
00049             replaceNode(target, "inet.nodes.mpls.LDP_FAILED");
00050         else
00051             ASSERT(false);
00052     }
00053     else if(!strcmp(node.getTagName(), "startup"))
00054     {
00055         target->getDisplayString().removeTag("i2");
00056         if(!strcmp(target->getModuleType()->getName(), "RSVP_FAILED"))
00057             replaceNode(target, "inet.nodes.mpls.RSVP_LSR");
00058         else if(!strcmp(target->getModuleType()->getName(), "LDP_FAILED"))
00059             replaceNode(target, "inet.nodes.mpls.LDP_LSR");
00060         else
00061             ASSERT(false);
00062     }
00063     else
00064         ASSERT(false);
00065 
00066 }
00067 
00068 void FailureManager::replaceNode(cModule *mod, const char *newNodeType)
00069 {
00070     ASSERT(mod);
00071 
00072     cModuleType *nodeType = cModuleType::find(newNodeType);
00073     if (!nodeType)
00074         error("Cannot replace module `%s' with a module of type `%s': No such module type", mod->getFullPath().c_str(), newNodeType);
00075 
00076     cModule *nodeMod = nodeType->create(mod->getName(), simulation.getSystemModule());
00077     ASSERT(nodeMod);
00078 
00079     reconnectNode(mod, nodeMod);
00080     delete mod;
00081 
00082     nodeMod->buildInside();
00083     nodeMod->scheduleStart(simTime());
00084     nodeMod->callInitialize();
00085 }
00086 
00087 void FailureManager::reconnectNode(cModule *old, cModule *n)
00088 {
00089     copyParams(old, n);
00090     n->finalizeParameters();
00091     n->setDisplayString(old->getDisplayString().str());
00092 
00093     reconnectAllGates(old, n);
00094 }
00095 
00096 void FailureManager::reconnectAllGates(cModule *old, cModule *n)
00097 {
00098     std::vector<const char*> gateNames = old->getGateNames();
00099     for (std::vector<const char*>::const_iterator it=gateNames.begin(); it!=gateNames.end(); ++it)
00100     {
00101         const char* gateName = *it;
00102         if (old->isGateVector(gateName))
00103         {
00104             unsigned int size = old->gateSize(gateName);
00105             n->setGateSize(gateName, size);
00106             for (unsigned int i = 0; i < size; i++)
00107                 reconnectGates(old, n, gateName, i);
00108         }
00109         else
00110         {
00111             reconnectGates(old, n, gateName);
00112         }
00113     }
00114 }
00115 
00116 void FailureManager::reconnectGates(cModule *old, cModule *n, const char *gateName, int gateIndex)
00117 {
00118     cGate::Type gateType = old->gateType(gateName);
00119     if (gateType == cGate::INOUT)
00120     {
00121         std::string ingateName = (std::string(gateName)+"$i");
00122         std::string outgateName = (std::string(gateName)+"$o");
00123         reconnectGate(old->gate(ingateName.c_str(), gateIndex), n->gate(ingateName.c_str(), gateIndex));
00124         reconnectGate(old->gate(outgateName.c_str(), gateIndex), n->gate(outgateName.c_str(), gateIndex));
00125     }
00126     else
00127     {
00128         reconnectGate(old->gate(gateName, gateIndex), n->gate(gateName, gateIndex));
00129     }
00130 }
00131 
00132 void FailureManager::reconnectGate(cGate *oldGate, cGate *newGate)
00133 {
00134     cGate::Type gateType = oldGate->getType();
00135     if (gateType == cGate::OUTPUT)
00136     {
00137         if(oldGate->isConnected())
00138         {
00139             cGate *to = oldGate->getNextGate();
00140             cChannel *ch = copyChannel(oldGate->getChannel());
00141             std::string displayString = oldGate->getChannel()->getDisplayString().str();
00142             oldGate->disconnect();
00143             newGate->connectTo(to, ch);
00144             ch->setDisplayString(displayString.c_str());
00145         }
00146     }
00147     else if (gateType == cGate::INPUT)
00148     {
00149         if (oldGate->isConnected())
00150         {
00151             cGate *from = oldGate->getPreviousGate();
00152             cChannel *ch = copyChannel(from->getChannel());
00153             std::string displayString = from->getChannel()->getDisplayString().str();
00154             from->disconnect();
00155             from->connectTo(newGate, ch);
00156             ch->setDisplayString(displayString.c_str());
00157         }
00158     }
00159     else
00160     {
00161         error("Unexpected gate type: %d", (int)gateType);
00162     }
00163 }
00164 
00165 cChannel *FailureManager::copyChannel(cChannel *channel)
00166 {
00167     cChannel *copy = channel->getChannelType()->create(channel->getName());
00168     copyParams(channel, copy);
00169     return copy;
00170 }
00171 
00172 void FailureManager::copyParams(cComponent *from, cComponent *to)
00173 {
00174     for(int i = 0; i < from->getNumParams(); i++)
00175         to->par(i) = from->par(i);
00176 }
00177