SimpleUnderlayConfigurator Class Reference

Sets up a SimpleNetwork. More...

#include <SimpleUnderlayConfigurator.h>

Inheritance diagram for SimpleUnderlayConfigurator:

UnderlayConfigurator

List of all members.

Public Member Functions

 ~SimpleUnderlayConfigurator ()
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.
uint32_t getFieldSize ()
uint32_t getFieldDimension ()
uint32_t 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.
uint32_t 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
uint32_t sendQueueLength
 send queue length of overlay terminals
uint32_t fieldSize
int dimensions
bool fixedNodePositions
bool useXmlCoords
const char * nodeCoordinateSource
uint32_t maxCoordinate
std::vector< std::pair
< NodeRecord *, bool > > 
nodeRecordPool
int numCreated
 number of overall created overlay terminals
int numKilled
 number of overall killed overlay terminals


Detailed Description

Sets up a SimpleNetwork.

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

Definition at line 43 of file SimpleUnderlayConfigurator.h.


Constructor & Destructor Documentation

SimpleUnderlayConfigurator::~SimpleUnderlayConfigurator (  ) 

Definition at line 49 of file SimpleUnderlayConfigurator.cc.

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


Member Function Documentation

TransportAddress * SimpleUnderlayConfigurator::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.

Definition at line 107 of file SimpleUnderlayConfigurator.cc.

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

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

Saves statistics, prints simulation time.

Reimplemented from UnderlayConfigurator.

Definition at line 489 of file SimpleUnderlayConfigurator.cc.

00490 {
00491     // statistics
00492     recordScalar("Terminals added", numCreated);
00493     recordScalar("Terminals removed", numKilled);
00494 
00495     if (!isInInitPhase()) {
00496         struct timeval now, diff;
00497         gettimeofday(&now, NULL);
00498         timersub(&now, &initFinishedTime, &diff);
00499         printf("Simulation time: %li.%06li\n", diff.tv_sec, diff.tv_usec);
00500     }
00501 }

uint32_t SimpleUnderlayConfigurator::getFieldDimension (  )  [inline]

Definition at line 73 of file SimpleUnderlayConfigurator.h.

00073 { return dimensions; };

uint32_t SimpleUnderlayConfigurator::getFieldSize (  )  [inline]

Definition at line 72 of file SimpleUnderlayConfigurator.h.

00072 { return fieldSize; };

uint32_t SimpleUnderlayConfigurator::getSendQueueLenghth (  )  [inline]

Definition at line 74 of file SimpleUnderlayConfigurator.h.

00074 { return sendQueueLength; };

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

Reimplemented from UnderlayConfigurator.

Definition at line 441 of file SimpleUnderlayConfigurator.cc.

00442 {
00443     Enter_Method_Silent();
00444 
00445     // get next scheduled node and remove it from the kill list
00446     IPvXAddress addr = killList.back();
00447     killList.pop_back();
00448 
00449     SimpleNodeEntry* entry = NULL;
00450 
00451     SimpleInfo* info =
00452             dynamic_cast<SimpleInfo*> (globalNodeList->getPeerInfo(addr));
00453 
00454     if (info != NULL) {
00455         entry = info->getEntry();
00456     } else {
00457         throw cRuntimeError("SimpleNetConfigurator: Trying to kill node with "
00458                             "unknown TransportAddress!");
00459     }
00460 
00461     cGate* gate = entry->getGate();
00462     cModule* node = gate->getOwnerModule()->getParentModule();
00463 
00464     if (useXmlCoords) {
00465         nodeRecordPool[entry->getRecordIndex()].second = true;
00466     }
00467 
00468     scheduledID.erase(node->getId());
00469     globalNodeList->killPeer(addr);
00470 
00471     InterfaceEntry* ie = IPAddressResolver().interfaceTableOf(node)->
00472                                          getInterfaceByName("dummy interface");
00473     delete ie->ipv4Data();
00474 
00475     node->callFinish();
00476     node->deleteModule();
00477 
00478     delete msg;
00479 }

void SimpleUnderlayConfigurator::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.

Definition at line 58 of file SimpleUnderlayConfigurator.cc.

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

void SimpleUnderlayConfigurator::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.

Definition at line 354 of file SimpleUnderlayConfigurator.cc.

00355 {
00356     Enter_Method_Silent();
00357 
00358     SimpleNodeEntry* entry = NULL;
00359 
00360     if (addr != NULL) {
00361         SimpleInfo* info =
00362               dynamic_cast<SimpleInfo*> (globalNodeList->getPeerInfo(*addr));
00363         if (info != NULL) {
00364             entry = info->getEntry();
00365         } else {
00366             opp_error("SimpleNetConfigurator: Trying to migrate node with "
00367                       "nonexistant TransportAddress!");
00368         }
00369     } else {
00370         SimpleInfo* info = dynamic_cast<SimpleInfo*> (
00371                 globalNodeList-> getRandomPeerInfo(type.typeID));
00372         entry = info->getEntry();
00373     }
00374 
00375     cGate* gate = entry->getGate();
00376     cModule* node = gate->getOwnerModule()->getParentModule();
00377 
00378     // do not migrate node that is already scheduled
00379     if (scheduledID.count(node->getId()))
00380         return;
00381 
00382     //std::cout << "migration @ " << tmp_ip << " --> " << address << std::endl;
00383 
00384     // FIXME use only IPv4?
00385     IPvXAddress address = IPAddress(nextFreeAddress++);
00386 
00387     IPvXAddress tmp_ip = IPAddressResolver().addressOf(node);
00388     SimpleNodeEntry* newentry;
00389 
00390     int chanIndex = intuniform(0, type.channelTypesRx.size() - 1);
00391     cChannelType* rxChan = cChannelType::find(type.channelTypesRx[chanIndex].c_str());
00392     cChannelType* txChan = cChannelType::find(type.channelTypesTx[chanIndex].c_str());
00393 
00394     if (!txChan || !rxChan)
00395          opp_error("Could not find Channel Type. Most likely parameter "
00396             "channelTypesRx or channelTypes does not match the channels defined in "
00397              "channels.ned");
00398 
00399     if (useXmlCoords) {
00400        newentry = new SimpleNodeEntry(node,
00401                                       rxChan,
00402                                       txChan,
00403                                       sendQueueLength,
00404                                       entry->getNodeRecord(), entry->getRecordIndex());
00405         //newentry->getNodeRecord()->ip = address;
00406     } else {
00407         newentry = new SimpleNodeEntry(node, rxChan, txChan, fieldSize, sendQueueLength);
00408     }
00409 
00410     node->bubble("I am migrating!");
00411 
00412     //remove node from bootstrap oracle
00413     globalNodeList->killPeer(tmp_ip);
00414 
00415     SimpleUDP* simple = check_and_cast<SimpleUDP*> (gate->getOwnerModule());
00416     simple->setNodeEntry(newentry);
00417 
00418     InterfaceEntry* ie = IPAddressResolver().interfaceTableOf(node)->
00419                                       getInterfaceByName("dummy interface");
00420     delete ie->ipv4Data();
00421 
00422     // Add pseudo-Interface to node's interfaceTable
00423     IPv4InterfaceData* ifdata = new IPv4InterfaceData;
00424     ifdata->setIPAddress(address.get4());
00425     ifdata->setNetmask(IPAddress("255.255.255.255"));
00426     ie->setIPv4Data(ifdata);
00427 
00428     // create meta information
00429     SimpleInfo* newinfo = new SimpleInfo(type.typeID, node->getId());
00430     newinfo->setEntry(newentry);
00431 
00432     //add node to bootstrap oracle
00433     globalNodeList->addPeer(address, newinfo);
00434 
00435     // inform the notification board about the migration
00436     NotificationBoard* nb = check_and_cast<NotificationBoard*> (
00437                                       node->getSubmodule("notificationBoard"));
00438     nb->fireChangeNotification(NF_OVERLAY_TRANSPORTADDRESS_CHANGED);
00439 }

uint32_t SimpleUnderlayConfigurator::parseCoordFile ( const char *  nodeCoordinateSource  )  [protected]

Definition at line 235 of file SimpleUnderlayConfigurator.cc.

Referenced by initializeUnderlay().

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

void SimpleUnderlayConfigurator::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.

Definition at line 287 of file SimpleUnderlayConfigurator.cc.

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

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

Prints statistics.

Implements UnderlayConfigurator.

Definition at line 481 of file SimpleUnderlayConfigurator.cc.

Referenced by createNode(), and preKillNode().

00482 {
00483     // Updates the statistics display string.
00484     char buf[80];
00485     sprintf(buf, "%i overlay terminals", overlayTerminalCount);
00486     getDisplayString().setTagArg("t", 0, buf);
00487 }


Member Data Documentation

Definition at line 106 of file SimpleUnderlayConfigurator.h.

Referenced by createNode(), and initializeUnderlay().

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

stores nodes scheduled to be killed

Definition at line 100 of file SimpleUnderlayConfigurator.h.

Referenced by handleTimerEvent(), and preKillNode().

Definition at line 110 of file SimpleUnderlayConfigurator.h.

Referenced by initializeUnderlay().

adress of the node that will be created next

Definition at line 99 of file SimpleUnderlayConfigurator.h.

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

Definition at line 109 of file SimpleUnderlayConfigurator.h.

Referenced by createNode(), and initializeUnderlay().

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

number of overall created overlay terminals

Definition at line 115 of file SimpleUnderlayConfigurator.h.

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

number of overall killed overlay terminals

Definition at line 116 of file SimpleUnderlayConfigurator.h.

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

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

stores nodeIds to prevent migration of prekilled nodes

Definition at line 101 of file SimpleUnderlayConfigurator.h.

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

send queue length of overlay terminals

Definition at line 103 of file SimpleUnderlayConfigurator.h.

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


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

Generated on Tue Sep 8 17:27:02 2009 for OverSim by  doxygen 1.5.8