00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include <vector>
00025 #include <iostream>
00026
00027 #include <omnetpp.h>
00028
00029 #include <IRoutingTable.h>
00030 #include <IInterfaceTable.h>
00031 #include <IPAddressResolver.h>
00032 #include <IPv4InterfaceData.h>
00033
00034 #include "AccessNet.h"
00035
00036 Define_Module(AccessNet);
00037
00038 std::ostream& operator<<(std::ostream& os, NodeInfo& n)
00039 {
00040 os << IPAddress(n.IPAddress);
00041 return os;
00042 }
00043
00044 void AccessNet::initialize(int stage)
00045 {
00046 if(stage != MIN_STAGE_UNDERLAY + 1)
00047 return;
00048
00049 router.module = getParentModule();
00050 router.interfaceTable = IPAddressResolver().interfaceTableOf(getParentModule());
00051 router.routingTable = IPAddressResolver().routingTableOf(getParentModule());
00052 router.IPAddress = IPAddressResolver().addressOf(getParentModule()).get4().getInt();
00053
00054 channelTypesTx = cStringTokenizer(par("channelTypes"), " ").asVector();
00055 channelTypesRx = cStringTokenizer(par("channelTypesRx"), " ").asVector();
00056
00057 if (channelTypesRx.size() != channelTypesTx.size()) {
00058 channelTypesRx = channelTypesTx;
00059 }
00060
00061 int chanIndex = intuniform(0, channelTypesTx.size()-1);
00062
00063 selectChannel(channelTypesRx[chanIndex], channelTypesTx[chanIndex]);
00064
00065
00066 lifetimeVector.setName("Terminal Lifetime");
00067
00068 WATCH_VECTOR(overlayTerminal);
00069
00070 lastIP = 0;
00071
00072 updateDisplayString();
00073 }
00074
00075 void AccessNet::handleMessage(cMessage* msg)
00076 {
00077 error("this module doesn't handle messages, it runs only in initialize()");
00078 }
00079
00080 int AccessNet::addOverlayNode(cModule* node, bool migrate)
00081 {
00082 Enter_Method("addOverlayNode()");
00083
00084 TerminalInfo terminal;
00085 terminal.module = node;
00086 terminal.interfaceTable = IPAddressResolver().interfaceTableOf(node);
00087 terminal.remoteInterfaceTable = router.interfaceTable;
00088 terminal.routingTable = IPAddressResolver().routingTableOf(node);
00089 terminal.PPPInterface = node->getSubmodule("ppp", 0);
00090 terminal.createdAt = simTime();
00091
00092
00093
00094 bool ip_test = false;
00095 for (uint32 ipOffset = lastIP + 1; ipOffset != lastIP; ipOffset++) {
00096 if ( ipOffset == 0x10000) {
00097
00098 ipOffset = 0;
00099 continue;
00100 }
00101
00102 uint32_t ip = router.IPAddress + ipOffset;
00103
00104
00105
00106 if ( ((ip & 0xff) == 0) || ((ip & 0xff) == 0xff)
00107 || ((ip & 0xff00) == 0xff00) ) {
00108 continue;
00109 }
00110
00111
00112 ip_test = true;
00113 for (uint32_t i = 0; i < overlayTerminal.size(); i++) {
00114 if (overlayTerminal[i].IPAddress == ip) {
00115 ip_test = false;
00116 break;
00117 }
00118 }
00119
00120
00121 if (ip_test) {
00122 terminal.IPAddress = ip;
00123 lastIP = ipOffset;
00124 break;
00125 }
00126 }
00127 if (!ip_test)
00128 opp_error ("Error creating node: No available IP in access net!");
00129
00130
00131 if (ev.isGUI()) {
00132 const char* ip_disp = const_cast<char*>
00133 (IPAddress(terminal.IPAddress).str().c_str());
00134 terminal.module->getDisplayString().insertTag("t", 0);
00135 terminal.module->getDisplayString().setTagArg("t", 0, ip_disp);
00136 terminal.module->getDisplayString().setTagArg("t", 1, "l");
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146 int k = 1;
00147 while ( router.module->findSubmodule("ppp", k) != -1 )
00148 k++;
00149
00150 cModuleType* pppInterfaceModuleType = cModuleType::get("inet.linklayer.ppp.PPPInterface");
00151 terminal.remotePPPInterface = pppInterfaceModuleType->
00152 create("ppp", router.module, 0, k);
00153
00154
00155
00156
00157
00158
00159
00160 cGate* routerInGate = firstUnusedGate(router.module, "pppg", cGate::INPUT);
00161 cGate* routerOutGate = firstUnusedGate(router.module, "pppg", cGate::OUTPUT);
00162
00163 cChannelType* channelTypeRx = cChannelType::find( channelTypeRxStr.c_str() );
00164 cChannelType* channelTypeTx = cChannelType::find( channelTypeTxStr.c_str() );
00165 if (!channelTypeRx || !channelTypeTx)
00166 opp_error("Could not find Channel or ChannelRx Type. Most likely "
00167 "parameter channelTypes does not match the channels defined "
00168 "in channels.ned");
00169
00170 terminal.module->gate("pppg$o", 0)->connectTo(routerInGate,
00171 channelTypeRx->create(channelTypeRxStr.c_str()));
00172 routerOutGate->connectTo(terminal.module->gate("pppg$i", 0),
00173 channelTypeTx->create(channelTypeTxStr.c_str()));
00174
00175
00176 routerInGate->connectTo(terminal.remotePPPInterface->gate("phys$i"));
00177 terminal.remotePPPInterface->gate("phys$o")->connectTo(routerOutGate);
00178
00179
00180 cModule* netwModule = router.module->getSubmodule("networkLayer");
00181
00182 cGate* netwInGate = firstUnusedGate(netwModule, "ifIn");
00183 cGate* netwOutGate = firstUnusedGate(netwModule, "ifOut");
00184
00185 netwOutGate->connectTo(terminal.remotePPPInterface->gate("netwIn"));
00186 terminal.remotePPPInterface->gate("netwOut")->connectTo(netwInGate);
00187
00188
00189 cModule* ipModule = router.module->getSubmodule("networkLayer")->
00190 getSubmodule("ip");
00191
00192 cGate* ipIn = firstUnusedGate(ipModule, "queueIn");
00193 netwInGate->connectTo(ipIn);
00194
00195 #ifdef _ORIG_INET
00196 cModule* arpModule = router.module->getSubmodule("networkLayer")->getSubmodule("arp");
00197
00198 cGate* arpOut = firstUnusedGate(arpModule, "nicOut");
00199
00200
00201 cGate* ipOut = ipModule->gate("queueOut");
00202
00203 arpOut->connectTo(netwOutGate);
00204 #endif
00205
00206
00207
00208
00209 terminal.remotePPPInterface->finalizeParameters();
00210 terminal.remotePPPInterface->setDisplayString("i=block/ifcard");
00211 terminal.remotePPPInterface->buildInside();
00212 terminal.remotePPPInterface->scheduleStart(simTime());
00213 terminal.remotePPPInterface->callInitialize();
00214
00215 if ( !migrate) {
00216
00217
00218 for (int i=0; i < MAX_STAGE_UNDERLAY + 1; i++) {
00219 terminal.module->callInitialize(i);
00220 }
00221 }
00222
00223 terminal.remoteInterfaceEntry = router.interfaceTable->getInterface(
00224 router.interfaceTable->getNumInterfaces() - 1);
00225 terminal.interfaceEntry = terminal.interfaceTable->getInterfaceByName("ppp0");
00226
00227
00228
00229
00230
00231
00232
00233 IPv4InterfaceData* interfaceData = new IPv4InterfaceData;
00234 interfaceData->setIPAddress(router.IPAddress);
00235 interfaceData->setNetmask(IPAddress::ALLONES_ADDRESS);
00236 terminal.remoteInterfaceEntry->setIPv4Data(interfaceData);
00237
00238
00239 terminal.interfaceEntry->ipv4Data()->setIPAddress(IPAddress(terminal.IPAddress));
00240 terminal.interfaceEntry->ipv4Data()->setNetmask(IPAddress::ALLONES_ADDRESS);
00241
00242
00243
00244
00245
00246
00247 IPRoute* re = new IPRoute();
00248 re->setHost(IPAddress(terminal.IPAddress));
00249 re->setNetmask(IPAddress(IPAddress::ALLONES_ADDRESS));
00250 re->setInterface(terminal.remoteInterfaceEntry);
00251 re->setType(IPRoute::DIRECT);
00252 re->setSource(IPRoute::MANUAL);
00253 router.routingTable->addRoute(re);
00254 terminal.remoteRoutingEntry = re;
00255
00256
00257 IPRoute* te = new IPRoute();
00258 te->setHost(IPAddress::UNSPECIFIED_ADDRESS);
00259 te->setNetmask(IPAddress::UNSPECIFIED_ADDRESS);
00260 te->setGateway(router.IPAddress);
00261 te->setInterface(terminal.interfaceEntry);
00262 te->setType(IPRoute::REMOTE);
00263 te->setSource(IPRoute::MANUAL);
00264 terminal.routingTable->addRoute(te);
00265 terminal.routingEntry = te;
00266
00267
00268
00269 overlayTerminal.push_back(terminal);
00270 int ID = terminal.module->getId();
00271
00272 updateDisplayString();
00273
00274 return ID;
00275 }
00276
00277 int AccessNet::getRandomNodeId()
00278 {
00279 Enter_Method("getRandomNodeId()");
00280
00281 return overlayTerminal[intuniform(0, overlayTerminal.size() - 1)].module->getId();
00282 }
00283
00284 cModule* AccessNet::removeOverlayNode(int ID)
00285 {
00286 Enter_Method("removeOverlayNode()");
00287
00288 cModule* node = NULL;
00289 TerminalInfo terminal;
00290 int index;
00291
00292 for(unsigned int i=0; i<overlayTerminal.size(); i++) {
00293 if(overlayTerminal[i].module->getId() == ID) {
00294 terminal = overlayTerminal[i];
00295 node = terminal.module;
00296 index = i;
00297 }
00298 }
00299
00300 if(node == NULL) return NULL;
00301
00302 cModule* ppp = terminal.remotePPPInterface;
00303
00304
00305 node->gate("pppg$o", 0)->disconnect();
00306 node->gate("pppg$i", 0)->getPreviousGate()->disconnect();
00307
00308
00309 ppp->gate("netwIn")->getPathStartGate()->disconnect();
00310 ppp->gate("netwOut")->getNextGate()->disconnect();
00311
00312
00313 ppp->callFinish();
00314 ppp->deleteModule();
00315
00316
00317 router.interfaceTable->deleteInterface(terminal.remoteInterfaceEntry);
00318
00319
00320 terminal.routingTable->deleteRoute(terminal.routingEntry);
00321 router.routingTable->deleteRoute(terminal.remoteRoutingEntry);
00322
00323
00324 lifetimeVector.record(simTime() - overlayTerminal[index].createdAt);
00325
00326
00327 overlayTerminal.erase(overlayTerminal.begin() + index);
00328
00329 updateDisplayString();
00330
00331 return node;
00332 }
00333
00334 cModule* AccessNet::getOverlayNode(int ID)
00335 {
00336 Enter_Method("getOverlayNode()");
00337
00338 cModule* node = NULL;
00339
00340 for(unsigned int i=0; i<overlayTerminal.size(); i++) {
00341 if(overlayTerminal[i].module->getId() == ID)
00342 node = overlayTerminal[i].module;
00343 }
00344 return node;
00345 }
00346
00347 void AccessNet::updateDisplayString()
00348 {
00349 if (ev.isGUI()) {
00350 char buf[80];
00351 if ( overlayTerminal.size() == 1 ) {
00352 sprintf(buf, "1 terminal connected");
00353 } else {
00354 sprintf(buf, "%zi terminals connected", overlayTerminal.size());
00355 }
00356 getDisplayString().setTagArg("t", 0, buf);
00357 getDisplayString().setTagArg("t", 2, "blue");
00358 }
00359 }
00360
00361 cGate* firstUnusedGate(cModule* owner, const char* name, cGate::Type type)
00362 {
00363 int index;
00364 for (index = 0; index < owner->gateSize(name); index++) {
00365 cGate *gate = type == cGate::NONE ? owner->gate(name, index) : owner->gateHalf(name, type, index);
00366 if (!gate->isConnectedOutside()) {
00367 return gate;
00368 }
00369 }
00370
00371 owner->setGateSize(name, index + 2);
00372 return type == cGate::NONE ? owner->gate(name, index + 1) : owner->gateHalf(name, type, index + 1);
00373 }
00374