Directory Structuring
diff --git a/src/communication/nlsr_dm.cpp b/src/communication/nlsr_dm.cpp
new file mode 100644
index 0000000..92a911d
--- /dev/null
+++ b/src/communication/nlsr_dm.cpp
@@ -0,0 +1,202 @@
+#include<iostream>
+#include<cstdlib>
+
+#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <ndn-cpp-dev/util/io.hpp>
+
+#include "nlsr.hpp"
+#include "nlsr_dm.hpp"
+#include "utility/nlsr_tokenizer.hpp"
+#include "nlsr_lsdb.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+    using namespace ndn;
+
+    void
+    DataManager::processContent(Nlsr& pnlsr, const ndn::Interest &interest,
+                                const ndn::Data & data, interestManager& im)
+    {
+        cout << "I: " << interest.toUri() << endl;
+        string dataName(data.getName().toUri());
+        //cout << "D: " << dataName << endl;
+        //cout << "Data Content: " << dataContent << endl;
+        nlsrTokenizer nt(dataName,"/");
+        //SignatureSha256WithRsa sig(data.getSignature());
+        //ndn::Name keyName=sig.getKeyLocator().getName();
+        //cout<<"Key Locator Name: "<<keyName.toUri()<<endl;
+        string chkString("info");
+        if( nt.doesTokenExist(chkString) )
+        {
+            string dataContent((char *)data.getContent().value());
+            processContentInfo(pnlsr,dataName,dataContent);
+        }
+        chkString="LSA";
+        if( nt.doesTokenExist(chkString) )
+        {
+            string dataContent((char *)data.getContent().value());
+            processContentLsa(pnlsr, dataName, dataContent);
+        }
+        chkString="keys";
+        if( nt.doesTokenExist(chkString) )
+        {
+            processContentKeys(pnlsr, data);
+        }
+    }
+
+    void
+    DataManager::processContentInfo(Nlsr& pnlsr, string& dataName,
+                                    string& dataContent)
+    {
+        nlsrTokenizer nt(dataName,"/");
+        string chkString("info");
+        string neighbor=nt.getTokenString(0,nt.getTokenPosition(chkString)-1);
+        int oldStatus=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+        int infoIntTimedOutCount=pnlsr.getAdl().getTimedOutInterestCount(neighbor);
+        //debugging purpose start
+        cout <<"Before Updates: " <<endl;
+        cout <<"Neighbor : "<<neighbor<<endl;
+        cout<<"Status: "<< oldStatus << endl;
+        cout<<"Info Interest Timed out: "<< infoIntTimedOutCount <<endl;
+        //debugging purpose end
+        pnlsr.getAdl().setStatusOfNeighbor(neighbor,1);
+        pnlsr.getAdl().setTimedOutInterestCount(neighbor,0);
+        int newStatus=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+        infoIntTimedOutCount=pnlsr.getAdl().getTimedOutInterestCount(neighbor);
+        //debugging purpose
+        cout <<"After Updates: " <<endl;
+        cout <<"Neighbor : "<<neighbor<<endl;
+        cout<<"Status: "<< newStatus << endl;
+        cout<<"Info Interest Timed out: "<< infoIntTimedOutCount <<endl;
+        //debugging purpose end
+        if ( ( oldStatus-newStatus)!= 0 ) // change in Adjacency list
+        {
+            pnlsr.incrementAdjBuildCount();
+            /* Need to schedule event for Adjacency LSA building */
+            if ( pnlsr.getIsBuildAdjLsaSheduled() == 0 )
+            {
+                pnlsr.setIsBuildAdjLsaSheduled(1);
+                // event here
+                pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(5),
+                                                   ndn::bind(&Lsdb::scheduledAdjLsaBuild, pnlsr.getLsdb(),
+                                                           boost::ref(pnlsr)));
+            }
+        }
+    }
+
+    void
+    DataManager::processContentLsa(Nlsr& pnlsr, string& dataName,
+                                   string& dataContent)
+    {
+        nlsrTokenizer nt(dataName,"/");
+        string chkString("LSA");
+        string origRouter=nt.getTokenString(nt.getTokenPosition(chkString)+1,
+                                            nt.getTokenNumber()-4);
+        string lsTypeString=nt.getToken(nt.getTokenNumber()-3);
+        string lsSeNoString=nt.getToken(nt.getTokenNumber()-2);
+        uint32_t interestedLsSeqNo;
+        try
+        {
+            interestedLsSeqNo=boost::lexical_cast<uint32_t>(lsSeNoString);
+        }
+        catch(std::exception &e)
+        {
+            return;
+        }
+        if( lsTypeString == "1" ) //Name Lsa
+        {
+            processContentNameLsa(pnlsr, origRouter+"/"+lsTypeString,
+                                  interestedLsSeqNo, dataContent);
+        }
+        else if( lsTypeString == "2" ) //Adj Lsa
+        {
+            processContentAdjLsa(pnlsr, origRouter+"/"+lsTypeString,
+                                 interestedLsSeqNo, dataContent);
+        }
+        else if( lsTypeString == "3" ) //Cor Lsa
+        {
+            processContentCorLsa(pnlsr, origRouter+"/"+lsTypeString,
+                                 interestedLsSeqNo, dataContent);
+        }
+        else
+        {
+            cout<<"Unrecognized LSA Type :("<<endl;
+        }
+    }
+
+    void
+    DataManager::processContentNameLsa(Nlsr& pnlsr, string lsaKey,
+                                       uint32_t lsSeqNo, string& dataContent)
+    {
+        if ( pnlsr.getLsdb().isNameLsaNew(lsaKey,lsSeqNo))
+        {
+            NameLsa nameLsa;
+            if( nameLsa.initNameLsaFromContent(dataContent) )
+            {
+                pnlsr.getLsdb().installNameLsa(pnlsr, nameLsa);
+            }
+            else
+            {
+                cout<<"LSA data decoding error :("<<endl;
+            }
+        }
+    }
+
+    void
+    DataManager::processContentAdjLsa(Nlsr& pnlsr, string lsaKey,
+                                      uint32_t lsSeqNo, string& dataContent)
+    {
+        if ( pnlsr.getLsdb().isAdjLsaNew(lsaKey,lsSeqNo))
+        {
+            AdjLsa adjLsa;
+            if( adjLsa.initAdjLsaFromContent(dataContent) )
+            {
+                pnlsr.getLsdb().installAdjLsa(pnlsr, adjLsa);
+            }
+            else
+            {
+                cout<<"LSA data decoding error :("<<endl;
+            }
+        }
+    }
+
+    void
+    DataManager::processContentCorLsa(Nlsr& pnlsr, string lsaKey,
+                                      uint32_t lsSeqNo, string& dataContent)
+    {
+        if ( pnlsr.getLsdb().isCorLsaNew(lsaKey,lsSeqNo))
+        {
+            CorLsa corLsa;
+            if( corLsa.initCorLsaFromContent(dataContent) )
+            {
+                pnlsr.getLsdb().installCorLsa(pnlsr, corLsa);
+            }
+            else
+            {
+                cout<<"LSA data decoding error :("<<endl;
+            }
+        }
+    }
+    
+    void 
+    DataManager::processContentKeys(Nlsr& pnlsr, const ndn::Data& data)
+    {
+        std::ofstream outFile("data_received");
+        ndn::io::save(data,outFile,ndn::io::NO_ENCODING);
+        cout<<" processContentKeys called "<<endl;
+        SignatureSha256WithRsa signature(data.getSignature());
+        cout<<"D: <<"<<data<<endl;
+        cout<<"Key Locator: "<<signature.getKeyLocator().getName().toUri()<<endl;
+        ndn::shared_ptr<ndn::IdentityCertificate> cert=ndn::make_shared<ndn::IdentityCertificate>();
+        cert->wireDecode(data.getContent().blockFromValue());
+        cout<<*(cert)<<endl;
+        
+        if( pnlsr.getKeyManager().verifySignature(*(cert),cert->getPublicKeyInfo()))
+        {
+            cout<<"Verified Data"<<endl;
+        }
+    }
+}//namespace nlsr
diff --git a/src/communication/nlsr_dm.hpp b/src/communication/nlsr_dm.hpp
new file mode 100644
index 0000000..fdb45db
--- /dev/null
+++ b/src/communication/nlsr_dm.hpp
@@ -0,0 +1,40 @@
+#ifndef NLSR_DM_HPP
+#define NLSR_DM_HPP
+
+#include <ndn-cpp-dev/face.hpp>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+
+#include "nlsr_im.hpp"
+
+namespace nlsr
+{
+
+    using namespace ndn;
+    using namespace std;
+
+    class Nlsr;
+
+    class DataManager
+    {
+    public:
+        void processContent(Nlsr& pnlsr, const ndn::Interest &interest,
+                            const ndn::Data& data, interestManager& im);
+    private:
+        void processContentInfo(Nlsr& pnlsr, string& dataName,
+                                string& dataContent);
+        void processContentLsa(Nlsr& pnlsr, string& dataName,
+                               string& dataContent);
+        void processContentNameLsa(Nlsr& pnlsr, string lsaKey,
+                                   uint32_t lsSeqNo, string& dataContent);
+        void processContentAdjLsa(Nlsr& pnlsr, string lsaKey,
+                                  uint32_t lsSeqNo, string& dataContent);
+        void processContentCorLsa(Nlsr& pnlsr, string lsaKey,
+                                  uint32_t lsSeqNo, string& dataContent);
+        void processContentKeys(Nlsr& pnlsr, const ndn::Data& data);
+        
+
+    };
+
+}//namespace nlsr
+#endif
diff --git a/src/communication/nlsr_im.cpp b/src/communication/nlsr_im.cpp
new file mode 100644
index 0000000..7495265
--- /dev/null
+++ b/src/communication/nlsr_im.cpp
@@ -0,0 +1,300 @@
+#include<iostream>
+#include<cstdlib>
+
+
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <ndn-cpp-dev/util/io.hpp>
+
+#include "nlsr.hpp"
+#include "nlsr_im.hpp"
+#include "nlsr_dm.hpp"
+#include "utility/nlsr_tokenizer.hpp"
+#include "nlsr_lsdb.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+    using namespace ndn;
+
+    void
+    interestManager::processInterest( Nlsr& pnlsr,
+                                      const ndn::Name &name,
+                                      const ndn::Interest &interest)
+    {
+        cout << "<< I: " << interest << endl;
+        string intName=interest.getName().toUri();
+        cout << "Interest Received for Name: "<< intName <<endl;
+        nlsrTokenizer nt(intName,"/");
+        string chkString("info");
+        if( nt.doesTokenExist(chkString) )
+        {
+            string nbr=nt.getTokenString(nt.getTokenPosition(chkString)+1);
+            cout <<"Neighbor: " << nbr <<endl;
+            processInterestInfo(pnlsr,nbr,interest);
+        }
+        chkString="LSA";
+        if( nt.doesTokenExist(chkString) )
+        {
+            processInterestLsa(pnlsr,interest);
+        }
+        chkString="keys";
+        if( nt.doesTokenExist(chkString) )
+        {
+            processInterestKeys(pnlsr,interest);
+        }
+        //Data data(ndn::Name(interest->getName()).append("testApp").appendVersion());
+        //data.setFreshnessPeriod(1000); // 10 sec
+        //data.setContent((const uint8_t*)"HELLO KITTY", sizeof("HELLO KITTY"));
+        //pnlsr.getKeyChain().sign(data);
+        //cout << ">> D: " << data << endl;
+        //pnlsr.getNlsrFace().put(data);
+    }
+
+    void
+    interestManager::processInterestInfo(Nlsr& pnlsr, string& neighbor,
+                                         const ndn::Interest &interest)
+    {
+        if ( pnlsr.getAdl().isNeighbor(neighbor) )
+        {
+            Data data(ndn::Name(interest.getName()).appendVersion());
+            data.setFreshnessPeriod(1000); // 10 sec
+            data.setContent((const uint8_t*)"info", sizeof("info"));
+            pnlsr.getKeyManager().signData(data);
+            cout << ">> D: " << data << endl;
+            pnlsr.getNlsrFace()->put(data);
+            int status=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+            if ( status == 0 )
+            {
+                string intName=neighbor +"/"+"info"+
+                               pnlsr.getConfParameter().getRouterPrefix();
+                expressInterest(	pnlsr,intName,2,
+                                    pnlsr.getConfParameter().getInterestResendTime());
+            }
+        }
+    }
+
+    void
+    interestManager::processInterestLsa(Nlsr& pnlsr,const ndn::Interest &interest)
+    {
+        string intName=interest.getName().toUri();
+        nlsrTokenizer nt(intName,"/");
+        string chkString("LSA");
+        string origRouter=nt.getTokenString(nt.getTokenPosition(chkString)+1,
+                                            nt.getTokenNumber()-3);
+        string lsTypeString=nt.getToken(nt.getTokenNumber()-2);
+        string lsSeqString=nt.getToken(nt.getTokenNumber()-1);
+        cout<<"Router Name: "<<origRouter<<endl;
+        cout<<"Ls Type    : "<<lsTypeString<<endl;
+        cout<<"Ls Seq     : "<<lsSeqString<<endl;
+        uint8_t interestedLsType;
+        uint32_t interestedLsSeqNo;
+        try
+        {
+            interestedLsType=boost::lexical_cast<uint8_t>(lsTypeString);
+            interestedLsSeqNo=boost::lexical_cast<uint32_t>(lsSeqString);
+        }
+        catch(std::exception &e)
+        {
+            return;
+        }
+        cout <<"Ls Type: "<<interestedLsType<<endl;
+        if( lsTypeString == "1" ) //Name Lsa
+        {
+            processInterestForNameLsa(pnlsr, interest,
+                                      origRouter+"/"+lsTypeString, interestedLsSeqNo);
+        }
+        else if( lsTypeString == "2" ) //Adj Lsa
+        {
+            processInterestForAdjLsa(pnlsr, interest,
+                                     origRouter+"/"+lsTypeString, interestedLsSeqNo);
+        }
+        else if( lsTypeString == "3" ) //Cor Lsa
+        {
+            processInterestForCorLsa(pnlsr, interest,
+                                     origRouter+"/"+lsTypeString, interestedLsSeqNo);
+        }
+        else
+        {
+            cout<<"Unrecognized LSA Type :("<<endl;
+        }
+    }
+
+    void
+    interestManager::processInterestForNameLsa(Nlsr& pnlsr,
+            const ndn::Interest &interest,
+            string lsaKey, uint32_t interestedlsSeqNo)
+    {
+        std::pair<NameLsa&, bool>  nameLsa=pnlsr.getLsdb().getNameLsa(lsaKey);
+        if( nameLsa.second )
+        {
+            if ( nameLsa.first.getLsSeqNo() >= interestedlsSeqNo )
+            {
+                Data data(ndn::Name(interest.getName()).appendVersion());
+                data.setFreshnessPeriod(1000); // 10 sec
+                string content=nameLsa.first.getNameLsaData();
+                data.setContent((const uint8_t*)content.c_str(),content.size());
+                pnlsr.getKeyManager().signData(data);
+                cout << ">> D: " << data << endl;
+                pnlsr.getNlsrFace()->put(data);
+            }
+        }
+    }
+
+    void
+    interestManager::processInterestForAdjLsa(Nlsr& pnlsr,
+            const ndn::Interest &interest,
+            string lsaKey, uint32_t interestedlsSeqNo)
+    {
+        std::pair<AdjLsa&, bool>  adjLsa=pnlsr.getLsdb().getAdjLsa(lsaKey);
+        if( adjLsa.second )
+        {
+            if ( adjLsa.first.getLsSeqNo() >= interestedlsSeqNo )
+            {
+                Data data(ndn::Name(interest.getName()).appendVersion());
+                data.setFreshnessPeriod(1000); // 10 sec
+                string content=adjLsa.first.getAdjLsaData();
+                data.setContent((const uint8_t*)content.c_str(),content.size());
+                pnlsr.getKeyManager().signData(data);
+                cout << ">> D: " << data << endl;
+                pnlsr.getNlsrFace()->put(data);
+            }
+        }
+    }
+
+    void
+    interestManager::processInterestForCorLsa(Nlsr& pnlsr,
+            const ndn::Interest &interest,
+            string lsaKey, uint32_t interestedlsSeqNo)
+    {
+        std::pair<CorLsa&, bool>  corLsa=pnlsr.getLsdb().getCorLsa(lsaKey);
+        if( corLsa.second )
+        {
+            if ( corLsa.first.getLsSeqNo() >= interestedlsSeqNo )
+            {
+                Data data(ndn::Name(interest.getName()).appendVersion());
+                data.setFreshnessPeriod(1000); // 10 sec
+                string content=corLsa.first.getCorLsaData();
+                data.setContent((const uint8_t*)content.c_str(),content.size());
+                pnlsr.getKeyManager().signData(data);
+                cout << ">> D: " << data << endl;
+                pnlsr.getNlsrFace()->put(data);
+            }
+        }
+    }
+
+    void
+    interestManager::processInterestKeys(Nlsr& pnlsr,const ndn::Interest &interest)
+    {
+        cout<<" processInterestKeys called "<<endl;
+        ndn::shared_ptr<ndn::IdentityCertificate> cert=pnlsr.getKeyManager().getCertificate("dummy");
+        Data data(ndn::Name(interest.getName()).appendVersion());
+        data.setFreshnessPeriod(1000); // 10 sec
+        data.setContent(cert->wireEncode());
+        pnlsr.getKeyManager().signData(data);
+        std::ofstream outFile("data_sent");
+        ndn::io::save(data,outFile,ndn::io::NO_ENCODING);
+        pnlsr.getNlsrFace()->put(data);
+    }
+
+
+    void
+    interestManager::processInterestTimedOut(Nlsr& pnlsr,
+            const ndn::Interest &interest)
+    {
+        cout << "Timed out interest : " << interest.getName().toUri() << endl;
+        string intName=	interest.getName().toUri();
+        nlsrTokenizer nt(intName,"/");
+        string chkString("info");
+        if( nt.doesTokenExist(chkString) )
+        {
+            string nbr=nt.getTokenString(0,nt.getTokenPosition(chkString)-1);
+            processInterestTimedOutInfo( pnlsr , nbr , interest);
+        }
+        chkString="LSA";
+        if( nt.doesTokenExist(chkString) )
+        {
+            processInterestTimedOutLsa(pnlsr, interest);
+        }
+    }
+
+    void
+    interestManager::processInterestTimedOutInfo(Nlsr& pnlsr, string& neighbor,
+            const ndn::Interest &interest)
+    {
+        pnlsr.getAdl().incrementTimedOutInterestCount(neighbor);
+        int status=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+        int infoIntTimedOutCount=pnlsr.getAdl().getTimedOutInterestCount(neighbor);
+        cout<<"Neighbor: "<< neighbor << endl;
+        cout<<"Status: "<< status << endl;
+        cout<<"Info Interest Timed out: "<< infoIntTimedOutCount <<endl;
+        if((infoIntTimedOutCount < pnlsr.getConfParameter().getInterestRetryNumber()))
+        {
+            string intName=neighbor +"/"+"info"+
+                           pnlsr.getConfParameter().getRouterPrefix();
+            expressInterest(	pnlsr,intName,2,
+                                pnlsr.getConfParameter().getInterestResendTime());
+        }
+        else if ( (status == 1) &&
+                  (infoIntTimedOutCount == pnlsr.getConfParameter().getInterestRetryNumber()))
+        {
+            pnlsr.getAdl().setStatusOfNeighbor(neighbor,0);
+            pnlsr.incrementAdjBuildCount();
+            if ( pnlsr.getIsBuildAdjLsaSheduled() == 0 )
+            {
+                pnlsr.setIsBuildAdjLsaSheduled(1);
+                // event here
+                pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(5),
+                                                   ndn::bind(&Lsdb::scheduledAdjLsaBuild,&pnlsr.getLsdb(),
+                                                           boost::ref(pnlsr)));
+            }
+        }
+    }
+
+    void
+    interestManager::processInterestTimedOutLsa(Nlsr& pnlsr,
+            const ndn::Interest &interest)
+    {
+    }
+
+    void
+    interestManager::expressInterest(Nlsr& pnlsr,const string& interestNamePrefix,
+                                     int scope, int seconds)
+    {
+        cout<<"Expressing Interest :"<<interestNamePrefix<<endl;
+        ndn::Interest i((ndn::Name(interestNamePrefix)));
+        //i.setScope(scope);
+        i.setInterestLifetime(seconds*1000);
+        i.setMustBeFresh(true);
+        pnlsr.getNlsrFace()->expressInterest(i,
+                                             ndn::func_lib::bind(&DataManager::processContent,
+                                                     &pnlsr.getDm(), boost::ref(pnlsr),_1, _2,boost::ref(*this)),
+                                             ndn::func_lib::bind(&interestManager::processInterestTimedOut,
+                                                     this,boost::ref(pnlsr),_1));
+    }
+
+
+    void
+    interestManager::sendScheduledInfoInterest(Nlsr& pnlsr, int seconds)
+    {
+        std::list<Adjacent> adjList=pnlsr.getAdl().getAdjList();
+        for(std::list<Adjacent>::iterator it=adjList.begin(); it!=adjList.end(); ++it)
+        {
+            string adjName=(*it).getAdjacentName()+"/"+"info"+
+                           pnlsr.getConfParameter().getRouterPrefix();
+            expressInterest(	pnlsr,adjName,2,
+                                pnlsr.getConfParameter().getInterestResendTime());
+        }
+        scheduleInfoInterest(pnlsr, pnlsr.getConfParameter().getInfoInterestInterval());
+    }
+
+    void
+    interestManager::scheduleInfoInterest(Nlsr& pnlsr, int seconds)
+    {
+        EventId eid=pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(seconds),
+                    ndn::bind(&interestManager::sendScheduledInfoInterest, this,
+                              boost::ref(pnlsr),seconds));
+    }
+
+
+} //namespace nlsr
diff --git a/src/communication/nlsr_im.hpp b/src/communication/nlsr_im.hpp
new file mode 100644
index 0000000..330874f
--- /dev/null
+++ b/src/communication/nlsr_im.hpp
@@ -0,0 +1,52 @@
+#ifndef NLSR_IM_HPP
+#define NLSR_IM_HPP
+
+#include <ndn-cpp-dev/face.hpp>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+
+namespace nlsr
+{
+
+    using namespace ndn;
+    using namespace std;
+
+    class Nlsr;
+
+    class interestManager
+    {
+    public:
+        interestManager()
+        {
+        }
+        void processInterest(Nlsr& pnlsr, const ndn::Name &name,
+                             const ndn::Interest &interest);
+        void processInterestInfo(Nlsr& pnlsr, string& neighbor,
+                                 const ndn::Interest &interest);
+        void processInterestLsa(Nlsr& pnlsr,const ndn::Interest &interest);
+        void processInterestForNameLsa(Nlsr& pnlsr, const ndn::Interest &interest,
+                                       string lsaKey, uint32_t interestedlsSeqNo);
+        void processInterestForAdjLsa(Nlsr& pnlsr, const ndn::Interest &interest,
+                                      string lsaKey, uint32_t interestedlsSeqNo);
+        void processInterestForCorLsa(Nlsr& pnlsr, const ndn::Interest &interest,
+                                      string lsaKey, uint32_t interestedlsSeqNo);
+
+        void processInterestKeys(Nlsr& pnlsr,const ndn::Interest &interest);
+
+        void processInterestTimedOut(Nlsr& pnlsr, const ndn::Interest &interest);
+        void processInterestTimedOutInfo(Nlsr& pnlsr, string& neighbor,
+                                         const ndn::Interest &interest);
+        void processInterestTimedOutLsa(Nlsr& pnlsr,const ndn::Interest &interest);
+        void expressInterest(Nlsr& pnlsr,const string& interestNamePrefix, int scope,
+                             int seconds);
+        void sendScheduledInfoInterest(Nlsr& pnlsr, int seconds);
+        void scheduleInfoInterest(Nlsr& pnlsr, int seconds);
+
+    private:
+
+
+    };
+
+}//namespace nlsr
+
+#endif
diff --git a/src/communication/nlsr_slh.cpp b/src/communication/nlsr_slh.cpp
new file mode 100644
index 0000000..ac29148
--- /dev/null
+++ b/src/communication/nlsr_slh.cpp
@@ -0,0 +1,147 @@
+#include "nlsr.hpp"
+#include "nlsr_slh.hpp"
+#include "security/nlsr_km.hpp"
+#include "utility/nlsr_tokenizer.hpp"
+
+
+namespace nlsr
+{
+    void
+    SyncLogicHandler::createSyncSocket(Nlsr &pnlsr )
+    {
+        cout<<"Creating Sync socket ......"<<endl;
+        cout<<"Sync prefix: "<<syncPrefix.toUri()<<endl;
+        syncSocket=make_shared<SyncSocket>(syncPrefix, validator, syncFace,
+                                           bind(&SyncLogicHandler::nsyncUpdateCallBack,this,
+                                                _1, _2,boost::ref(pnlsr)),
+                                           bind(&SyncLogicHandler::nsyncRemoveCallBack, this,
+                                                _1,boost::ref(pnlsr)));
+    }
+
+    void
+    SyncLogicHandler::nsyncUpdateCallBack(const vector<MissingDataInfo> &v,
+                                          SyncSocket *socket, Nlsr& pnlsr)
+    {
+        cout<<"nsyncUpdateCallBack called ...."<<endl;
+        int n = v.size();
+        for(int i=0; i < n; i++)
+        {
+            std::cout<<"Data Name: "<<v[i].prefix<<" Seq: "<<v[i].high.getSeq()<<endl;
+            processUpdateFromSync(v[i].prefix,v[i].high.getSeq(),pnlsr);
+        }
+    }
+
+    void
+    SyncLogicHandler::nsyncRemoveCallBack(const string& prefix, Nlsr& pnlsr)
+    {
+        cout<<"nsyncRemoveCallBack called ...."<<endl;
+    }
+
+    void
+    SyncLogicHandler::removeRouterFromSyncing(string& routerPrefix)
+    {
+    }
+
+    void
+    SyncLogicHandler::processUpdateFromSync(std::string updateName,
+                                            uint64_t seqNo,  Nlsr& pnlsr)
+    {
+        nlsrTokenizer nt(updateName,"/");
+        string chkString("LSA");
+        if( nt.doesTokenExist(chkString) )
+        {
+            //process LSA Update here
+            string routerName=nt.getTokenString(nt.getTokenPosition(chkString)+1);
+            processRoutingUpdateFromSync(routerName, seqNo, pnlsr);
+        }
+        chkString="keys";
+        if( nt.doesTokenExist(chkString) )
+        {
+            //process keys update here
+            processKeysUpdateFromSync(updateName,seqNo, pnlsr);
+        }
+    }
+
+    void
+    SyncLogicHandler::processRoutingUpdateFromSync(std::string routerName,
+            uint64_t seqNo,  Nlsr& pnlsr)
+    {
+        if( routerName != pnlsr.getConfParameter().getRouterPrefix() )
+        {
+            SequencingManager sm(seqNo);
+            cout<<sm;
+            cout<<"Router Name: "<<routerName<<endl;
+            if ( pnlsr.getLsdb().isNameLsaNew(routerName+"/1",sm.getNameLsaSeq()))
+            {
+                cout<<"Updated Name LSA. Need to fetch it"<<endl;
+                string lsaPrefix=
+                    pnlsr.getConfParameter().getChronosyncLsaPrefix() +
+                    routerName + "/1/" +
+                    boost::lexical_cast<std::string>(sm.getNameLsaSeq());
+                pnlsr.getIm().expressInterest(pnlsr, lsaPrefix, 3,
+                                              pnlsr.getConfParameter().getInterestResendTime());
+            }
+            if ( pnlsr.getLsdb().isAdjLsaNew(routerName+"/2",sm.getAdjLsaSeq()))
+            {
+                cout<<"Updated Adj LSA. Need to fetch it"<<endl;
+                string lsaPrefix=
+                    pnlsr.getConfParameter().getChronosyncLsaPrefix() +
+                    routerName + "/2/" +
+                    boost::lexical_cast<std::string>(sm.getAdjLsaSeq());
+                pnlsr.getIm().expressInterest(pnlsr, lsaPrefix, 3,
+                                              pnlsr.getConfParameter().getInterestResendTime());
+            }
+            if ( pnlsr.getLsdb().isCorLsaNew(routerName+"/3",sm.getCorLsaSeq()))
+            {
+                cout<<"Updated Cor LSA. Need to fetch it"<<endl;
+                string lsaPrefix=
+                    pnlsr.getConfParameter().getChronosyncLsaPrefix() +
+                    routerName + "/3/" +
+                    boost::lexical_cast<std::string>(sm.getCorLsaSeq());
+                pnlsr.getIm().expressInterest(pnlsr, lsaPrefix, 3,
+                                              pnlsr.getConfParameter().getInterestResendTime());
+            }
+        }
+    }
+
+    void
+    SyncLogicHandler::processKeysUpdateFromSync(std::string certName,
+            uint64_t seqNo, Nlsr& pnlsr)
+    {
+        string certNamePrefix=certName + "/" + boost::lexical_cast<string>(seqNo);
+        pnlsr.getIm().expressInterest(pnlsr, certNamePrefix, 3,
+                                      pnlsr.getConfParameter().getInterestResendTime());
+    }
+
+    void
+    SyncLogicHandler::publishRoutingUpdate(SequencingManager& sm,
+                                           string updatePrefix)
+    {
+        sm.writeSeqNoToFile();
+        publishSyncUpdate(updatePrefix,sm.getCombinedSeqNo());
+    }
+
+    void
+    SyncLogicHandler::publishKeyUpdate(KeyManager& km)
+    {
+        publishSyncUpdate(km.getRouterCertName().toUri(),km.getCertSeqNo());
+    }
+
+    void
+    SyncLogicHandler::publishIdentityUpdate(string identityName)
+    {
+        publishSyncUpdate(identityName,0);
+    }
+
+    void
+    SyncLogicHandler::publishSyncUpdate(string updatePrefix, uint64_t seqNo)
+    {
+        cout<<"Publishing Sync Update ......"<<endl;
+        cout<<"Update in prefix: "<<updatePrefix<<endl;
+        cout<<"Seq No: "<<seqNo<<endl;
+        ndn::Name updateName(updatePrefix);
+        string data("NoData");
+        syncSocket->publishData(updateName,0,data.c_str(),data.size(),1000,seqNo);
+    }
+
+}
diff --git a/src/communication/nlsr_slh.hpp b/src/communication/nlsr_slh.hpp
new file mode 100644
index 0000000..3fef612
--- /dev/null
+++ b/src/communication/nlsr_slh.hpp
@@ -0,0 +1,65 @@
+#ifndef NLSR_SLH_HPP
+#define NLSR_SLH_HPP
+
+#include <iostream>
+
+#include <ndn-cpp-dev/face.hpp>
+#include <nsync/sync-socket.h>
+#include <ndn-cpp-dev/security/validator-null.hpp>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+
+#include "nlsr_sm.hpp"
+
+class KeyManager;
+
+extern "C" {
+#include <unistd.h>
+}
+
+using namespace ndn;
+using namespace Sync;
+using namespace std;
+
+class interestManager;
+class ConfParameter;
+
+namespace nlsr
+{
+    class SyncLogicHandler
+    {
+    public:
+        SyncLogicHandler(ndn::shared_ptr<boost::asio::io_service> ioService)
+            : validator(new ndn::ValidatorNull())
+            , syncFace(new ndn::Face(ioService))
+        {}
+
+
+        void createSyncSocket(Nlsr& pnlsr);
+        void nsyncUpdateCallBack(const vector<MissingDataInfo> &v,
+                                 SyncSocket *socket, Nlsr& pnlsr );
+        void nsyncRemoveCallBack(const string& prefix, Nlsr &pnlsr);
+        void removeRouterFromSyncing(string& routerPrefix);
+        void publishRoutingUpdate(SequencingManager& sm, string updatePrefix);
+        void publishKeyUpdate(KeyManager& km);
+        void publishIdentityUpdate(string identityName);
+        void setSyncPrefix(string sp)
+        {
+            syncPrefix.clear();
+            syncPrefix.set(sp);
+        }
+    private:
+        void processUpdateFromSync(std::string updateName, uint64_t seqNo,
+                                   Nlsr& pnlsr);
+        void processRoutingUpdateFromSync(std::string routerName, uint64_t seqNo,
+                                          Nlsr& pnlsr);
+        void processKeysUpdateFromSync(std::string certName, uint64_t seqNo,
+                                       Nlsr& pnlsr);
+        void publishSyncUpdate(string updatePrefix, uint64_t seqNo);
+    private:
+        ndn::shared_ptr<ndn::ValidatorNull> validator;
+        ndn::shared_ptr<ndn::Face> syncFace;
+        ndn::shared_ptr<SyncSocket> syncSocket;
+        ndn::Name syncPrefix;
+    };
+}
+#endif