/* * File: WirelessConnectivityObserver.cc * Author: thandreg * Author: jgaebler * * Created on October 16, 2012, 1:30 PM */ #include "WirelessConnectivityObserver.h" #include "NotificationInfo.h" #include #include "base/NotificationBoard.h" #include "mobility/models/MovingMobilityBase.h" #include "mobility/models/StationaryMobility.h" #include #include #include #include namespace ubeeme { namespace moversight { Define_Module(WirelessConnectivityObserver); void WirelessConnectivityObserver::initialize(int stage) { if (stage == 2) { nodeInfo.clear(); // extract topology into the cTopology object, then fill in // isIPNode, rt and ift members of nodeInfo[] extractTopology(topo, nodeInfo); // assign addresses to IPv4 nodes, and also store result in nodeInfo[].address assignAddresses(topo, nodeInfo); // add default routes to hosts (nodes with a single attachment); // also remember result in nodeInfo[].usesDefaultRoute addDefaultRoutes(topo, nodeInfo); // calculate shortest paths, and add corresponding static routes fillRoutingTables(topo, nodeInfo); // update display string setDisplayString(topo, nodeInfo); cc = dynamic_cast (simulation.getModuleByPath("channelControl")); if (!cc) { throw cRuntimeError("Could not find ChannelControl module with name 'channelControl' in the toplevel network."); }//End if EV << "Initialising WirelessConnectivityObserver" << endl; //initialize nodeList topo.extractByProperty("node"); for (int i = 0; i < (topo.getNumNodes()); i++) { //we are only interested in wireless nodes if (topo.getNode(i)->getModule()->getSubmodule("wlan", 0)) { std::string nodeName(topo.getNode(i)->getModule()->getFullName()); Node node(nodeName); node.setRadioModule(topo.getNode(i)->getModule()->getSubmodule("wlan", 0)->getSubmodule("radio", 0)); MACAddress mac; mac.setAddress(topo.getNode(i)->getModule()->getSubmodule("wlan", 0)->getSubmodule("mac", 0)->par("address").stringValue()); node.setMacAdress(mac); int isMobil = topo.getNode(i)->getModule()->getSubmodule("mobility")->findPar("updateInterval"); if (isMobil != -1) { node.setHasMobility(true); }//end if //setting event-listener to AccessPoints if (topo.getNode(i)->getModule()->getSubmodule("relayUnit", 0) && topo.getNode(i)->getModule()->getSubmodule("notificationBoard", 0)) { NotificationBoard * blackBoard = dynamic_cast (topo.getNode(i)->getModule()->getSubmodule("notificationBoard")); if (!blackBoard) { std::cerr << "Could not find NotificationBoard module with name 'notificationBoard' in AP-Node." << endl; }//end if else { //categories for notifications blackBoard->subscribe(this, NF_L2_AP_ASSOCIATED); blackBoard->subscribe(this, NF_L2_AP_DISASSOCIATED); }//end else node.setIsAccessPoint(true); }//end if // Eventlistener to Notificationboard only for WirelessNodes if (topo.getNode(i)->getModule()->getSubmodule("networkLayer", 0) && topo.getNode(i)->getModule()->getSubmodule("notificationBoard", 0)) { NotificationBoard * blackBoard = dynamic_cast (topo.getNode(i)->getModule()->getSubmodule("notificationBoard")); if (!blackBoard) { std::cerr << "Could not find NotificationBoard module with name 'notificationBoard' in wlan-Node." << endl; } else { //categories für notifications blackBoard->subscribe(this, NF_L2_ASSOCIATED_NEWAP); blackBoard->subscribe(this, NF_L2_BEACON_LOST); blackBoard->subscribe(this, NF_L2_AP_ASSOCIATED); }//End else } nodeList.push_back(node); } } //init params updateFrequency = par("updateFreq").doubleValue(); //starting Initialization2 selfTrigger = new cMessage("selfTrigger"); scheduleAt(simTime() + updateFrequency, selfTrigger); } } void WirelessConnectivityObserver::handleMessage(cMessage *msg) { //we only handly selfTrigger messages if (msg == selfTrigger) { if (simTime() <= updateFrequency) initalizeNodes(); else { for (size_t i = 0; i < nodeList.size(); i++) { updatePositons(i); updateDistance(i); timeLeft(i); std::cerr << "Name: " << nodeList.at(i).getNodeName() << endl; std::cerr << "verbundene Zeit: " << nodeList.at(i).getConnectedTime() << endl; std::cerr << "verbleibene Zeit: " << nodeList.at(i).getTimeLeft() << endl; std::cerr << "verbunden mit: " << nodeList.at(i).getConnectedWith() << endl; std::cerr << "Speed: " << nodeList.at(i).getCurrentSpeed() << endl; std::cerr << "num equal: " << nodeList.at(i).getNumEqualModules() << endl << endl; }//End for }//End else scheduleAt(simTime() + updateFrequency, selfTrigger); }//end if } void WirelessConnectivityObserver::initalizeNodes() { //initial the position of the nodes for (size_t i = 0; i < nodeList.size(); i++) { updatePositons(i); }//end for //initial the distance of the nodes for (size_t i = 0; i < nodeList.size(); i++) { Node & node = nodeList[i]; cModule * radioModule = node.getRadioModule(); if (radioModule != NULL) { double transmissionPower = radioModule->par("transmitterPower"); double transmissionRange = calcDistFreeSpace(i, transmissionPower); node.setTransmissionRange(transmissionRange); for (size_t z = 0; z < nodeList.size(); z++) { if (i != z && node.isAccessPoint() != nodeList[z].isAccessPoint()) { double distance = node.getCurrentPosition().distance(nodeList[z].getCurrentPosition()); Distance temp(nodeList[z].getNodeName(), distance); node.getNodeDistanceList().push_back(temp); }//End if }//end for }//end if }//end for } double WirelessConnectivityObserver::calcDistFreeSpace(size_t nodesIndex, double transmissionPower) { //the carrier frequency used double carrierFrequency = getChannelControlPar("carrierFrequency"); //path loss coefficient double alpha = getChannelControlPar("alpha"); double waveLength = (SPEED_OF_LIGHT / carrierFrequency); //minimum power level to be able to physically receive a signal double minReceivePower = FWMath::dBm2mW(double(nodeList.at(nodesIndex).getRadioModule()->par("sensitivity"))); double interfDistance = pow(waveLength * waveLength * transmissionPower / (16.0 * M_PI * M_PI * minReceivePower), 1.0 / alpha); return interfDistance; } void WirelessConnectivityObserver::updatePositons(size_t i) { Node & node = nodeList[i]; cModule * radio = node.getRadioModule(); if (radio != NULL) { cModule* help = radio->getParentModule()->getParentModule()->getSubmodule("mobility", 0); if (node.hasMobility()) { //All mobilities inherit from same modules MovingMobilityBase* mod = (MovingMobilityBase*) help; node.setCurrentPosition(mod->getCurrentPosition()); node.setCurrentSpeed(mod->getCurrentSpeed() / 10); }//end if else { // when there is no mobility StationaryMobility* mod = (StationaryMobility*) help; node.setCurrentPosition(mod->getCurrentPosition()); node.setCurrentSpeed(Coord::ZERO); }//end else } } void WirelessConnectivityObserver::updateDistance(size_t nodeNum) { Node & node = nodeList[nodeNum]; Node::DistanceList & distanceList = node.getNodeDistanceList(); for (size_t i = 0; i < distanceList.size(); i++) { std::string neighbourNodeName = distanceList.at(i).getNodeName(); //found myself if (node.getNodeName().compare(neighbourNodeName) == 0) continue; //found position of neighbour Coord neighbourPos; for (size_t z = 0; z < nodeList.size(); z++) { //node found? if (nodeList[z].getNodeName().compare(neighbourNodeName) == 0) { neighbourPos = nodeList[z].getCurrentPosition(); }//End if }//End for Coord selfPos = node.getCurrentPosition(); double distance = selfPos.distance(neighbourPos); distanceList[i].setDistance(distance); }//end for } void WirelessConnectivityObserver::timeLeft(size_t nodeNum) { bool connected = false; Node & node = nodeList[nodeNum]; size_t neighbourNodeNum = 0; node.setTimeLeft(0); //test, to avoid errors if (node.getNumEqualModules() == 0) { return; }//End if if (node.getConnectedWith().compare("") != 0) { connected = true; }//End if if (!connected) { node.setConnectedTime(0); }//End if else { //searching for connected Node while (node.getConnectedWith().compare(nodeList.at(neighbourNodeNum).getNodeName()) != 0) { neighbourNodeNum++; }//End while node.setConnectedTime(node.getConnectedTime() + updateFrequency); Node connectedNode = nodeList.at(neighbourNodeNum); double distance = node.getCurrentPosition().distance(connectedNode.getCurrentPosition()); Coord speed1 = connectedNode.getCurrentSpeed(); Coord speed2 = node.getCurrentSpeed(); Coord Pos = node.getCurrentPosition(); while (node.getTransmissionRange() >= distance) { speed1 += connectedNode.getCurrentSpeed(); speed2 += node.getCurrentSpeed(); if (speed1 == speed2 && speed1 == Coord::ZERO) { //std::cerr<getFullPath().find(nodeName.c_str()) != details->getFullPath().npos) { findObject = true; // set Associated AccessPoint for Wireless Host nodeList[i].setConnectedWith(nodeList[modulNumber].getNodeName()); // set Associatetd Wireless Host for AP nodeList[modulNumber].setConnectedWith(nodeList[i].getNodeName()); break; }//end if i++; }//End while }//end if if (!findObject) { //only for wireless AccessPoints const NotificationInfo * notiInfo = (NotificationInfo * const) details; if (notiInfo) { i = 0; //compares MacAdresses of Nodes and finds the notification giving object while (notiInfo->getApAddress() != nodeList.at(i).getMacAdress() && i < nodeList.size()) i++; } // APs changes notification first, so save the name of AP to associated AP with new associated WirelessNode //number of the ap within the nodeList modulNumber = i; }//end else switch (category) { //emitted by Whost case NF_L2_ASSOCIATED_NEWAP: std::cerr << nodeList.at(i).getNodeName() << " associated with " << nodeList.at(modulNumber).getNodeName() << endl; addRoute(i); break; // emitted by WHOST case NF_L2_BEACON_LOST: std::cerr << "wirelessNode " << nodeList.at(i).getNodeName() << " dissociated" << endl; nodeList.at(i).setConnectedWith(""); break; //emitted by AP case NF_L2_AP_ASSOCIATED: std::cerr << nodeList.at(i).getNodeName() << " associated" << endl; break; //probably did not work with this inet?! case NF_L2_AP_DISASSOCIATED: std::cerr << nodeList.at(i).getNodeName() << " dissociated" << endl; break; } } void WirelessConnectivityObserver::addRoute(size_t numNode) { Node & node = nodeList[numNode]; //a wHost std::string accessPointName = node.getConnectedWith(); //findet den node in der topologie int findNode = 0; while (findNode < topo.getNumNodes() && node.getNodeName().compare(topo.getNode(findNode)->getModule()->getFullName()) != 0) { findNode++; }//end while cTopology::Node *destNode = topo.getNode(findNode); IPv4Address destAddr = nodeInfo[findNode].address; std::string destModName = destNode->getModule()->getFullName(); //findet den passenden AccessPoint in topo int findAP = 0; while (findAP < topo.getNumNodes()) { if (accessPointName.compare(topo.getNode(findAP)->getModule()->getFullPath()) == 0) { destNode = topo.getNode(findAP); }//End if findAP++; } // calculate shortest paths from everywhere towards destNode topo.calculateUnweightedSingleShortestPathsTo(destNode); // add route (with host=destNode) to every routing table in the network // (excepting nodes with only one interface -- there we'll set up a default route) for (int j = 0; j < topo.getNumNodes(); j++) { if (findNode == j) continue; if (!nodeInfo[j].isIPNode) continue; cTopology::Node *atNode = topo.getNode(j); if (atNode->getNumPaths() == 0) continue; // not connected if (nodeInfo[j].usesDefaultRoute) continue; // already added default route here IPv4Address atAddr = nodeInfo[j].address; IInterfaceTable *ift = nodeInfo[j].ift; int outputGateId = atNode->getPath(0)->getLocalGate()->getId(); InterfaceEntry *ie = ift->getInterfaceByNodeOutputGateId(outputGateId); if (!ie) error("%s has no interface for output gate id %d", ift->getFullPath().c_str(), outputGateId); EV << " from " << atNode->getModule()->getFullName() << "=" << IPv4Address(atAddr); EV << " towards " << destModName << "=" << IPv4Address(destAddr) << " interface " << ie->getName() << endl; // delete old route IRoutingTable *rt = nodeInfo[j].rt; int i = rt->getNumRoutes(); for (; i > 0; i--) { IPv4Route* x = rt->getRoute(i - 1); if (x->getDestination() == destAddr) rt->deleteRoute(x); } // add new route IPv4Route *e = new IPv4Route(); e->setDestination(destAddr); e->setNetmask(IPv4Address(255, 255, 255, 255)); // full match needed e->setInterface(ie); e->setSource(IPv4Route::MANUAL); rt->addRoute(e); } } cPar & WirelessConnectivityObserver::getChannelControlPar(const char *parName) { return dynamic_cast (cc)->par(parName); } } // end namespace moversight } // end namespace ubeeme