| #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 |