25 #if !defined(__APPLE__) && !defined(_WIN32) && !defined(__ANDROID__)
35 #include "IInterfaceTable.h"
36 #include "InterfaceEntry.h"
37 #include "IPv4InterfaceData.h"
38 #include "IPv6InterfaceData.h"
40 #include "IPAddressResolver.h"
42 #include <cxmlelement.h>
58 for (uint32_t i = 0; i < nodeRecordPool.size(); ++i) {
60 delete nodeRecordPool[i].first;
62 nodeRecordPool.clear();
71 fixedNodePositions = par(
"fixedNodePositions");
72 useIPv6 = par(
"useIPv6Addresses");
75 fieldSize = par(
"fieldSize");
76 sendQueueLength = par(
"sendQueueLength");
79 nodeCoordinateSource = par(
"nodeCoordinateSource");
81 if (std::string(nodeCoordinateSource) !=
"") {
83 std::ifstream check_for_xml_file(nodeCoordinateSource);
84 if (check_for_xml_file) {
87 EV<<
"[SimpleNetConfigurator::initializeUnderlay()]\n"
88 <<
" Using '" << nodeCoordinateSource
89 <<
"' as coordinate source file" << endl;
91 maxCoordinate = parseCoordFile(nodeCoordinateSource);
93 throw cRuntimeError(
"Coordinate source file not found!");
95 check_for_xml_file.close();
100 EV <<
"[SimpleNetConfigurator::initializeUnderlay()]\n"
101 <<
" Using conventional (random) coordinates for placing nodes!\n"
102 <<
" (no XML coordinate source file was specified)" << endl;
106 nextFreeAddress = 0x1000001;
109 overlayTerminalCount = 0;
118 Enter_Method_Silent();
120 cModuleType* moduleType = cModuleType::get(type.
terminalType.c_str());
122 std::string nameStr =
"overlayTerminal";
123 if (churnGenerator.size() > 1) {
124 nameStr +=
"-" + convertToString<int32_t>(type.
typeID);
126 cModule* node = moduleType->create(nameStr.c_str(), getParentModule(),
127 numCreated + 1, numCreated);
129 std::string displayString;
132 ((displayString +=
"i=device/wifilaptop_l,")
133 += colorNames[type.
typeID - 1]) +=
",40;i2=block/circle_s";
135 displayString =
"i=device/wifilaptop_l;i2=block/circle_s";
138 node->finalizeParameters();
139 node->setDisplayString(displayString.c_str());
141 node->scheduleStart(simTime());
144 node->callInitialize(i);
149 addr = IPv6Address(0, nextFreeAddress++, 0, 0);
151 addr = IPAddress(nextFreeAddress++);
155 cChannelType* rxChan = cChannelType::find(type.
channelTypesRx[chanIndex].c_str());
156 cChannelType* txChan = cChannelType::find(type.
channelTypesTx[chanIndex].c_str());
158 if (!txChan || !rxChan)
159 opp_error(
"Could not find Channel Type. Most likely parameter "
160 "channelTypesRx or channelTypes does not match the channels defined in "
166 entry =
new SimpleNodeEntry(node, rxChan, txChan, sendQueueLength, fieldSize);
171 uint32_t volunteer = intuniform(0, nodeRecordPool.size() - 1);
172 uint32_t temp = volunteer;
173 while (nodeRecordPool[volunteer].second ==
false) {
175 if (volunteer >= nodeRecordPool.size())
178 if (temp == volunteer)
179 throw cRuntimeError(
"No unused coordinates left -> "
180 "cannot create any more nodes. "
181 "Provide %s-file with more nodes!\n", nodeCoordinateSource);
185 sendQueueLength, nodeRecordPool[volunteer].first, volunteer);
189 nodeRecordPool[volunteer].second =
false;
201 IPv6InterfaceData* ifdata =
new IPv6InterfaceData;
202 ifdata->assignAddress(addr.get6(),
false, 0, 0);
203 IPv6InterfaceData::AdvPrefix prefix = {addr.get6(), 64};
204 ifdata->addAdvPrefix(prefix);
205 InterfaceEntry* e =
new InterfaceEntry;
206 e->setName(
"dummy interface");
207 e->setIPv6Data(ifdata);
208 IPAddressResolver().interfaceTableOf(node)->addInterface(e, NULL);
211 IPv4InterfaceData* ifdata =
new IPv4InterfaceData;
212 ifdata->setIPAddress(addr.get4());
213 ifdata->setNetmask(IPAddress(
"255.255.255.255"));
214 InterfaceEntry* e =
new InterfaceEntry;
215 e->setName(
"dummy interface");
216 e->setIPv4Data(ifdata);
218 IPAddressResolver().interfaceTableOf(node)->addInterface(e, NULL);
226 globalNodeList->addPeer(addr, info);
232 node->callInitialize(i);
238 if (fixedNodePositions && ev.isGUI()) {
239 node->getDisplayString().insertTag(
"p");
240 node->getDisplayString().setTagArg(
"p", 0, (
long int)(entry->
getX() * 5));
241 node->getDisplayString().setTagArg(
"p", 1, (
long int)(entry->
getY() * 5));
242 node->getDisplayString().insertTag(
"t", 0);
243 node->getDisplayString().setTagArg(
"t", 0, addr.str().c_str());
244 node->getDisplayString().setTagArg(
"t", 1,
"l");
247 overlayTerminalCount++;
250 churnGenerator[type.
typeID]->terminalCount++;
262 cXMLElement* rootElement = ev.getXMLDocument(nodeCoordinateSource);
265 dimensions = atoi(rootElement->getAttribute(
"dimensions"));
267 EV <<
"[SimpleNetConfigurator::parseCoordFile()]\n"
268 <<
" using " << dimensions <<
" dimensions: ";
270 double max_coord = 0;
272 for (cXMLElement *tmpElement = rootElement->getFirstChild(); tmpElement;
273 tmpElement = tmpElement->getNextSibling()) {
288 for (cXMLElement *coord = tmpElement->getFirstChild(); coord;
289 coord = coord->getNextSibling()) {
291 tmpNode->
coords[i] = atof(coord->getNodeValue());
293 double newMax = fabs(tmpNode->
coords[i]);
294 if (newMax > max_coord) {
301 nodeRecordPool.push_back(make_pair(tmpNode,
true));
306 EV << nodeRecordPool.size()
307 <<
" nodes added to vector \"nodeRecordPool\"." << endl;
309 #if OMNETPP_VERSION>=0x0401
311 ev.forgetXMLDocument(nodeCoordinateSource);
312 #if !defined(__APPLE__) && !defined(_WIN32) && !defined(__ANDROID__)
317 return (uint32_t)ceil(max_coord);
322 Enter_Method_Silent();
328 addr = globalNodeList->getRandomAliveNode(type.
typeID);
332 std::cout <<
"all nodes are already prekilled" << std::endl;
337 info =
dynamic_cast<SimpleInfo*
> (globalNodeList->getPeerInfo(*addr));
341 globalNodeList->setPreKilled(*addr);
343 opp_error(
"SimpleNetConfigurator: Trying to pre kill node "
344 "with nonexistant TransportAddress!");
347 uint32_t effectiveType = info->
getTypeID();
350 cModule* node = gate->getOwnerModule()->getParentModule();
352 if (scheduledID.count(node->getId())) {
353 std::cout <<
"SchedID" << std::endl;
358 globalNodeList->removePeer(IPAddressResolver().addressOf(node));
362 killList.push_front(IPAddressResolver().addressOf(node));
363 scheduledID.insert(node->getId());
365 overlayTerminalCount--;
368 churnGenerator[effectiveType]->terminalCount--;
374 NotificationBoard* nb = check_and_cast<NotificationBoard*> (
375 node-> getSubmodule(
"notificationBoard"));
376 nb->fireChangeNotification(NF_OVERLAY_NODE_LEAVE);
378 double random = uniform(0, 1);
379 if (random < gracefulLeaveProbability) {
380 nb->fireChangeNotification(NF_OVERLAY_NODE_GRACEFUL_LEAVE);
383 cMessage* msg =
new cMessage();
384 scheduleAt(simTime() + gracefulLeaveDelay, msg);
389 Enter_Method_Silent();
395 dynamic_cast<SimpleInfo*
> (globalNodeList->getPeerInfo(*addr));
399 opp_error(
"SimpleNetConfigurator: Trying to migrate node with "
400 "nonexistant TransportAddress!");
404 globalNodeList-> getRandomPeerInfo(type.
typeID));
409 cModule* node = gate->getOwnerModule()->getParentModule();
412 if (scheduledID.count(node->getId()))
418 IPvXAddress address = IPAddress(nextFreeAddress++);
420 IPvXAddress tmp_ip = IPAddressResolver().addressOf(node);
424 cChannelType* rxChan = cChannelType::find(type.
channelTypesRx[chanIndex].c_str());
425 cChannelType* txChan = cChannelType::find(type.
channelTypesTx[chanIndex].c_str());
427 if (!txChan || !rxChan)
428 opp_error(
"Could not find Channel Type. Most likely parameter "
429 "channelTypesRx or channelTypes does not match the channels defined in "
440 newentry =
new SimpleNodeEntry(node, rxChan, txChan, fieldSize, sendQueueLength);
443 node->bubble(
"I am migrating!");
446 globalNodeList->killPeer(tmp_ip);
451 InterfaceEntry* ie = IPAddressResolver().interfaceTableOf(node)->
452 getInterfaceByName(
"dummy interface");
453 delete ie->ipv4Data();
456 IPv4InterfaceData* ifdata =
new IPv4InterfaceData;
457 ifdata->setIPAddress(address.get4());
458 ifdata->setNetmask(IPAddress(
"255.255.255.255"));
459 ie->setIPv4Data(ifdata);
467 globalNodeList->addPeer(address, newinfo);
470 NotificationBoard* nb = check_and_cast<NotificationBoard*> (
471 node->getSubmodule(
"notificationBoard"));
472 nb->fireChangeNotification(NF_OVERLAY_TRANSPORTADDRESS_CHANGED);
477 Enter_Method_Silent();
480 IPvXAddress addr = killList.back();
486 dynamic_cast<SimpleInfo*
> (globalNodeList->getPeerInfo(addr));
491 throw cRuntimeError(
"SimpleUnderlayConfigurator: Trying to kill "
492 "node with unknown TransportAddress!");
496 cModule* node = gate->getOwnerModule()->getParentModule();
502 scheduledID.erase(node->getId());
503 globalNodeList->killPeer(addr);
505 InterfaceEntry* ie = IPAddressResolver().interfaceTableOf(node)->
506 getInterfaceByName(
"dummy interface");
507 delete ie->ipv4Data();
510 node->deleteModule();
519 sprintf(buf,
"%i overlay terminals", overlayTerminalCount);
520 getDisplayString().setTagArg(
"t", 0, buf);
526 recordScalar(
"Terminals added", numCreated);
527 recordScalar(
"Terminals removed", numKilled);
529 if (!isInInitPhase()) {
530 struct timeval now, diff;
531 gettimeofday(&now, NULL);
532 timersub(&now, &initFinishedTime, &diff);
533 printf(
"Simulation time: %li.%06li\n", diff.tv_sec, diff.tv_usec);
542 Enter_Method_Silent();
547 dynamic_cast<SimpleInfo*
> (globalNodeList->getPeerInfo(addr));
551 opp_error(
"SimpleNetConfigurator: Trying to migrate node with "
552 "nonexistent TransportAddress!");
560 cModule* node = gate->getOwnerModule()->getParentModule();
563 if (scheduledID.count(node->getId()))
567 IPvXAddress address = IPAddress(nextFreeAddress++);
568 EV << addr <<
" migrates to ";
569 EV << address <<
"!" << endl;
574 cChannelType* rxChan = cChannelType::find(type.
channelTypesRx[chanIndex].c_str());
575 cChannelType* txChan = cChannelType::find(type.
channelTypesTx[chanIndex].c_str());
577 if (!txChan || !rxChan)
578 opp_error(
"Could not find Channel Type. Most likely parameter "
579 "channelTypesRx or channelTypes does not match the channels defined in "
589 newentry =
new SimpleNodeEntry(node, rxChan, txChan, fieldSize, sendQueueLength);
592 node->bubble(
"I am migrating!");
595 NodeHandle* peer = globalNodeList->getNodeHandle(addr);
599 registrationPeer = *peer;
602 globalNodeList->killPeer(addr);
607 InterfaceEntry* ie = IPAddressResolver().interfaceTableOf(node)->
608 getInterfaceByName(
"dummy interface");
609 delete ie->ipv4Data();
612 IPv4InterfaceData* ifdata =
new IPv4InterfaceData;
613 ifdata->setIPAddress(address.get4());
614 ifdata->setNetmask(IPAddress(
"255.255.255.255"));
615 ie->setIPv4Data(ifdata);
623 globalNodeList->addPeer(address, newinfo);
626 registrationPeer.
setIp(address);
627 globalNodeList->registerPeer(registrationPeer);
632 NotificationBoard* nb = check_and_cast<NotificationBoard*> (
633 node->getSubmodule(
"notificationBoard"));
634 nb->fireChangeNotification(NF_OVERLAY_TRANSPORTADDRESS_CHANGED);
650 radius = uniform (0.3, 1, 0) * radius;
651 double angle = uniform (0, 2 *M_PI, 0);
653 ret->
coords[0] = cos(angle)*radius + tempLoc->
coords[0];
654 ret->
coords[1] = sin(angle)*radius + tempLoc->
coords[1];