diff --git a/src/route/nlsr_rtc.cpp b/src/route/nlsr_rtc.cpp
new file mode 100644
index 0000000..acdf6d5
--- /dev/null
+++ b/src/route/nlsr_rtc.cpp
@@ -0,0 +1,504 @@
+#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"
+
+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).getAdjacentName();
+                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++)
+        {
+            parent[i]=EMPTY_PARENT;
+            distance[i]=INF_DISTANCE;
+            Q[i]=i;
+        }
+        if ( sourceRouter != NO_MAPPING_NUM )
+        {
+            distance[sourceRouter]=0;
+            sortQueueByDistance(Q,distance,head,numOfRouter);
+            while (head < numOfRouter )
+            {
+                u=Q[head];
+                if(distance[u] == INF_DISTANCE)
+                {
+                    break;
+                }
+                for(v=0 ; v <numOfRouter; v++)
+                {
+                    if( adjMatrix[u][v] > 0 )
+                    {
+                        if ( isNotExplored(Q,v,head+1,numOfRouter) )
+                        {
+                            if( distance[u] + adjMatrix[u][v] <  distance[v])
+                            {
+                                distance[v]=distance[u] + adjMatrix[u][v] ;
+                                parent[v]=u;
+                            }
+                        }
+                    }
+                }
+                head++;
+                sortQueueByDistance(Q,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);
+                double routeCost=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 ( parent[dest] != EMPTY_PARENT )
+        {
+            nextHop=dest;
+            dest=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 (parent[destRouter] != EMPTY_PARENT )
+        {
+            printLsPath(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()
+    {
+        parent=new int[numOfRouter];
+    }
+
+    void
+    LinkStateRoutingTableCalculator::allocateDistance()
+    {
+        distance= new double[numOfRouter];
+    }
+
+    void
+    LinkStateRoutingTableCalculator::freeParent()
+    {
+        delete [] parent;
+    }
+
+    void LinkStateRoutingTableCalculator::freeDistance()
+    {
+        delete [] 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 )
+                    {
+                        linkFaces[k] = nextHopFace;
+                        distanceToNeighbor[k] = distToNbr;
+                        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(linkFaces[i],distFromNbrToDest[i]);
+            rt.addNextHop(destRouter,nh);
+            if( isDryRun == 1 )
+            {
+                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()
+    {
+        linkFaces=new int[vNoLink];
+    }
+
+    void
+    HypRoutingTableCalculator::allocateDistanceToNeighbor()
+    {
+        distanceToNeighbor=new double[vNoLink];
+    }
+
+    void
+    HypRoutingTableCalculator::allocateDistFromNbrToDest()
+    {
+        distFromNbrToDest=new double[vNoLink];
+    }
+
+    void
+    HypRoutingTableCalculator::freeLinkFaces()
+    {
+        delete [] linkFaces;
+    }
+
+    void
+    HypRoutingTableCalculator::freeDistanceToNeighbor()
+    {
+        delete [] distanceToNeighbor;
+    }
+
+    void
+    HypRoutingTableCalculator::freeDistFromNbrToDest()
+    {
+        delete [] distFromNbrToDest;
+    }
+
+}//namespace nlsr
