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 50 of file SimpleUnderlayConfigurator.cc.

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


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 108 of file SimpleUnderlayConfigurator.cc.

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

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

Saves statistics, prints simulation time.

Reimplemented from UnderlayConfigurator.

Definition at line 499 of file SimpleUnderlayConfigurator.cc.

00500 {
00501     // statistics
00502     recordScalar("Terminals added", numCreated);
00503     recordScalar("Terminals removed", numKilled);
00504 
00505     if (!isInInitPhase()) {
00506         struct timeval now, diff;
00507         gettimeofday(&now, NULL);
00508         timersub(&now, &initFinishedTime, &diff);
00509         printf("Simulation time: %li.%06li\n", diff.tv_sec, diff.tv_usec);
00510     }
00511 }

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 451 of file SimpleUnderlayConfigurator.cc.

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

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 59 of file SimpleUnderlayConfigurator.cc.

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

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 363 of file SimpleUnderlayConfigurator.cc.

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

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

Definition at line 236 of file SimpleUnderlayConfigurator.cc.

Referenced by initializeUnderlay().

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

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 296 of file SimpleUnderlayConfigurator.cc.

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

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

Prints statistics.

Implements UnderlayConfigurator.

Definition at line 491 of file SimpleUnderlayConfigurator.cc.

Referenced by createNode(), and preKillNode().

00492 {
00493     // Updates the statistics display string.
00494     char buf[80];
00495     sprintf(buf, "%i overlay terminals", overlayTerminalCount);
00496     getDisplayString().setTagArg("t", 0, buf);
00497 }


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 Wed May 26 16:21:19 2010 for OverSim by  doxygen 1.6.3