CoordBasedRouting.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00025 #include <fstream>
00026 #include <string>
00027 #include <cassert>
00028
00029 #include <omnetpp.h>
00030
00031 #include <GlobalNodeListAccess.h>
00032 #include <PeerInfo.h>
00033
00034 #include "CoordBasedRouting.h"
00035
00036
00037 Define_Module(CoordBasedRouting);
00038
00039 const std::string CoordBasedRouting::NOPREFIX = "NOPREFIX";
00040
00041 void CoordBasedRouting::initialize()
00042 {
00043 areaCoordinateSource = par("areaCoordinateSource");
00044 cbrStartAtDigit = par("CBRstartAtDigit");
00045 cbrStopAtDigit = par("CBRstopAtDigit");
00046 globalNodeList = GlobalNodeListAccess().get();
00047
00048
00049 std::ifstream check_for_xml_file(areaCoordinateSource);
00050 if (!check_for_xml_file) {
00051 check_for_xml_file.close();
00052 throw cRuntimeError("CBR area file not found!");
00053 return;
00054 }
00055 else {
00056 EV << "[CoordBasedRouting::initialize()]\n CBR area file '"
00057 << areaCoordinateSource << "' loaded." << endl;
00058 check_for_xml_file.close();
00059 }
00060
00061
00062 parseSource(areaCoordinateSource);
00063 }
00064
00065 void CoordBasedRouting::finish()
00066 {
00067 for (uint32_t i = 0; i < CBRAreaPool.size(); i++) {
00068 delete CBRAreaPool[i];
00069 }
00070 CBRAreaPool.clear();
00071 }
00072
00073
00074 void CoordBasedRouting::parseSource(const char* areaCoordinateSource)
00075 {
00076 cXMLElement* rootElement = ev.getXMLDocument(areaCoordinateSource);
00077
00078 xmlDimensions = atoi(rootElement->getAttribute("dimensions"));
00079
00080 for (cXMLElement *area = rootElement->getFirstChildWithTag("area"); area;
00081 area = area->getNextSiblingWithTag("area") ) {
00082 CBRArea* tmpArea = new CBRArea(xmlDimensions);
00083 for (cXMLElement *areavals = area->getFirstChild(); areavals;
00084 areavals = areavals->getNextSibling() ) {
00085 std::string tagname = std::string(areavals->getTagName());
00086 if (tagname == "min") {
00087 uint8_t currentdim = atoi(areavals->getAttribute("dimension"));
00088 double value = atof(areavals->getNodeValue());
00089 tmpArea->min[currentdim] = value;
00090 }
00091
00092 else if (tagname == "max") {
00093 uint8_t currentdim = atoi(areavals->getAttribute("dimension"));
00094 double value = atof(areavals->getNodeValue());
00095 tmpArea->max[currentdim] = value;
00096 }
00097
00098 else if (tagname == "prefix") {
00099 tmpArea->prefix = areavals->getNodeValue();
00100 }
00101 }
00102 CBRAreaPool.push_back(tmpArea);
00103 }
00104
00105 EV << "[CoordBasedRouting::parseSource()]" << endl;
00106 EV << " " << CBRAreaPool.size() << " prefix areas detected." << endl;
00107 }
00108
00109 OverlayKey CoordBasedRouting::getNodeId(const std::vector<double>& coords,
00110 uint8_t bpd, uint8_t length) const
00111 {
00112 std::string prefix = getPrefix(coords);
00113
00114
00115 if (prefix == NOPREFIX) {
00116 opp_error("[CoordBasedRouting::getNodeId()]: "
00117 "No prefix for given coords found. "
00118 "Check your area source file!");
00119 }
00120 std::string idString;
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 uint8_t startLength = (bpd * cbrStartAtDigit < length) ?
00134 (bpd * cbrStartAtDigit) : length;
00135 uint8_t beforeEnd = (startLength + prefix.length() < length) ?
00136 (startLength + prefix.length()) : length;
00137 uint8_t endPos = (bpd * cbrStopAtDigit < beforeEnd) ?
00138 (bpd * cbrStopAtDigit) : beforeEnd;
00139 uint8_t endLength = length - endPos;
00140
00141
00142 for (uint8_t i = 0; i < startLength; i++)
00143 idString += "0";
00144
00145
00146 idString += prefix;
00147 if (endPos < idString.length())
00148 idString.erase(endPos);
00149 if (length < idString.length())
00150 idString.erase(length);
00151
00152
00153 for (uint8_t i = 0; i < endLength; i++)
00154 idString += "0";
00155
00156 OverlayKey nodeId(idString, 2);
00157
00158
00159 if (startLength > 0)
00160 nodeId = nodeId.randomPrefix(length - startLength);
00161 if (endLength > 0)
00162 nodeId = nodeId.randomSuffix(endLength);
00163
00164 EV << "[CoordBasedRouting::getNodeId()]\n"
00165 <<" calculated id: " << nodeId << endl;
00166 return nodeId;
00167 }
00168
00169 std::string CoordBasedRouting::getPrefix(const std::vector<double>& coords) const
00170 {
00171 bool areaFound = false;
00172 uint32_t iter = 0;
00173
00174
00175 if (!checkDimensions(coords.size()))
00176 return NOPREFIX;
00177
00178 while (!areaFound && iter < CBRAreaPool.size()) {
00179 CBRArea* thisArea = CBRAreaPool[iter];
00180
00181
00182 areaFound = true;
00183 for (uint8_t thisdim = 0; thisdim < coords.size(); thisdim++) {
00184 if (coords[thisdim] < thisArea->min[thisdim] ||
00185 coords[thisdim] > thisArea->max[thisdim]) {
00186 areaFound = false;
00187 break;
00188 }
00189 }
00190
00191
00192
00193 if (areaFound) {
00194 EV << "[CoordBasedRouting::getPrefix()]\n"
00195 <<" calculated prefix: " << thisArea->prefix << endl;
00196 return thisArea->prefix;
00197 }
00198 iter++;
00199 }
00200
00201
00202 EV << "[CoordBasedRouting::getPrefix()]\n"
00203 << " No corresponding prefix found, check your area source file!"
00204 << endl;
00205
00206 return NOPREFIX;
00207 }
00208
00209 double CoordBasedRouting::getEuclidianDistanceByKeyAndCoords(const OverlayKey& destKey,
00210 const std::vector<double>& coords,
00211 uint8_t bpd) const
00212 {
00213 assert(!destKey.isUnspecified());
00214 uint32_t iter = 0;
00215 while (iter < CBRAreaPool.size()) {
00216 CBRArea* thisArea = CBRAreaPool[iter];
00217
00218
00219 uint8_t startbit = bpd * cbrStartAtDigit;
00220 uint8_t length = (bpd * cbrStopAtDigit - bpd * cbrStartAtDigit <
00221 (uint8_t)thisArea->prefix.length() - bpd * cbrStartAtDigit)
00222 ? (bpd * cbrStopAtDigit - bpd * cbrStartAtDigit)
00223 : (thisArea->prefix.length() - bpd * cbrStartAtDigit);
00224 if (destKey.toString(2).substr(startbit, length) ==
00225 thisArea->prefix.substr(startbit, length)) {
00226
00227 std::vector<double> areaCenterCoords;
00228 areaCenterCoords.resize(getXmlDimensions());
00229 double sumofsquares = 0;
00230 for (uint8_t dim = 0; dim < getXmlDimensions(); dim++) {
00231 areaCenterCoords[dim] =
00232 (thisArea->min[dim] + thisArea->max[dim]) / 2;
00233 sumofsquares += pow((coords[dim] - areaCenterCoords[dim]), 2);
00234 }
00235 return sqrt(sumofsquares);
00236 }
00237 iter++;
00238 }
00239
00240
00241 throw cRuntimeError("[CoordBasedRouting::"
00242 "getEuclidianDistanceByKeyAndCoords]: "
00243 "No prefix for search key found!");
00244 return -1;
00245 }
00246
00247
00248 bool CoordBasedRouting::checkDimensions(uint8_t dims) const
00249 {
00250 if (dims == xmlDimensions) {
00251 return true;
00252 } else {
00253 EV << "[CoordBasedRouting::checkDimensions()]" << endl;
00254 EV << " ERROR: Given coordinate dimensions do not match dimensions "
00255 "in the used area source file. Mapping results will be wrong."
00256 << endl;
00257 return false;
00258 }
00259 }
00260
00261
00265 CBRArea::CBRArea(uint8_t dim)
00266 {
00267 min.reserve(dim);
00268 max.reserve(dim);
00269 }
00270