SimpleNetConfigurator Class Reference

#include <SimpleNetConfigurator.h>

Inheritance diagram for SimpleNetConfigurator:

UnderlayConfigurator

List of all members.


Detailed Description

Sets up a SimpleNetwork.

Adds overlay nodes to the network in init phase and adds/removes/migrates overlay nodes after init phase.

Public Member Functions

 ~SimpleNetConfigurator ()
virtual TransportAddresscreateNode (NodeType type, bool initialize=false)
 Creates an overlay node.
virtual void preKillNode (NodeType type, TransportAddress *addr=NULL)
 Notifies and schedules overlay nodes for removal.
virtual void migrateNode (NodeType type, TransportAddress *addr=NULL)
 Migrates overlay nodes from one access net to another.
uint getFieldSize ()
uint getFieldDimension ()
uint getSendQueueLenghth ()

Protected Member Functions

void initializeUnderlay (int stage)
 Enables access to the globalHashMap, sets some parameters and adds the initial number of nodes to the network.
void handleTimerEvent (cMessage *msg)
void finishUnderlay ()
 Saves statistics, prints simulation time.
void setDisplayString ()
 Prints statistics.
uint parseCoordFile (const char *nodeCoordinateSource)

Protected Attributes

uint32 nextFreeAddress
 adress of the node that will be created next
std::deque< IPvXAddress > killList
 stores nodes scheduled to be killed
std::set< int > scheduledID
 stores nodeIds to prevent migration of prekilled nodes
uint sendQueueLength
 send queue length of overlay terminals
uint fieldSize
int dimensions
bool fixedNodePositions
bool useXmlCoords
const char * nodeCoordinateSource
uint maxCoordinate
std::vector< std::pair
< NodeRecord *, bool > > 
nodeRecordPool
int numCreated
 number of overall created overlay terminals
int numKilled
 number of overall killed overlay terminals


Constructor & Destructor Documentation

SimpleNetConfigurator::~SimpleNetConfigurator (  ) 

00049 {
00050     for (uint i = 0; i < nodeRecordPool.size(); ++i) {
00051         //std::cout << (nodeRecordPool[i].second ? "+" : "_");
00052         delete nodeRecordPool[i].first;
00053     }
00054     nodeRecordPool.clear();
00055 }


Member Function Documentation

TransportAddress * SimpleNetConfigurator::createNode ( NodeType  type,
bool  initialize = false 
) [virtual]

Creates an overlay node.

Parameters:
type NodeType of the node to create
initialize are we in init phase?

Implements UnderlayConfigurator.

00103 {
00104     Enter_Method_Silent();
00105     // derive overlay node from ned
00106     cModuleType* moduleType = findModuleType(type.terminalType.c_str());
00107 
00108     cModule* node = moduleType->create("overlayTerminal", parentModule());
00109 
00110     node->par("overlayType").setStringValue(type.overlayType.c_str());
00111     node->par("tier1Type").setStringValue(type.tier1Type.c_str());
00112     node->par("tier2Type").setStringValue(type.tier2Type.c_str());
00113     node->par("tier3Type").setStringValue(type.tier3Type.c_str());
00114 
00115     std::string displayString;
00116 
00117     if ((type.typeID > 1) && (type.typeID <= (NUM_COLORS + 1))) {
00118         ((displayString += "i=device/wifilaptop_l,") += colorNames[type.typeID
00119                 - 2]) += ",40;i2=block/circle_s";
00120     } else {
00121         displayString = "i=device/wifilaptop_l;i2=block/circle_s";
00122     }
00123 
00124     node->setDisplayString(displayString.c_str());
00125     node->buildInside();
00126     node->scheduleStart(simulation.simTime());
00127 
00128     for (int i = 0; i < MAX_STAGE_UNDERLAY + 1; i++) {
00129         node->callInitialize(i);
00130     }
00131 
00132     // FIXME use only IPv4?
00133     IPvXAddress addr = IPAddress(nextFreeAddress++);
00134 
00135     cChannelType* chan = findChannelType(type.channelTypes[intuniform(0,
00136             type.channelTypes.size() - 1)].c_str());
00137 
00138     if (!chan)
00139         opp_error("Could not find Channel Type. Most likely parameter "
00140             "channelTypes does not match the channels defined in "
00141             "channels.ned");
00142     SimpleNodeEntry* entry;
00143 
00144     if (!useXmlCoords) {
00145         entry = new SimpleNodeEntry(node, chan, fieldSize, sendQueueLength);
00146     } else {
00147         //get random unused node
00148         uint volunteer = intuniform(0, nodeRecordPool.size() - 1);
00149         uint temp = volunteer;
00150         while (nodeRecordPool[volunteer].second == false) {
00151             //std::cout << ".";
00152             ++volunteer;
00153             if (volunteer >= nodeRecordPool.size())
00154                 volunteer = 0;
00155             // stop with errormessage if no more unused nodes available
00156             if (temp == volunteer)
00157                 throw new cRuntimeError("No unused coordinates left -> "
00158                     "cannot create any more nodes. "
00159                     "Provide %s-file with more nodes!\n", nodeCoordinateSource);
00160         }
00161 
00162         entry
00163                 = new SimpleNodeEntry(node, chan, sendQueueLength, nodeRecordPool[volunteer].first, volunteer);
00164 
00165         //insert IP-address into noderecord used
00166         nodeRecordPool[volunteer].first->ip = addr;
00167         nodeRecordPool[volunteer].second = false;
00168     }
00169 
00170     node->gate("out", 0)->setChannel(chan->create("outChan"));
00171 
00172     SimpleUDP* simple = check_and_cast<SimpleUDP*> (node->submodule("udp"));
00173     simple->setNodeEntry(entry);
00174 
00175     // Add pseudo-Interface to node's interfaceTable
00176     IPv4InterfaceData* ifdata = new IPv4InterfaceData;
00177     ifdata->setInetAddress(addr.get4());
00178     ifdata->setNetmask(IPAddress("255.255.255.255"));
00179     InterfaceEntry* e = new InterfaceEntry;
00180     e->setName("dummy interface");
00181     e->setIPv4Data(ifdata);
00182 
00183     IPAddressResolver().interfaceTableOf(node)->addInterface(e, NULL);
00184 
00185     // create meta information
00186     SimpleInfo* info = new SimpleInfo(type.typeID, node->id());
00187     info->setEntry(entry);
00188 
00189     // append index to module name
00190     char buf[80];
00191     sprintf(buf, "overlayTerminal[%i]", numCreated);
00192     node->setName(buf);
00193 
00194     //add node to bootstrap oracle
00195     bootstrapOracle->addPeer(addr, info);
00196 
00197     // if the node was not created during startup we have to
00198     // finish the initialization process manually
00199     if (!initialize) {
00200         for (int i = MAX_STAGE_UNDERLAY + 1; i < NUM_STAGES_ALL; i++) {
00201             node->callInitialize(i);
00202         }
00203     }
00204 
00205     //show ip...
00206     //TODO: migrate
00207     if (fixedNodePositions && ev.isGUI()) {
00208         node->displayString().insertTag("p");
00209         node->displayString().setTagArg("p", 0, (long int) entry->getX());
00210         node->displayString().setTagArg("p", 1, (long int) entry->getY());
00211         node->displayString().insertTag("t", 0);
00212         node->displayString().setTagArg("t", 0, addr.str().c_str());
00213         node->displayString().setTagArg("t", 1, "l");
00214     }
00215 
00216     overlayTerminalCount++;
00217     numCreated++;
00218 
00219     churnGenerator[type.typeID - 1]->terminalCount++;
00220 
00221     TransportAddress *address = new TransportAddress(addr);
00222 
00223     // update display
00224     setDisplayString();
00225 
00226     return address;
00227 }

void SimpleNetConfigurator::preKillNode ( NodeType  type,
TransportAddress addr = NULL 
) [virtual]

Notifies and schedules overlay nodes for removal.

Parameters:
type NodeType of the node to remove
addr NULL for random node

Implements UnderlayConfigurator.

00278 {
00279     Enter_Method_Silent();
00280 
00281     SimpleNodeEntry* entry = NULL;
00282     SimpleInfo* info;
00283 
00284     if (addr == NULL) {
00285         addr = bootstrapOracle->getRandomAliveNode(type.typeID);
00286 
00287         if (addr == NULL) {
00288             // all nodes are already prekilled
00289             std::cout << "all nodes are already prekilled" << std::endl;
00290             return;
00291         }
00292     }
00293 
00294     info = dynamic_cast<SimpleInfo*> (bootstrapOracle->getPeerInfo(*addr));
00295 
00296     if (info != NULL) {
00297         entry = info->getEntry();
00298         bootstrapOracle->setPreKilled(*addr);
00299     } else {
00300         opp_error("SimpleNetConfigurator: Trying to pre kill node "
00301                   "with nonexistant TransportAddress!");
00302     }
00303 
00304     uint32_t effectiveType = info->getTypeID();
00305     cGate* gate = entry->getGate();
00306 
00307     cModule* node = gate->ownerModule()->parentModule();
00308 
00309     if (scheduledID.count(node->id())) {
00310         std::cout << "SchedID" << std::endl;
00311         return;
00312     }
00313 
00314     // remove node from bootstrap oracle
00315     bootstrapOracle->removePeer(IPAddressResolver().addressOf(node));
00316 
00317     // put node into the kill list and schedule a message for final removal
00318     // of the node
00319     killList.push_front(IPAddressResolver().addressOf(node));
00320     scheduledID.insert(node->id());
00321 
00322     overlayTerminalCount--;
00323     numKilled++;
00324 
00325     churnGenerator[effectiveType - 1]->terminalCount--;
00326 
00327     // update display
00328     setDisplayString();
00329 
00330     // inform the notification board about the removal
00331     NotificationBoard* nb = check_and_cast<NotificationBoard*> (
00332                              node-> submodule("notificationBoard"));
00333     nb->fireChangeNotification(NF_OVERLAY_NODE_LEAVE);
00334 
00335     double random = uniform(0, 1);
00336     if (random < gracefulLeaveProbability) {
00337         nb->fireChangeNotification(NF_OVERLAY_NODE_GRACEFUL_LEAVE);
00338     }
00339 
00340     cMessage* msg = new cMessage();
00341     scheduleAt(simulation.simTime() + gracefulLeaveDelay, msg);
00342 }

void SimpleNetConfigurator::migrateNode ( NodeType  type,
TransportAddress addr = NULL 
) [virtual]

Migrates overlay nodes from one access net to another.

Parameters:
type NodeType of the node to migrate
addr NULL for random node

Implements UnderlayConfigurator.

00345 {
00346     Enter_Method_Silent();
00347 
00348     SimpleNodeEntry* entry = NULL;
00349 
00350     if (addr != NULL) {
00351         SimpleInfo* info =
00352               dynamic_cast<SimpleInfo*> (bootstrapOracle->getPeerInfo(*addr));
00353         if (info != NULL) {
00354             entry = info->getEntry();
00355         } else {
00356             opp_error("SimpleNetConfigurator: Trying to migrate node with "
00357                       "nonexistant TransportAddress!");
00358         }
00359     } else {
00360         SimpleInfo* info = dynamic_cast<SimpleInfo*> (
00361                 bootstrapOracle-> getRandomPeerInfo(type.typeID));
00362         entry = info->getEntry();
00363     }
00364 
00365     cGate* gate = entry->getGate();
00366     cModule* node = gate->ownerModule()->parentModule();
00367 
00368     // do not migrate node that is already scheduled
00369     if (scheduledID.count(node->id()))
00370         return;
00371 
00372     //std::cout << "migration @ " << tmp_ip << " --> " << address << std::endl;
00373 
00374     // FIXME use only IPv4?
00375     IPvXAddress address = IPAddress(nextFreeAddress++);
00376 
00377     IPvXAddress tmp_ip = IPAddressResolver().addressOf(node);
00378     SimpleNodeEntry* newentry;
00379 
00380     if (useXmlCoords) {
00381         newentry = new SimpleNodeEntry(node, findChannelType(
00382             channelTypes[intuniform(0, channelTypes.size() - 1)].c_str()),
00383             sendQueueLength, entry->getNodeRecord(), entry->getRecordIndex());
00384 
00385         newentry->getNodeRecord()->ip = address;
00386     } else {
00387         newentry = new SimpleNodeEntry(node, findChannelType(
00388             channelTypes[intuniform(0, channelTypes.size() - 1)].c_str()),
00389             fieldSize, sendQueueLength);
00390     }
00391 
00392     node->bubble("I am migrating!");
00393 
00394     //remove node from bootstrap oracle
00395     bootstrapOracle->killPeer(tmp_ip);
00396 
00397     SimpleUDP* simple = check_and_cast<SimpleUDP*> (gate->ownerModule());
00398     simple->setNodeEntry(newentry);
00399 
00400     InterfaceEntry* ie = IPAddressResolver().interfaceTableOf(node)->
00401                                       interfaceByName("dummy interface");
00402     delete ie->ipv4();
00403 
00404     // Add pseudo-Interface to node's interfaceTable
00405     IPv4InterfaceData* ifdata = new IPv4InterfaceData;
00406     ifdata->setInetAddress(address.get4());
00407     ifdata->setNetmask(IPAddress("255.255.255.255"));
00408     ie->setIPv4Data(ifdata);
00409 
00410     // create meta information
00411     SimpleInfo* newinfo = new SimpleInfo(type.typeID, node->id());
00412     newinfo->setEntry(newentry);
00413 
00414     //add node to bootstrap oracle
00415     bootstrapOracle->addPeer(address, newinfo);
00416 
00417     // inform the notification board about the migration
00418     NotificationBoard* nb = check_and_cast<NotificationBoard*> (
00419                                       node->submodule("notificationBoard"));
00420     nb->fireChangeNotification(NF_OVERLAY_TRANSPORTADDRESS_CHANGED);
00421 }

uint SimpleNetConfigurator::getFieldSize (  )  [inline]

00072 { return fieldSize; };

uint SimpleNetConfigurator::getFieldDimension (  )  [inline]

00073 { return dimensions; };

uint SimpleNetConfigurator::getSendQueueLenghth (  )  [inline]

00074 { return sendQueueLength; };

void SimpleNetConfigurator::initializeUnderlay ( int  stage  )  [protected, virtual]

Enables access to the globalHashMap, sets some parameters and adds the initial number of nodes to the network.

Parameters:
stage the phase of the initialisation

Implements UnderlayConfigurator.

00058 {
00059     if (stage != MAX_STAGE_UNDERLAY)
00060         return;
00061 
00062     // fetch some parameters
00063     fixedNodePositions = par("fixedNodePositions");
00064 
00065     // set maximum coordinates and send queue length
00066     fieldSize = par("fieldSize");
00067     sendQueueLength = par("sendQueueLength");
00068 
00069     // get parameter of sourcefile's name
00070     nodeCoordinateSource = par("nodeCoordinateSource");
00071 
00072     // check if exists and process xml-file containing coordinates
00073     std::ifstream check_for_xml_file(nodeCoordinateSource);
00074     if (check_for_xml_file) {
00075         useXmlCoords = 1;
00076 
00077         EV<< "[SimpleNetConfigurator::initializeUnderlay()]\n"
00078         << "    Using '" << nodeCoordinateSource
00079         << "' as Coordinate-Sourcefile" << endl;
00080 
00081         maxCoordinate = parseCoordFile(nodeCoordinateSource);
00082     } else {
00083         useXmlCoords = 0;
00084         dimensions = 2;
00085         EV << "[SimpleNetConfigurator::initializeUnderlay()]\n"
00086         << "    Using conventional (random) coordinates for placing nodes!\n"
00087         << "    (An XML-Sourcefile could not be opened)" << endl;
00088     }
00089     check_for_xml_file.close();
00090 
00091     // FIXME get address from parameter
00092     nextFreeAddress = 0x1000001;
00093 
00094     // count the overlay clients
00095     overlayTerminalCount = 0;
00096 
00097     numCreated = 0;
00098     numKilled = 0;
00099 }

void SimpleNetConfigurator::handleTimerEvent ( cMessage *  msg  )  [protected, virtual]

Reimplemented from UnderlayConfigurator.

00424 {
00425     Enter_Method_Silent();
00426 
00427     // get next scheduled node and remove it from the kill list
00428     IPvXAddress addr = killList.back();
00429     killList.pop_back();
00430 
00431     SimpleNodeEntry* entry = NULL;
00432 
00433     SimpleInfo* info =
00434             dynamic_cast<SimpleInfo*> (bootstrapOracle->getPeerInfo(addr));
00435 
00436     if (info != NULL) {
00437         entry = info->getEntry();
00438     } else {
00439         opp_error("SimpleNetConfigurator: Trying to kill node with "
00440             "unknown TransportAddress!");
00441     }
00442 
00443     cGate* gate = entry->getGate();
00444     cModule* node = gate->ownerModule()->parentModule();
00445 
00446     if (useXmlCoords) {
00447         nodeRecordPool[entry->getRecordIndex()].second = true;
00448     }
00449 
00450     scheduledID.erase(node->id());
00451     bootstrapOracle->killPeer(addr);
00452 
00453     InterfaceEntry* ie = IPAddressResolver().interfaceTableOf(node)->
00454                                          interfaceByName("dummy interface");
00455     delete ie->ipv4();
00456 
00457     node->callFinish();
00458     node->deleteModule();
00459 
00460     delete msg;
00461 }

void SimpleNetConfigurator::finishUnderlay (  )  [protected, virtual]

Saves statistics, prints simulation time.

Reimplemented from UnderlayConfigurator.

00472 {
00473     // statistics
00474     recordScalar("Terminals added", numCreated);
00475     recordScalar("Terminals removed", numKilled);
00476 
00477     if (!isInInitPhase()) {
00478         struct timeval now, diff;
00479         gettimeofday(&now, NULL);
00480         timersub(&now, &initFinishedTime, &diff);
00481         printf("Simulation time: %li.%06li\n", diff.tv_sec, diff.tv_usec);
00482     }
00483 }

void SimpleNetConfigurator::setDisplayString (  )  [protected, virtual]

Prints statistics.

Implements UnderlayConfigurator.

Referenced by createNode(), and preKillNode().

00464 {
00465     // Updates the statistics display string.
00466     char buf[80];
00467     sprintf(buf, "%i overlay terminals", overlayTerminalCount);
00468     displayString().setTagArg("t", 0, buf);
00469 }

uint SimpleNetConfigurator::parseCoordFile ( const char *  nodeCoordinateSource  )  [protected]

Referenced by initializeUnderlay().

00230 {
00231     cXMLElement* rootElement = ev.getXMLDocument(nodeCoordinateSource);
00232 
00233     // get number of dimensions from attribute of xml rootelement
00234     dimensions = atoi(rootElement->getAttribute("dimensions"));
00235     EV << "[SimpleNetConfigurator::parseCoordFile()]\n"
00236        << "    using " << dimensions << " dimensions: ";
00237 
00238     double max_coord = 0;
00239 
00240     for (cXMLElement *tmpElement = rootElement->getFirstChild(); tmpElement;
00241          tmpElement = tmpElement->getNextSibling()) {
00242 
00243         // get "ip" and "isRoot" from Attributes (not needed yet)
00244       /*
00245        const char* str_ip = tmpElement->getAttribute("ip");
00246        int tmpIP = 0;
00247        if (str_ip) sscanf(str_ip, "%x", &tmpIP);
00248        bool tmpIsRoot = atoi(tmpElement->getAttribute("isroot"));
00249        */
00250 
00251         // create tmpNode to be added to vector
00252         NodeRecord* tmpNode = new NodeRecord(dimensions);
00253 
00254         // get coords from childEntries and fill tmpNodes Array
00255         int i = 0;
00256         for (cXMLElement *coord = tmpElement->getFirstChild(); coord;
00257              coord = coord->getNextSibling()) {
00258 
00259             tmpNode->coords[i] = atof(coord->getNodeValue());
00260 
00261             if (fabs(tmpNode->coords[i])> max_coord) {
00262                max_coord = fabs(tmpNode->coords[i]);
00263             }
00264             i++;
00265         }
00266 
00267         // add to vector
00268         nodeRecordPool.push_back(make_pair(tmpNode, true));
00269     } // now all nodes from xml-file are in vector unusedRootNodes
00270 
00271     EV << nodeRecordPool.size()
00272        << " nodes added to vector \"nodeRecordPool\"." << endl;
00273 
00274     return (uint)ceil(max_coord);
00275 }


Member Data Documentation

adress of the node that will be created next

Referenced by createNode(), initializeUnderlay(), and migrateNode().

std::deque<IPvXAddress> SimpleNetConfigurator::killList [protected]

stores nodes scheduled to be killed

Referenced by handleTimerEvent(), and preKillNode().

std::set<int> SimpleNetConfigurator::scheduledID [protected]

stores nodeIds to prevent migration of prekilled nodes

Referenced by handleTimerEvent(), migrateNode(), and preKillNode().

send queue length of overlay terminals

Referenced by createNode(), getSendQueueLenghth(), initializeUnderlay(), and migrateNode().

Referenced by createNode(), and initializeUnderlay().

Referenced by createNode(), and initializeUnderlay().

Referenced by initializeUnderlay().

std::vector<std::pair<NodeRecord*, bool> > SimpleNetConfigurator::nodeRecordPool [protected]

number of overall created overlay terminals

Referenced by createNode(), finishUnderlay(), and initializeUnderlay().

number of overall killed overlay terminals

Referenced by finishUnderlay(), initializeUnderlay(), and preKillNode().


The documentation for this class was generated from the following files:

Generated on Fri Sep 19 13:05:08 2008 for ITM OverSim by  doxygen 1.5.5