Schedule Adj LSA build and installation
diff --git a/nlsr.cpp b/nlsr.cpp
index 145fa47..a21aa3f 100644
--- a/nlsr.cpp
+++ b/nlsr.cpp
@@ -65,7 +65,7 @@
 	
 	
 /* debugging purpose start */
-	cout <<	nlsr.getConfParameter(); ;
+	cout <<	nlsr.getConfParameter();
 	nlsr.getAdl().printAdl();
 	nlsr.getNpl().printNpl();
 	nlsr.getLsdb().printNameLsdb();
diff --git a/nlsr.hpp b/nlsr.hpp
index c78caac..8b325fe 100644
--- a/nlsr.hpp
+++ b/nlsr.hpp
@@ -33,6 +33,10 @@
     , nameLsaSeq(0)
     , adjLsaSeq(0)
     , corLsaSeq(0)
+    , adjBuildCount(0)
+    , isBuildAdjLsaSheduled(0)
+    , isRouteCalculationScheduled(0)
+    , isRoutingTableCalculating(0)
 	{
 		isDaemonProcess=false;
 		configFileName="nlsr.conf";	
@@ -49,6 +53,10 @@
     , im()
     , dm()
     , nlsrLsdb()
+    , adjBuildCount(0)
+    , isBuildAdjLsaSheduled(0)
+    , isRouteCalculationScheduled(0)
+    , isRoutingTableCalculating(0)
 	{
 		isDaemonProcess=false;
 		configFileName=confFile;
@@ -151,7 +159,32 @@
 	void setCorLsaSeq(uint32_t clsn){
 		corLsaSeq=clsn;
 	}
-		
+
+	long int getAdjBuildCount()
+	{
+		return adjBuildCount;
+	}
+
+	void incrementAdjBuildCount()
+	{
+		adjBuildCount++;
+	}
+
+	void setAdjBuildCount(long int abc)
+	{
+		adjBuildCount=abc;
+	}
+
+	int getIsBuildAdjLsaSheduled()
+	{
+		return isBuildAdjLsaSheduled;
+	}
+
+	void setIsBuildAdjLsaSheduled(int iabls)
+	{
+		isBuildAdjLsaSheduled=iabls;
+	}
+	
 private:
 	ConfParameter confParam;
 	Adl adl;
@@ -168,6 +201,11 @@
 	uint32_t nameLsaSeq;
 	uint32_t adjLsaSeq;
 	uint32_t corLsaSeq;
+
+	long int adjBuildCount;
+	int isBuildAdjLsaSheduled;
+	int isRouteCalculationScheduled;
+	int isRoutingTableCalculating;
 	
 
 };
diff --git a/nlsr_adl.cpp b/nlsr_adl.cpp
index 0cbdb4a..0f4be8f 100644
--- a/nlsr_adl.cpp
+++ b/nlsr_adl.cpp
@@ -3,6 +3,7 @@
 
 #include "nlsr_adl.hpp"
 #include "nlsr_adjacent.hpp"
+#include "nlsr.hpp"
 
 Adl::Adl(){
 }
@@ -151,6 +152,51 @@
 	return adjList;
 }
 
+bool
+Adl::isAdjLsaBuildable(nlsr& pnlsr)
+{
+	int nbrCount=0;
+	for( std::list<Adjacent>::iterator it=adjList.begin(); 
+	                                                   it!= adjList.end() ; it++)
+	{
+		if ( ((*it).getStatus() == 1 ) )
+		{
+			nbrCount++;
+		}
+		else
+		{
+			if ( (*it).getInterestTimedOutNo() >= 
+				                       pnlsr.getConfParameter().getInterestRetryNumber())
+			{
+					nbrCount++;
+			}
+		} 
+	}
+
+	if( nbrCount == adjList.size())
+	{
+		return true;
+	}
+
+	return false;
+}
+
+int 
+Adl::getNumOfActiveNeighbor()
+{
+	int actNbrCount=0;
+	for( std::list<Adjacent>::iterator it=adjList.begin(); 
+	                                                   it!= adjList.end() ; it++)
+	{
+		if ( ((*it).getStatus() == 1 ) )
+		{
+			actNbrCount++;
+		}
+	}
+
+	return actNbrCount;
+}
+
 // used for debugging purpose
 void
 Adl::printAdl(){
diff --git a/nlsr_adl.hpp b/nlsr_adl.hpp
index 71829c1..d6923e1 100644
--- a/nlsr_adl.hpp
+++ b/nlsr_adl.hpp
@@ -5,6 +5,8 @@
 #include "nlsr_adjacent.hpp"
 #include<list>
 
+class nlsr;
+
 using namespace std;
 
 class Adl{
@@ -23,6 +25,14 @@
 	void setStatusOfNeighbor(string& neighbor, int status);
 	void setTimedOutInterestCount(string& neighbor, int count);
 
+	bool isAdjLsaBuildable(nlsr& pnlsr);
+	int getNumOfActiveNeighbor();
+
+	int getAdlSize()
+	{
+		return adjList.size();
+	}
+
 	void printAdl();
 
 private:	
diff --git a/nlsr_conf_param.hpp b/nlsr_conf_param.hpp
index ce56c72..817bf2e 100644
--- a/nlsr_conf_param.hpp
+++ b/nlsr_conf_param.hpp
@@ -7,17 +7,12 @@
 
 class ConfParameter{
 	
-	public:
-		ConfParameter()
-			:chronosyncSyncPrefix("ndn/nlsr/sync")
-			,chronosyncLsaPrefix("/ndn/nlsr/LSA")
+public:
+	ConfParameter()
+		:chronosyncSyncPrefix("ndn/nlsr/sync")
+		,chronosyncLsaPrefix("/ndn/nlsr/LSA")
 		{
-			adjBuildFlag=0;
-        		adjBuildCount=0;
-        		isBuildAdjLsaSheduled=0;
-        		isRouteCalculationScheduled=0;
-			isRoutingTableCalculating=0;
-        		isStrictHierchicalKeyCheck=0;
+      isStrictHierchicalKeyCheck=0;
 
 			interestRetryNumber=3;
 			interestResendTime=5;
@@ -27,10 +22,8 @@
 			maxFacesPerPrefix=0;
 			tunnelType=0;
 			detailedLogging=0;
-        		debugging=0;
-			isHyperbolicCalc=0;
-			
-			
+      debugging=0;
+			isHyperbolicCalc=0;	
 		}
 
 		void setRouterName(const string& rn){  
@@ -206,13 +199,6 @@
 	double corTheta;
 
 	int tunnelType;
-
-	int adjBuildFlag;
-	long int adjBuildCount;
-	int isBuildAdjLsaSheduled;
-	int isRouteCalculationScheduled;
-
-	int isRoutingTableCalculating;
 	int isStrictHierchicalKeyCheck;
 
 };
diff --git a/nlsr_dm.cpp b/nlsr_dm.cpp
index 7b958de..1ff7555 100644
--- a/nlsr_dm.cpp
+++ b/nlsr_dm.cpp
@@ -6,6 +6,7 @@
 #include "nlsr.hpp"
 #include "nlsr_dm.hpp"
 #include "nlsr_tokenizer.hpp"
+#include "nlsr_lsdb.hpp"
 
 using namespace std;
 using namespace ndn;
@@ -40,28 +41,43 @@
 	string chkString("info");
 	string neighbor="/" + nt.getFirstToken()
 							+nt.getTokenString(0,nt.getTokenPosition(chkString)-1);
-	int status=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+	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: "<< status << 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);
 
-	status=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+	int newStatus=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
 	infoIntTimedOutCount=pnlsr.getAdl().getTimedOutInterestCount(neighbor);
 
 	//debugging purpose
 	cout <<"After Updates: " <<endl;
 	cout <<"Neighbor : "<<neighbor<<endl;
-	cout<<"Status: "<< status << endl;
+	cout<<"Status: "<< newStatus << endl;
 	cout<<"Info Interest Timed out: "<< infoIntTimedOutCount <<endl;
 	//debugging purpose end
 
-	/* Need to schedule event for Adjacency LSA building */
+	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)));
+		}
+		
+	}
+
+	
 	
 }
diff --git a/nlsr_im.cpp b/nlsr_im.cpp
index a29fac9..cdcba5f 100644
--- a/nlsr_im.cpp
+++ b/nlsr_im.cpp
@@ -7,6 +7,7 @@
 #include "nlsr_im.hpp"
 #include "nlsr_dm.hpp"
 #include "nlsr_tokenizer.hpp"
+#include "nlsr_lsdb.hpp"
 
 using namespace std;
 using namespace ndn;
@@ -98,7 +99,15 @@
 	  (infoIntTimedOutCount == pnlsr.getConfParameter().getInterestRetryNumber()))
 	{
 		pnlsr.getAdl().setStatusOfNeighbor(neighbor,0);
-		// schedule event for building adjacency LSA
+		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)));
+		}
 	}
 	
 }
diff --git a/nlsr_lsa.cpp b/nlsr_lsa.cpp
index a92687e..5495859 100644
--- a/nlsr_lsa.cpp
+++ b/nlsr_lsa.cpp
@@ -4,6 +4,7 @@
 
 #include "nlsr_lsa.hpp"
 #include "nlsr_npl.hpp"
+#include "nlsr_adjacent.hpp"
 
 using namespace std;
 
@@ -15,7 +16,7 @@
 	return key;
 }
 
-NameLsa::NameLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, Npl& npl)
+NameLsa::NameLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, Npl npl)
 {
 	origRouter=origR;
 	lsType=lst;
@@ -110,3 +111,68 @@
 	return os;
 }
 
+
+AdjLsa::AdjLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, 
+	                                                        uint32_t nl ,Adl padl)
+{
+	origRouter=origR;
+	lsType=lst;
+	lsSeqNo=lsn;
+	lifeTime=lt;
+	noLink=nl;
+
+	std::list<Adjacent> al=padl.getAdjList();
+	for( std::list<Adjacent>::iterator it=al.begin(); it != al.end(); it++)
+	{
+		if((*it).getStatus()==1)
+		{
+				addAdjacentToLsa((*it));
+		}
+	}
+}
+
+string 
+AdjLsa::getAdjLsaData(){
+	string adjLsaData;
+	adjLsaData=origRouter + "|" + boost::lexical_cast<std::string>(lsType) + "|" 
+	    + boost::lexical_cast<std::string>(lsSeqNo) + "|" 
+	    + boost::lexical_cast<std::string>(lifeTime);
+	adjLsaData+="|";
+	adjLsaData+=boost::lexical_cast<std::string>(adl.getAdlSize());
+
+	std::list<Adjacent> al=adl.getAdjList();
+	for( std::list<Adjacent>::iterator it=al.begin(); it != al.end(); it++)
+	{
+		adjLsaData+="|";
+		adjLsaData+=(*it).getAdjacentName();
+		adjLsaData+="|";
+		adjLsaData+=boost::lexical_cast<std::string>((*it).getConnectingFace());
+		adjLsaData+="|";
+		adjLsaData+=boost::lexical_cast<std::string>((*it).getLinkCost());
+		
+	}
+	return adjLsaData;
+}
+
+std::ostream& 
+operator<<(std::ostream& os, AdjLsa& aLsa) 
+{
+	os<<"Adj Lsa: "<<endl;
+	os<<"  Origination Router: "<<aLsa.getOrigRouter()<<endl;
+	os<<"  Ls Type: "<<(unsigned short)aLsa.getLsType()<<endl;
+	os<<"  Ls Seq No: "<<(unsigned int)aLsa.getLsSeqNo()<<endl;
+	os<<"  Ls Lifetime: "<<(unsigned int)aLsa.getLifeTime()<<endl;
+	os<<"  No Link: "<<(unsigned int)aLsa.getNoLink()<<endl;
+	os<<"  Adjacents: "<<endl;
+	int i=1;
+	std::list<Adjacent> al=aLsa.getAdl().getAdjList();
+	for( std::list<Adjacent>::iterator it=al.begin(); it != al.end(); it++)
+	{
+		os<<"    Adjacent "<<i<<": "<<endl;
+		os<<"      Adjacent Name: "<<(*it).getAdjacentName()<<endl;
+		os<<"      Connecting Face: "<<(*it).getConnectingFace()<<endl;
+		os<<"      Link Cost: "<<(*it).getLinkCost()<<endl;
+	}
+	
+	return os;  
+}
diff --git a/nlsr_lsa.hpp b/nlsr_lsa.hpp
index 18a09d3..225229f 100644
--- a/nlsr_lsa.hpp
+++ b/nlsr_lsa.hpp
@@ -73,7 +73,7 @@
 		setLsType(1);
 	}
 
-	NameLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, Npl& npl);
+	NameLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, Npl npl);
 
 	Npl& getNpl(){
 		return npl;
@@ -100,6 +100,24 @@
 		: Lsa()
 		, adl()
 	{
+		setLsType(2);
+	}
+
+	AdjLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, 
+	                                                        uint32_t nl ,Adl padl);
+	Adl& getAdl(){
+		return adl;
+	}
+
+	void addAdjacentToLsa(Adjacent adj)
+	{
+		adl.insert(adj);
+	}
+
+	string getAdjLsaData();
+	uint32_t getNoLink()
+	{
+		return noLink;
 	}
 
 private:
@@ -107,11 +125,15 @@
 	Adl adl;
 };
 
+std::ostream& 
+operator<<(std::ostream& os, AdjLsa& aLsa);
+
 class CorLsa:public Lsa{
 public:
 	CorLsa()
 		:Lsa()
 	{
+		setLsType(3);
 	}
 
 	CorLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt
diff --git a/nlsr_lsdb.cpp b/nlsr_lsdb.cpp
index c6ae523..f62d12b 100644
--- a/nlsr_lsdb.cpp
+++ b/nlsr_lsdb.cpp
@@ -148,7 +148,7 @@
 bool 
 Lsdb::buildAndInstallOwnCorLsa(nlsr& pnlsr){
 	CorLsa corLsa(pnlsr.getConfParameter().getRouterPrefix()
-					, 1
+					, 3
 					, pnlsr.getCorLsaSeq()+1
 					, pnlsr.getConfParameter().getRouterDeadInterval()
 					, pnlsr.getConfParameter().getCorR()
@@ -248,7 +248,109 @@
 }
 
 
+void 
+Lsdb::scheduledAdjLsaBuild(nlsr& pnlsr)
+{
+	cout<<"scheduledAdjLsaBuild Called"<<endl;
+	pnlsr.setIsBuildAdjLsaSheduled(0);
 
+	if( pnlsr.getAdl().isAdjLsaBuildable(pnlsr))
+	{
+		int adjBuildCount=pnlsr.getAdjBuildCount();
+		if(adjBuildCount>0 )
+		{
+			if (pnlsr.getAdl().getNumOfActiveNeighbor()>0)
+			{
+				buildAndInstallOwnAdjLsa(pnlsr);
+			}
+			else
+			{
+				//remove if there is any adj lsa in LSDB
+			}
+			pnlsr.setAdjBuildCount(pnlsr.getAdjBuildCount()-adjBuildCount);
+		}		
+	}
+	else
+	{
+		pnlsr.setIsBuildAdjLsaSheduled(1);
+		int schedulingTime=pnlsr.getConfParameter().getInterestRetryNumber()*
+		                   pnlsr.getConfParameter().getInterestRetryNumber();
+		pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(schedulingTime),
+							ndn::bind(&Lsdb::scheduledAdjLsaBuild, pnlsr.getLsdb(), 
+																									boost::ref(pnlsr)));
+	}
+
+}
+
+
+bool 
+Lsdb::addAdjLsa(AdjLsa &alsa)
+{
+	std::list<AdjLsa >::iterator it = std::find_if( adjLsdb.begin(), 
+																		adjLsdb.end(),	
+   																	bind(adjLsaCompare, _1, alsa));
+
+	if( it == adjLsdb.end()){
+		adjLsdb.push_back(alsa);
+		return true;
+	}
+	return false;
+	
+}
+
+AdjLsa& 
+Lsdb::getAdjLsa(string key)
+{
+	std::list<AdjLsa >::iterator it = std::find_if( adjLsdb.begin(), 
+																		adjLsdb.end(),	
+   																	bind(adjLsaCompareByKey, _1, key));
+
+	if( it != adjLsdb.end()){
+		return (*it);
+	}
+	
+}
+
+bool 
+Lsdb::installAdjLsa(AdjLsa &alsa)
+{
+	bool doesLsaExist_ = doesAdjLsaExist(alsa.getLsaKey());
+	if ( !doesLsaExist_ )
+	{
+		// add Adj LSA
+		addAdjLsa(alsa);
+		// schedule routing table calculation
+	}
+	else
+	{
+		// check for newer name LSA
+		AdjLsa oldAdjLsa=getAdjLsa(alsa.getLsaKey());
+		
+	}
+
+	printAdjLsdb();
+	
+	return true;
+}
+
+bool 
+Lsdb::buildAndInstallOwnAdjLsa(nlsr& pnlsr)
+{
+	AdjLsa adjLsa(pnlsr.getConfParameter().getRouterPrefix()
+					, 2
+					, pnlsr.getAdjLsaSeq()+1
+					, pnlsr.getConfParameter().getRouterDeadInterval()
+					, pnlsr.getAdl().getNumOfActiveNeighbor()
+					, pnlsr.getAdl() );
+	pnlsr.setAdjLsaSeq(pnlsr.getAdjLsaSeq()+1);
+	return installAdjLsa(adjLsa);
+}
+
+bool 
+Lsdb::removeAdjLsa(string& key)
+{
+	
+}
 
 bool 
 Lsdb::doesAdjLsaExist(string key)
@@ -264,4 +366,13 @@
 	return true;
 }
 
+void 
+Lsdb::printAdjLsdb()
+{
+	for( std::list<AdjLsa>::iterator it=adjLsdb.begin(); 
+	                                                 it!= adjLsdb.end() ; it++)
+	{
+		cout<< (*it) <<endl;
+	}
+}
 
diff --git a/nlsr_lsdb.hpp b/nlsr_lsdb.hpp
index 0b0e664..58e0d53 100644
--- a/nlsr_lsdb.hpp
+++ b/nlsr_lsdb.hpp
@@ -28,14 +28,26 @@
 	bool installCorLsa(CorLsa &clsa);
 	bool removeCorLsa(string& key);
 	void printCorLsdb(); //debugging
+
+	//function related to Cor LSDB
+	void scheduledAdjLsaBuild(nlsr& pnlsr);
+	bool buildAndInstallOwnAdjLsa(nlsr& pnlsr);
+	bool removeAdjLsa(string& key);
+	bool installAdjLsa(AdjLsa &alsa);
+	AdjLsa& getAdjLsa(string key);
+	void printAdjLsdb();
 	
 private:
 	bool addNameLsa(NameLsa &nlsa);
-	bool addCorLsa(CorLsa& clsa);
 	bool doesNameLsaExist(string key);
-	bool doesAdjLsaExist(string key);
+	
+	bool addCorLsa(CorLsa& clsa);
 	bool doesCorLsaExist(string key);
 
+	bool addAdjLsa(AdjLsa &alsa);
+	bool doesAdjLsaExist(string key);
+	
+
 private:
 	std::list<NameLsa> nameLsdb;
 	std::list<AdjLsa> adjLsdb;