Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include <ctype.h>
00023 #include <algorithm>
00024 #include <sstream>
00025
00026 #include "InterfaceTable.h"
00027 #include "NotifierConsts.h"
00028
00029
00030 Define_Module( InterfaceTable );
00031
00032 #define INTERFACEIDS_START 100
00033
00034 std::ostream& operator<<(std::ostream& os, const InterfaceEntry& e)
00035 {
00036 os << e.info();
00037 return os;
00038 };
00039
00040
00041 InterfaceTable::InterfaceTable()
00042 {
00043 tmpNumInterfaces = -1;
00044 tmpInterfaceList = NULL;
00045 }
00046
00047 InterfaceTable::~InterfaceTable()
00048 {
00049 for (int i=0; i < (int)idToInterface.size(); i++)
00050 delete idToInterface[i];
00051 delete [] tmpInterfaceList;
00052 }
00053
00054 void InterfaceTable::initialize(int stage)
00055 {
00056 if (stage==0)
00057 {
00058
00059 nb = NotificationBoardAccess().get();
00060
00061
00062 InterfaceEntry *ie = new InterfaceEntry();
00063 ie->setName("lo0");
00064 ie->setMtu(3924);
00065 ie->setLoopback(true);
00066 addInterface(ie, NULL);
00067 }
00068 else if (stage==1)
00069 {
00070 WATCH_PTRVECTOR(idToInterface);
00071 updateDisplayString();
00072 }
00073 }
00074
00075 void InterfaceTable::updateDisplayString()
00076 {
00077 if (!ev.isGUI())
00078 return;
00079
00080 char buf[80];
00081 sprintf(buf, "%d interfaces", getNumInterfaces());
00082 getDisplayString().setTagArg("t",0,buf);
00083 }
00084
00085 void InterfaceTable::handleMessage(cMessage *msg)
00086 {
00087 opp_error("This module doesn't process messages");
00088 }
00089
00090 void InterfaceTable::receiveChangeNotification(int category, const cPolymorphic *details)
00091 {
00092
00093 Enter_Method_Silent();
00094 printNotificationBanner(category, details);
00095 }
00096
00097
00098
00099 int InterfaceTable::getNumInterfaces()
00100 {
00101 if (tmpNumInterfaces == -1)
00102 {
00103
00104 int n = 0;
00105 int maxId = idToInterface.size();
00106 for (int i=0; i<maxId; i++)
00107 if (idToInterface[i])
00108 n++;
00109 tmpNumInterfaces = n;
00110 }
00111
00112 return tmpNumInterfaces;
00113 }
00114
00115 InterfaceEntry *InterfaceTable::getInterface(int pos)
00116 {
00117 int n = getNumInterfaces();
00118 if (pos<0 || pos>=n)
00119 opp_error("getInterface(): interface index %d out of range 0..%d", pos, n-1);
00120
00121 if (!tmpInterfaceList)
00122 {
00123
00124 tmpInterfaceList = new InterfaceEntry *[n];
00125 int k = 0;
00126 int maxId = idToInterface.size();
00127 for (int i=0; i<maxId; i++)
00128 if (idToInterface[i])
00129 tmpInterfaceList[k++] = idToInterface[i];
00130 }
00131
00132 return tmpInterfaceList[pos];
00133 }
00134
00135 InterfaceEntry *InterfaceTable::getInterfaceById(int id)
00136 {
00137 id -= INTERFACEIDS_START;
00138 return (id<0 || id>=(int)idToInterface.size()) ? NULL : idToInterface[id];
00139 }
00140
00141 void InterfaceTable::addInterface(InterfaceEntry *entry, cModule *ifmod)
00142 {
00143
00144 if (getInterfaceByName(entry->getName())!=NULL)
00145 opp_error("addInterface(): interface '%s' already registered", entry->getName());
00146
00147
00148 entry->setInterfaceId(INTERFACEIDS_START + idToInterface.size());
00149 entry->setInterfaceTable(this);
00150 idToInterface.push_back(entry);
00151 invalidateTmpInterfaceList();
00152
00153
00154 if (ifmod)
00155 discoverConnectingGates(entry, ifmod);
00156
00157 nb->fireChangeNotification(NF_INTERFACE_CREATED, entry);
00158 }
00159
00160 void InterfaceTable::discoverConnectingGates(InterfaceEntry *entry, cModule *ifmod)
00161 {
00162
00163 cModule *host = getParentModule();
00164 while (ifmod && ifmod->getParentModule()!=host)
00165 ifmod = ifmod->getParentModule();
00166 if (!ifmod)
00167 opp_error("addInterface(): specified module is not in this host/router");
00168
00169
00170 cGate *nwlayerInGate=NULL, *nwlayerOutGate=NULL;
00171 for (GateIterator i(ifmod); !i.end(); i++)
00172 {
00173 cGate *g = i();
00174 if (!g) continue;
00175
00176
00177 if (g->getType()==cGate::OUTPUT && g->getNextGate() && g->getNextGate()->getOwnerModule()==host)
00178 entry->setNodeOutputGateId(g->getNextGate()->getId());
00179 if (g->getType()==cGate::INPUT && g->getPreviousGate() && g->getPreviousGate()->getOwnerModule()==host)
00180 entry->setNodeInputGateId(g->getPreviousGate()->getId());
00181
00182
00183 if (g->getType()==cGate::OUTPUT && g->getNextGate() && g->getNextGate()->isName("ifIn"))
00184 nwlayerInGate = g->getNextGate();
00185 if (g->getType()==cGate::INPUT && g->getPreviousGate() && g->getPreviousGate()->isName("ifOut"))
00186 nwlayerOutGate = g->getPreviousGate();
00187 }
00188
00189
00190
00191
00192 if (!nwlayerInGate || !nwlayerOutGate || nwlayerInGate->getIndex()!=nwlayerOutGate->getIndex())
00193 opp_error("addInterface(): interface must be connected to network layer's ifIn[]/ifOut[] gates of the same index");
00194 entry->setNetworkLayerGateIndex(nwlayerInGate->getIndex());
00195 }
00196
00197 void InterfaceTable::deleteInterface(InterfaceEntry *entry)
00198 {
00199 int id = entry->getInterfaceId();
00200 if (entry != getInterfaceById(id))
00201 opp_error("deleteInterface(): interface '%s' not found in interface table", entry->getName());
00202
00203 nb->fireChangeNotification(NF_INTERFACE_DELETED, entry);
00204
00205 idToInterface[id - INTERFACEIDS_START] = NULL;
00206 delete entry;
00207 invalidateTmpInterfaceList();
00208 }
00209
00210 void InterfaceTable::invalidateTmpInterfaceList()
00211 {
00212 tmpNumInterfaces = -1;
00213 delete[] tmpInterfaceList;
00214 tmpInterfaceList = NULL;
00215 }
00216
00217 void InterfaceTable::interfaceChanged(InterfaceEntry *entry, int category)
00218 {
00219 nb->fireChangeNotification(category, entry);
00220 }
00221
00222 InterfaceEntry *InterfaceTable::getInterfaceByNodeOutputGateId(int id)
00223 {
00224
00225 Enter_Method_Silent();
00226 int n = idToInterface.size();
00227 for (int i=0; i<n; i++)
00228 if (idToInterface[i] && idToInterface[i]->getNodeOutputGateId()==id)
00229 return idToInterface[i];
00230 return NULL;
00231 }
00232
00233 InterfaceEntry *InterfaceTable::getInterfaceByNodeInputGateId(int id)
00234 {
00235
00236 Enter_Method_Silent();
00237 int n = idToInterface.size();
00238 for (int i=0; i<n; i++)
00239 if (idToInterface[i] && idToInterface[i]->getNodeInputGateId()==id)
00240 return idToInterface[i];
00241 return NULL;
00242 }
00243
00244 InterfaceEntry *InterfaceTable::getInterfaceByNetworkLayerGateIndex(int index)
00245 {
00246
00247 Enter_Method_Silent();
00248 int n = idToInterface.size();
00249 for (int i=0; i<n; i++)
00250 if (idToInterface[i] && idToInterface[i]->getNetworkLayerGateIndex()==index)
00251 return idToInterface[i];
00252 return NULL;
00253 }
00254
00255 InterfaceEntry *InterfaceTable::getInterfaceByName(const char *name)
00256 {
00257 Enter_Method_Silent();
00258 if (!name)
00259 return NULL;
00260 int n = idToInterface.size();
00261 for (int i=0; i<n; i++)
00262 if (idToInterface[i] && !strcmp(name, idToInterface[i]->getName()))
00263 return idToInterface[i];
00264 return NULL;
00265 }
00266
00267 InterfaceEntry *InterfaceTable::getFirstLoopbackInterface()
00268 {
00269 Enter_Method_Silent();
00270 int n = idToInterface.size();
00271 for (int i=0; i<n; i++)
00272 if (idToInterface[i] && idToInterface[i]->isLoopback())
00273 return idToInterface[i];
00274 return NULL;
00275 }
00276