Files
scandocs/uni/masterarbeit/source/moversight/simutils/wirelessConnectivityObserver/WirelessConnectivityObserver.cc
2014-06-30 13:58:10 +02:00

485 lines
19 KiB
C++

/*
* File: WirelessConnectivityObserver.cc
* Author: thandreg
* Author: jgaebler
*
* Created on October 16, 2012, 1:30 PM
*/
#include "WirelessConnectivityObserver.h"
#include "NotificationInfo.h"
#include <FWMath.h>
#include "base/NotificationBoard.h"
#include "mobility/models/MovingMobilityBase.h"
#include "mobility/models/StationaryMobility.h"
#include <IRoutingTable.h>
#include <IInterfaceTable.h>
#include <IPvXAddressResolver.h>
#include <IPv4InterfaceData.h>
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<IChannelControl *> (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<NotificationBoard *> (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<NotificationBoard *> (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<<node.getNodeName()<<" ist undefiniert lange noch verbunden"<<endl;
return;
}
else {
Pos = Pos + speed1 + speed2;
distance = connectedNode.getCurrentPosition().distance(Pos);
}
node.setTimeLeft(node.getTimeLeft() + updateFrequency);
}//End while
//std::cerr<<node.getNodeName()<<" ist vorraussichtlich noch "<<node.getTimeLeft()<<" sec verbunden"<<endl;
}//End else
}
void
WirelessConnectivityObserver::receiveChangeNotification(int category, const cObject * details) {
size_t i = 0;
bool findObject = false;
std::string nodeName = nodeList.at(i).getNodeName();
// finds the the notification giving Object to assign wlan modul
// only for wireless Nodes
if (details) {
while (i < nodeList.size()) {
if (details->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<cModule *> (cc)->par(parName);
}
} // end namespace moversight
} // end namespace ubeeme