blob: 63147a53d418f9bdcbe16f0de7be73f2e8dfde65 [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014 University of Memphis,
4 * Regents of the University of California
5 *
6 * This file is part of NLSR (Named-data Link State Routing).
7 * See AUTHORS.md for complete list of NLSR authors and contributors.
8 *
9 * NLSR is free software: you can redistribute it and/or modify it under the terms
10 * of the GNU General Public License as published by the Free Software Foundation,
11 * either version 3 of the License, or (at your option) any later version.
12 *
13 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
14 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * \author A K M Mahmudul Hoque <ahoque1@memphis.edu>
21 *
22 **/
akmhoque53353462014-04-22 08:43:45 -050023#include <iostream>
24#include <cmath>
25#include "lsdb.hpp"
26#include "routing-table-calculator.hpp"
27#include "map.hpp"
28#include "lsa.hpp"
29#include "nexthop.hpp"
30#include "nlsr.hpp"
31
32namespace nlsr {
33
34using namespace std;
35
36void
37RoutingTableCalculator::allocateAdjMatrix()
38{
39 adjMatrix = new double*[numOfRouter];
akmhoque157b0a42014-05-13 00:26:37 -050040 for (int i = 0; i < numOfRouter; ++i) {
akmhoque53353462014-04-22 08:43:45 -050041 adjMatrix[i] = new double[numOfRouter];
42 }
43}
44
45void
46RoutingTableCalculator::initMatrix()
47{
akmhoque157b0a42014-05-13 00:26:37 -050048 for (int i = 0; i < numOfRouter; i++) {
49 for (int j = 0; j < numOfRouter; j++) {
akmhoque53353462014-04-22 08:43:45 -050050 adjMatrix[i][j] = 0;
akmhoque157b0a42014-05-13 00:26:37 -050051 }
akmhoque53353462014-04-22 08:43:45 -050052 }
53}
54
55void
56RoutingTableCalculator::makeAdjMatrix(Nlsr& pnlsr, Map pMap)
57{
58 std::list<AdjLsa> adjLsdb = pnlsr.getLsdb().getAdjLsdb();
59 for (std::list<AdjLsa>::iterator it = adjLsdb.begin();
akmhoque157b0a42014-05-13 00:26:37 -050060 it != adjLsdb.end() ; it++) {
akmhoque31d1d4b2014-05-05 22:08:14 -050061 int row = pMap.getMappingNoByRouterName((*it).getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -050062 std::list<Adjacent> adl = (*it).getAdl().getAdjList();
63 for (std::list<Adjacent>::iterator itAdl = adl.begin();
akmhoque157b0a42014-05-13 00:26:37 -050064 itAdl != adl.end() ; itAdl++) {
akmhoque31d1d4b2014-05-05 22:08:14 -050065 int col = pMap.getMappingNoByRouterName((*itAdl).getName());
akmhoque53353462014-04-22 08:43:45 -050066 double cost = (*itAdl).getLinkCost();
akmhoque157b0a42014-05-13 00:26:37 -050067 if ((row >= 0 && row < numOfRouter) && (col >= 0 && col < numOfRouter)) {
akmhoque53353462014-04-22 08:43:45 -050068 adjMatrix[row][col] = cost;
69 }
70 }
71 }
72}
73
74void
75RoutingTableCalculator::printAdjMatrix()
76{
akmhoque157b0a42014-05-13 00:26:37 -050077 for (int i = 0; i < numOfRouter; i++) {
78 for (int j = 0; j < numOfRouter; j++) {
akmhoque53353462014-04-22 08:43:45 -050079 printf("%f ", adjMatrix[i][j]);
akmhoque157b0a42014-05-13 00:26:37 -050080 }
akmhoque53353462014-04-22 08:43:45 -050081 printf("\n");
82 }
83}
84
85void
86RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
87{
akmhoque157b0a42014-05-13 00:26:37 -050088 for (int i = 0; i < numOfRouter; i++) {
89 if (i == link) {
akmhoque53353462014-04-22 08:43:45 -050090 adjMatrix[source][i] = linkCost;
91 }
akmhoque157b0a42014-05-13 00:26:37 -050092 else {
akmhoque53353462014-04-22 08:43:45 -050093 adjMatrix[source][i] = 0;
94 }
95 }
96}
97
98int
99RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
100{
101 int noLink = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500102 for (int i = 0; i < numOfRouter; i++) {
103 if (adjMatrix[sRouter][i] > 0) {
akmhoque53353462014-04-22 08:43:45 -0500104 noLink++;
105 }
106 }
107 return noLink;
108}
109
110void
111RoutingTableCalculator::getLinksFromAdjMatrix(int* links,
112 double* linkCosts, int source)
113{
114 int j = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500115 for (int i = 0; i < numOfRouter; i++) {
116 if (adjMatrix[source][i] > 0) {
akmhoque53353462014-04-22 08:43:45 -0500117 links[j] = i;
118 linkCosts[j] = adjMatrix[source][i];
119 j++;
120 }
121 }
122}
123
124void
125RoutingTableCalculator::freeAdjMatrix()
126{
akmhoque157b0a42014-05-13 00:26:37 -0500127 for (int i = 0; i < numOfRouter; ++i) {
akmhoque53353462014-04-22 08:43:45 -0500128 delete [] adjMatrix[i];
129 }
130 delete [] adjMatrix;
131}
132
133
134void
135RoutingTableCalculator::allocateLinks()
136{
137 links = new int[vNoLink];
138}
139
140void
141RoutingTableCalculator::allocateLinkCosts()
142{
143 linkCosts = new double[vNoLink];
144}
145
146
147void
148RoutingTableCalculator::freeLinks()
149{
150 delete [] links;
151}
152void
153RoutingTableCalculator::freeLinksCosts()
154{
155 delete [] linkCosts;
156}
157
158void
159LinkStateRoutingTableCalculator::calculatePath(Map& pMap,
160 RoutingTable& rt, Nlsr& pnlsr)
161{
162 std::cout << "LinkStateRoutingTableCalculator::calculatePath Called" <<
163 std::endl;
164 allocateAdjMatrix();
165 initMatrix();
166 makeAdjMatrix(pnlsr, pMap);
167 std::cout << pMap;
168 printAdjMatrix();
akmhoque31d1d4b2014-05-05 22:08:14 -0500169 int sourceRouter = pMap.getMappingNoByRouterName(pnlsr.getConfParameter().getRouterPrefix());
akmhoque53353462014-04-22 08:43:45 -0500170 //int noLink=getNumOfLinkfromAdjMatrix(sourceRouter);
171 allocateParent();
172 allocateDistance();
akmhoque157b0a42014-05-13 00:26:37 -0500173 if (pnlsr.getConfParameter().getMaxFacesPerPrefix() == 1) {
akmhoque53353462014-04-22 08:43:45 -0500174 // Single Path
175 doDijkstraPathCalculation(sourceRouter);
176 // print all ls path -- debugging purpose
177 printAllLsPath(sourceRouter);
178 // update routing table
179 addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
180 }
akmhoque157b0a42014-05-13 00:26:37 -0500181 else {
akmhoque53353462014-04-22 08:43:45 -0500182 // Multi Path
183 setNoLink(getNumOfLinkfromAdjMatrix(sourceRouter));
184 allocateLinks();
185 allocateLinkCosts();
186 getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500187 for (int i = 0 ; i < vNoLink; i++) {
akmhoque53353462014-04-22 08:43:45 -0500188 adjustAdMatrix(sourceRouter, links[i], linkCosts[i]);
189 printAdjMatrix();
190 doDijkstraPathCalculation(sourceRouter);
191 // print all ls path -- debugging purpose
192 printAllLsPath(sourceRouter);
193 //update routing table
194 addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
195 }
196 freeLinks();
197 freeLinksCosts();
198 }
199 freeParent();
200 freeDistance();
201 freeAdjMatrix();
202}
203
204void
205LinkStateRoutingTableCalculator::doDijkstraPathCalculation(int sourceRouter)
206{
207 int i;
208 int v, u;
209 int* Q = new int[numOfRouter];
210 int head = 0;
211 /* Initiate the Parent */
akmhoque157b0a42014-05-13 00:26:37 -0500212 for (i = 0 ; i < numOfRouter; i++) {
akmhoque53353462014-04-22 08:43:45 -0500213 m_parent[i] = EMPTY_PARENT;
214 m_distance[i] = INF_DISTANCE;
215 Q[i] = i;
216 }
akmhoque157b0a42014-05-13 00:26:37 -0500217 if (sourceRouter != NO_MAPPING_NUM) {
akmhoque53353462014-04-22 08:43:45 -0500218 m_distance[sourceRouter] = 0;
219 sortQueueByDistance(Q, m_distance, head, numOfRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500220 while (head < numOfRouter) {
akmhoque53353462014-04-22 08:43:45 -0500221 u = Q[head];
akmhoque157b0a42014-05-13 00:26:37 -0500222 if (m_distance[u] == INF_DISTANCE) {
akmhoque53353462014-04-22 08:43:45 -0500223 break;
224 }
akmhoque157b0a42014-05-13 00:26:37 -0500225 for (v = 0 ; v < numOfRouter; v++) {
226 if (adjMatrix[u][v] > 0) {
227 if (isNotExplored(Q, v, head + 1, numOfRouter)) {
228 if (m_distance[u] + adjMatrix[u][v] < m_distance[v]) {
akmhoque53353462014-04-22 08:43:45 -0500229 m_distance[v] = m_distance[u] + adjMatrix[u][v] ;
230 m_parent[v] = u;
231 }
232 }
233 }
234 }
235 head++;
236 sortQueueByDistance(Q, m_distance, head, numOfRouter);
237 }
238 }
239 delete [] Q;
240}
241
242void
243LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(Nlsr& pnlsr,
244 RoutingTable& rt, Map& pMap, int sourceRouter)
245{
246 std::cout <<
247 "LinkStateRoutingTableCalculator::addAllNextHopsToRoutingTable Called";
248 std::cout << std::endl;
249 int nextHopRouter = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500250 for (int i = 0; i < numOfRouter ; i++) {
251 if (i != sourceRouter) {
akmhoque53353462014-04-22 08:43:45 -0500252 nextHopRouter = getLsNextHop(i, sourceRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500253 if (nextHopRouter != NO_NEXT_HOP) {
akmhoque53353462014-04-22 08:43:45 -0500254 double routeCost = m_distance[i];
akmhoque31d1d4b2014-05-05 22:08:14 -0500255 ndn::Name nextHopRouterName = pMap.getRouterNameByMappingNo(nextHopRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500256 std::string nextHopFace =
257 pnlsr.getAdjacencyList().getAdjacent(nextHopRouterName).getConnectingFaceUri();
akmhoque53353462014-04-22 08:43:45 -0500258 std::cout << "Dest Router: " << pMap.getRouterNameByMappingNo(i) << std::endl;
259 std::cout << "Next hop Router: " << nextHopRouterName << std::endl;
akmhoque157b0a42014-05-13 00:26:37 -0500260 std::cout << "Next hop Face: " << nextHopFace << std::endl;
akmhoque53353462014-04-22 08:43:45 -0500261 std::cout << "Route Cost: " << routeCost << std::endl;
262 std::cout << std::endl;
263 // Add next hop to routing table
akmhoque157b0a42014-05-13 00:26:37 -0500264 NextHop nh(nextHopFace, routeCost);
akmhoque53353462014-04-22 08:43:45 -0500265 rt.addNextHop(pMap.getRouterNameByMappingNo(i), nh);
266 }
267 }
268 }
269}
270
271int
272LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
273{
274 int nextHop = NO_NEXT_HOP;
akmhoque157b0a42014-05-13 00:26:37 -0500275 while (m_parent[dest] != EMPTY_PARENT) {
akmhoque53353462014-04-22 08:43:45 -0500276 nextHop = dest;
277 dest = m_parent[dest];
278 }
akmhoque157b0a42014-05-13 00:26:37 -0500279 if (dest != source) {
akmhoque53353462014-04-22 08:43:45 -0500280 nextHop = NO_NEXT_HOP;
281 }
282 return nextHop;
283}
284
285void
286LinkStateRoutingTableCalculator::printAllLsPath(int sourceRouter)
287{
288 std::cout << "LinkStateRoutingTableCalculator::printAllLsPath Called" <<
289 std::endl;
290 std::cout << "Source Router: " << sourceRouter << std::endl;
akmhoque157b0a42014-05-13 00:26:37 -0500291 for (int i = 0; i < numOfRouter ; i++) {
292 if (i != sourceRouter) {
akmhoque53353462014-04-22 08:43:45 -0500293 printLsPath(i);
294 std::cout << std::endl;
295 }
296 }
297}
298
299void
300LinkStateRoutingTableCalculator::printLsPath(int destRouter)
301{
akmhoque157b0a42014-05-13 00:26:37 -0500302 if (m_parent[destRouter] != EMPTY_PARENT) {
akmhoque53353462014-04-22 08:43:45 -0500303 printLsPath(m_parent[destRouter]);
304 }
305 std:: cout << " " << destRouter;
306}
307
308void
309LinkStateRoutingTableCalculator::sortQueueByDistance(int* Q,
310 double* dist, int start, int element)
311{
akmhoque157b0a42014-05-13 00:26:37 -0500312 for (int i = start ; i < element ; i++) {
313 for (int j = i + 1; j < element; j++) {
314 if (dist[Q[j]] < dist[Q[i]]) {
akmhoque53353462014-04-22 08:43:45 -0500315 int tempU = Q[j];
316 Q[j] = Q[i];
317 Q[i] = tempU;
318 }
319 }
320 }
321}
322
323int
324LinkStateRoutingTableCalculator::isNotExplored(int* Q,
325 int u, int start, int element)
326{
327 int ret = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500328 for (int i = start; i < element; i++) {
329 if (Q[i] == u) {
akmhoque53353462014-04-22 08:43:45 -0500330 ret = 1;
331 break;
332 }
333 }
334 return ret;
335}
336
337void
338LinkStateRoutingTableCalculator::allocateParent()
339{
340 m_parent = new int[numOfRouter];
341}
342
343void
344LinkStateRoutingTableCalculator::allocateDistance()
345{
346 m_distance = new double[numOfRouter];
347}
348
349void
350LinkStateRoutingTableCalculator::freeParent()
351{
352 delete [] m_parent;
353}
354
355void LinkStateRoutingTableCalculator::freeDistance()
356{
357 delete [] m_distance;
358}
359
360
361
362void
363HypRoutingTableCalculator::calculatePath(Map& pMap,
364 RoutingTable& rt, Nlsr& pnlsr)
365{
366 makeAdjMatrix(pnlsr, pMap);
akmhoque31d1d4b2014-05-05 22:08:14 -0500367 ndn::Name routerName = pnlsr.getConfParameter().getRouterPrefix();
akmhoque53353462014-04-22 08:43:45 -0500368 int sourceRouter = pMap.getMappingNoByRouterName(routerName);
369 int noLink = getNumOfLinkfromAdjMatrix(sourceRouter);
370 setNoLink(noLink);
371 allocateLinks();
372 allocateLinkCosts();
373 getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500374 for (int i = 0 ; i < numOfRouter ; ++i) {
akmhoque53353462014-04-22 08:43:45 -0500375 int k = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500376 if (i != sourceRouter) {
akmhoque53353462014-04-22 08:43:45 -0500377 allocateLinkFaces();
378 allocateDistanceToNeighbor();
379 allocateDistFromNbrToDest();
akmhoque157b0a42014-05-13 00:26:37 -0500380 for (int j = 0; j < vNoLink; j++) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500381 ndn::Name nextHopRouterName = pMap.getRouterNameByMappingNo(links[j]);
akmhoque157b0a42014-05-13 00:26:37 -0500382 std::string nextHopFaceUri =
383 pnlsr.getAdjacencyList().getAdjacent(nextHopRouterName).getConnectingFaceUri();
akmhoque53353462014-04-22 08:43:45 -0500384 double distToNbr = getHyperbolicDistance(pnlsr, pMap,
385 sourceRouter, links[j]);
386 double distToDestFromNbr = getHyperbolicDistance(pnlsr,
387 pMap, links[j], i);
akmhoque157b0a42014-05-13 00:26:37 -0500388 if (distToDestFromNbr >= 0) {
389 m_linkFaceUris[k] = nextHopFaceUri;
akmhoque53353462014-04-22 08:43:45 -0500390 m_distanceToNeighbor[k] = distToNbr;
391 m_distFromNbrToDest[k] = distToDestFromNbr;
392 k++;
393 }
394 }
395 addHypNextHopsToRoutingTable(pnlsr, pMap, rt, k, i);
396 freeLinkFaces();
397 freeDistanceToNeighbor();
398 freeDistFromNbrToDest();
399 }
400 }
401 freeLinks();
402 freeLinksCosts();
403 freeAdjMatrix();
404}
405
406void
407HypRoutingTableCalculator::addHypNextHopsToRoutingTable(Nlsr& pnlsr, Map& pMap,
408 RoutingTable& rt, int noFaces, int dest)
409{
akmhoque157b0a42014-05-13 00:26:37 -0500410 for (int i = 0 ; i < noFaces ; ++i) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500411 ndn::Name destRouter = pMap.getRouterNameByMappingNo(dest);
akmhoque157b0a42014-05-13 00:26:37 -0500412 NextHop nh(m_linkFaceUris[i], m_distFromNbrToDest[i]);
akmhoque53353462014-04-22 08:43:45 -0500413 rt.addNextHop(destRouter, nh);
akmhoque157b0a42014-05-13 00:26:37 -0500414 if (m_isDryRun) {
akmhoque53353462014-04-22 08:43:45 -0500415 rt.addNextHopToDryTable(destRouter, nh);
416 }
417 }
418}
419
420double
421HypRoutingTableCalculator::getHyperbolicDistance(Nlsr& pnlsr,
422 Map& pMap, int src, int dest)
423{
424 double distance = 0.0;
akmhoque31d1d4b2014-05-05 22:08:14 -0500425 ndn::Name srcRouterKey = pMap.getRouterNameByMappingNo(src);
426 srcRouterKey.append("coordinate");
427 ndn::Name destRouterKey = pMap.getRouterNameByMappingNo(dest);
428 destRouterKey.append("coordinate");
akmhoqueb6450b12014-04-24 00:01:03 -0500429 double srcRadius = (pnlsr.getLsdb().findCoordinateLsa(
430 srcRouterKey))->getCorRadius();
431 double srcTheta = (pnlsr.getLsdb().findCoordinateLsa(
432 srcRouterKey))->getCorTheta();
433 double destRadius = (pnlsr.getLsdb().findCoordinateLsa(
434 destRouterKey))->getCorRadius();
435 double destTheta = (pnlsr.getLsdb().findCoordinateLsa(
436 destRouterKey))->getCorTheta();
akmhoque53353462014-04-22 08:43:45 -0500437 double diffTheta = fabs(srcTheta - destTheta);
akmhoque157b0a42014-05-13 00:26:37 -0500438 if (diffTheta > MATH_PI) {
akmhoque53353462014-04-22 08:43:45 -0500439 diffTheta = 2 * MATH_PI - diffTheta;
440 }
akmhoque157b0a42014-05-13 00:26:37 -0500441 if (srcRadius != -1 && destRadius != -1) {
442 if (diffTheta == 0) {
akmhoque53353462014-04-22 08:43:45 -0500443 distance = fabs(srcRadius - destRadius);
akmhoque157b0a42014-05-13 00:26:37 -0500444 }
445 else {
akmhoque53353462014-04-22 08:43:45 -0500446 distance = acosh((cosh(srcRadius) * cosh(destRadius)) -
447 (sinh(srcRadius) * sinh(destRadius) * cos(diffTheta)));
akmhoque157b0a42014-05-13 00:26:37 -0500448 }
akmhoque53353462014-04-22 08:43:45 -0500449 }
akmhoque157b0a42014-05-13 00:26:37 -0500450 else {
akmhoque53353462014-04-22 08:43:45 -0500451 distance = -1;
452 }
453 return distance;
454}
455
456void
457HypRoutingTableCalculator::allocateLinkFaces()
458{
akmhoque157b0a42014-05-13 00:26:37 -0500459 m_linkFaceUris.reserve(vNoLink);
akmhoque53353462014-04-22 08:43:45 -0500460}
461
462void
463HypRoutingTableCalculator::allocateDistanceToNeighbor()
464{
465 m_distanceToNeighbor = new double[vNoLink];
466}
467
468void
469HypRoutingTableCalculator::allocateDistFromNbrToDest()
470{
471 m_distFromNbrToDest = new double[vNoLink];
472}
473
474void
475HypRoutingTableCalculator::freeLinkFaces()
476{
akmhoque157b0a42014-05-13 00:26:37 -0500477 m_linkFaceUris.clear();
akmhoque53353462014-04-22 08:43:45 -0500478}
479
480void
481HypRoutingTableCalculator::freeDistanceToNeighbor()
482{
483 delete [] m_distanceToNeighbor;
484}
485
486void
487HypRoutingTableCalculator::freeDistFromNbrToDest()
488{
489 delete [] m_distFromNbrToDest;
490}
491
492}//namespace nlsr