blob: c6499f7dc5979adbe242b647ab82cbf6ef4eceb3 [file] [log] [blame]
#include <iostream>
#include <cmath>
#include "nlsr_lsdb.hpp"
#include "nlsr_rtc.hpp"
#include "nlsr_map.hpp"
#include "nlsr_lsa.hpp"
#include "nlsr_nexthop.hpp"
#include "nlsr.hpp"
#include "utility/nlsr_logger.hpp"
#define THIS_FILE "nlsr_rtc.cpp"
namespace nlsr
{
using namespace std;
void
RoutingTableCalculator::allocateAdjMatrix()
{
adjMatrix = new double*[numOfRouter];
for(int i = 0; i < numOfRouter; ++i)
{
adjMatrix[i] = new double[numOfRouter];
}
}
void
RoutingTableCalculator::initMatrix()
{
for(int i=0; i<numOfRouter; i++)
{
for(int j=0; j<numOfRouter; j++)
adjMatrix[i][j]=0;
}
}
void
RoutingTableCalculator::makeAdjMatrix(Nlsr& pnlsr, Map pMap)
{
std::list<AdjLsa> adjLsdb=pnlsr.getLsdb().getAdjLsdb();
for( std::list<AdjLsa>::iterator it=adjLsdb.begin();
it!= adjLsdb.end() ; it++)
{
string linkStartRouter=(*it).getOrigRouter();
int row=pMap.getMappingNoByRouterName(linkStartRouter);
std::list<Adjacent> adl=(*it).getAdl().getAdjList();
for( std::list<Adjacent>::iterator itAdl=adl.begin();
itAdl!= adl.end() ; itAdl++)
{
string linkEndRouter=(*itAdl).getName();
int col=pMap.getMappingNoByRouterName(linkEndRouter);
double cost=(*itAdl).getLinkCost();
if ( (row >= 0 && row<numOfRouter) && (col >= 0 && col<numOfRouter) )
{
adjMatrix[row][col]=cost;
}
}
}
}
void
RoutingTableCalculator::printAdjMatrix()
{
for(int i=0; i<numOfRouter; i++)
{
for(int j=0; j<numOfRouter; j++)
printf("%f ",adjMatrix[i][j]);
printf("\n");
}
}
void
RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
{
for ( int i = 0; i < numOfRouter; i++ )
{
if ( i == link )
{
adjMatrix[source][i]=linkCost;
}
else
{
adjMatrix[source][i]=0;
}
}
}
int
RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
{
int noLink=0;
for(int i=0; i<numOfRouter; i++)
{
if ( adjMatrix[sRouter][i] > 0 )
{
noLink++;
}
}
return noLink;
}
void
RoutingTableCalculator::getLinksFromAdjMatrix(int *links,
double *linkCosts, int source)
{
int j=0;
for (int i=0; i <numOfRouter; i++)
{
if ( adjMatrix[source][i] > 0 )
{
links[j]=i;
linkCosts[j]=adjMatrix[source][i];
j++;
}
}
}
void
RoutingTableCalculator::freeAdjMatrix()
{
for(int i = 0; i < numOfRouter; ++i)
{
delete [] adjMatrix[i];
}
delete [] adjMatrix;
}
void
RoutingTableCalculator::allocateLinks()
{
links=new int[vNoLink];
}
void RoutingTableCalculator::allocateLinkCosts()
{
linkCosts=new double[vNoLink];
}
void
RoutingTableCalculator::freeLinks()
{
delete [] links;
}
void
RoutingTableCalculator::freeLinksCosts()
{
delete [] linkCosts;
}
void
LinkStateRoutingTableCalculator::calculatePath(Map& pMap,
RoutingTable& rt, Nlsr& pnlsr)
{
cout<<"LinkStateRoutingTableCalculator::calculatePath Called"<<endl;
allocateAdjMatrix();
initMatrix();
makeAdjMatrix(pnlsr,pMap);
cout<<pMap;
printAdjMatrix();
string routerName=pnlsr.getConfParameter().getRouterPrefix();
int sourceRouter=pMap.getMappingNoByRouterName(routerName);
int noLink=getNumOfLinkfromAdjMatrix(sourceRouter);
allocateParent();
allocateDistance();
if ( pnlsr.getConfParameter().getMaxFacesPerPrefix() == 1 )
{
// Single Path
doDijkstraPathCalculation(sourceRouter);
// print all ls path -- debugging purpose
printAllLsPath(sourceRouter);
// update routing table
addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
}
else
{
// Multi Path
setNoLink(getNumOfLinkfromAdjMatrix(sourceRouter));
allocateLinks();
allocateLinkCosts();
getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
for (int i=0 ; i < vNoLink; i++)
{
adjustAdMatrix(sourceRouter,links[i], linkCosts[i]);
printAdjMatrix();
doDijkstraPathCalculation(sourceRouter);
// print all ls path -- debugging purpose
printAllLsPath(sourceRouter);
//update routing table
addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
}
freeLinks();
freeLinksCosts();
}
freeParent();
freeDistance();
freeAdjMatrix();
}
void
LinkStateRoutingTableCalculator::doDijkstraPathCalculation(int sourceRouter)
{
int i;
int v,u;
int *Q=new int[numOfRouter];
int head=0;
/* Initiate the Parent */
for (i = 0 ; i < numOfRouter; i++)
{
m_parent[i]=EMPTY_PARENT;
m_distance[i]=INF_DISTANCE;
Q[i]=i;
}
if ( sourceRouter != NO_MAPPING_NUM )
{
m_distance[sourceRouter]=0;
sortQueueByDistance(Q,m_distance,head,numOfRouter);
while (head < numOfRouter )
{
u=Q[head];
if(m_distance[u] == INF_DISTANCE)
{
break;
}
for(v=0 ; v <numOfRouter; v++)
{
if( adjMatrix[u][v] > 0 )
{
if ( isNotExplored(Q,v,head+1,numOfRouter) )
{
if( m_distance[u] + adjMatrix[u][v] < m_distance[v])
{
m_distance[v]=m_distance[u] + adjMatrix[u][v] ;
m_parent[v]=u;
}
}
}
}
head++;
sortQueueByDistance(Q,m_distance,head,numOfRouter);
}
}
delete [] Q;
}
void
LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(Nlsr& pnlsr,
RoutingTable& rt, Map& pMap, int sourceRouter)
{
cout<<"LinkStateRoutingTableCalculator::addAllNextHopsToRoutingTable Called";
cout<<endl;
for(int i=0; i < numOfRouter ; i++)
{
if ( i!= sourceRouter )
{
int nextHopRouter=getLsNextHop(i,sourceRouter);
if ( nextHopRouter != NO_NEXT_HOP )
{
double routeCost=m_distance[i];
string nextHopRouterName=
pMap.getRouterNameByMappingNo(nextHopRouter);
int nxtHopFace=
pnlsr.getAdl().getAdjacent(nextHopRouterName).getConnectingFace();
cout<<"Dest Router: "<<pMap.getRouterNameByMappingNo(i)<<endl;
cout<<"Next hop Router: "<<nextHopRouterName<<endl;
cout<<"Next hop Face: "<<nxtHopFace<<endl;
cout<<"Route Cost: "<<routeCost<<endl;
cout<<endl;
// Add next hop to routing table
NextHop nh(nxtHopFace,routeCost);
rt.addNextHop(pMap.getRouterNameByMappingNo(i),nh);
}
}
}
}
int
LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
{
int nextHop;
while ( m_parent[dest] != EMPTY_PARENT )
{
nextHop=dest;
dest=m_parent[dest];
}
if ( dest != source )
{
nextHop=NO_NEXT_HOP;
}
return nextHop;
}
void
LinkStateRoutingTableCalculator::printAllLsPath(int sourceRouter)
{
cout<<"LinkStateRoutingTableCalculator::printAllLsPath Called"<<endl;
cout<<"Source Router: "<<sourceRouter<<endl;
for(int i=0; i < numOfRouter ; i++)
{
if ( i!= sourceRouter )
{
printLsPath(i);
cout<<endl;
}
}
}
void
LinkStateRoutingTableCalculator::printLsPath(int destRouter)
{
if (m_parent[destRouter] != EMPTY_PARENT )
{
printLsPath(m_parent[destRouter]);
}
cout<<" "<<destRouter;
}
void
LinkStateRoutingTableCalculator::sortQueueByDistance(int *Q,
double *dist,int start,int element)
{
for ( int i=start ; i < element ; i ++)
{
for( int j=i+1; j<element; j ++)
{
if (dist[Q[j]] < dist[Q[i]])
{
int tempU=Q[j];
Q[j]=Q[i];
Q[i]=tempU;
}
}
}
}
int
LinkStateRoutingTableCalculator::isNotExplored(int *Q,
int u,int start, int element)
{
int ret=0;
for(int i=start; i< element; i++)
{
if ( Q[i] == u )
{
ret=1;
break;
}
}
return ret;
}
void
LinkStateRoutingTableCalculator::allocateParent()
{
m_parent=new int[numOfRouter];
}
void
LinkStateRoutingTableCalculator::allocateDistance()
{
m_distance= new double[numOfRouter];
}
void
LinkStateRoutingTableCalculator::freeParent()
{
delete [] m_parent;
}
void LinkStateRoutingTableCalculator::freeDistance()
{
delete [] m_distance;
}
void
HypRoutingTableCalculator::calculatePath(Map& pMap,
RoutingTable& rt, Nlsr& pnlsr)
{
makeAdjMatrix(pnlsr,pMap);
string routerName=pnlsr.getConfParameter().getRouterPrefix();
int sourceRouter=pMap.getMappingNoByRouterName(routerName);
int noLink=getNumOfLinkfromAdjMatrix(sourceRouter);
setNoLink(noLink);
allocateLinks();
allocateLinkCosts();
getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
for(int i=0 ; i < numOfRouter ; ++i)
{
int k=0;
if ( i != sourceRouter)
{
allocateLinkFaces();
allocateDistanceToNeighbor();
allocateDistFromNbrToDest();
for(int j=0; j<vNoLink; j++)
{
string nextHopRouterName=pMap.getRouterNameByMappingNo(links[j]);
int nextHopFace=
pnlsr.getAdl().getAdjacent(nextHopRouterName).getConnectingFace();
double distToNbr=getHyperbolicDistance(pnlsr,pMap,
sourceRouter,links[j]);
double distToDestFromNbr=getHyperbolicDistance(pnlsr,
pMap,links[j],i);
if ( distToDestFromNbr >= 0 )
{
m_linkFaces[k] = nextHopFace;
m_distanceToNeighbor[k] = distToNbr;
m_distFromNbrToDest[k] = distToDestFromNbr;
k++;
}
}
addHypNextHopsToRoutingTable(pnlsr,pMap,rt,k,i);
freeLinkFaces();
freeDistanceToNeighbor();
freeDistFromNbrToDest();
}
}
freeLinks();
freeLinksCosts();
freeAdjMatrix();
}
void
HypRoutingTableCalculator::addHypNextHopsToRoutingTable(Nlsr& pnlsr,Map& pMap,
RoutingTable& rt, int noFaces, int dest)
{
for(int i=0 ; i < noFaces ; ++i)
{
string destRouter=pMap.getRouterNameByMappingNo(dest);
NextHop nh(m_linkFaces[i],m_distFromNbrToDest[i]);
rt.addNextHop(destRouter,nh);
if( m_isDryRun)
{
rt.addNextHopToDryTable(destRouter,nh);
}
}
}
double
HypRoutingTableCalculator::getHyperbolicDistance(Nlsr& pnlsr,
Map& pMap, int src, int dest)
{
double distance=0.0;
string srcRouterKey=pMap.getRouterNameByMappingNo(src)+"/3";
string destRouterKey=pMap.getRouterNameByMappingNo(dest)+"/3";
double srcRadius=(pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorRadius();
double srcTheta=(pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorTheta();
double destRadius=(pnlsr.getLsdb().getCorLsa(
destRouterKey).first).getCorRadius();
double destTheta=(pnlsr.getLsdb().getCorLsa(destRouterKey).first).getCorTheta();
double diffTheta = fabs (srcTheta - destTheta);
if (diffTheta > MATH_PI)
{
diffTheta = 2 * MATH_PI - diffTheta;
}
if ( srcRadius != -1 && destRadius != -1 )
{
if (diffTheta == 0)
distance = fabs (srcRadius - destRadius);
else
distance = acosh((cosh(srcRadius)*cosh(destRadius))-
(sinh(srcRadius)*sinh(destRadius)*cos(diffTheta)));
}
else
{
distance = -1;
}
return distance;
}
void
HypRoutingTableCalculator::allocateLinkFaces()
{
m_linkFaces=new int[vNoLink];
}
void
HypRoutingTableCalculator::allocateDistanceToNeighbor()
{
m_distanceToNeighbor=new double[vNoLink];
}
void
HypRoutingTableCalculator::allocateDistFromNbrToDest()
{
m_distFromNbrToDest=new double[vNoLink];
}
void
HypRoutingTableCalculator::freeLinkFaces()
{
delete [] m_linkFaces;
}
void
HypRoutingTableCalculator::freeDistanceToNeighbor()
{
delete [] m_distanceToNeighbor;
}
void
HypRoutingTableCalculator::freeDistFromNbrToDest()
{
delete [] m_distFromNbrToDest;
}
}//namespace nlsr