Development Complete, README File To Be Updated
diff --git a/ndn-traffic-server.cpp b/ndn-traffic-server.cpp
index 4b12510..e059bbe 100644
--- a/ndn-traffic-server.cpp
+++ b/ndn-traffic-server.cpp
@@ -14,25 +14,242 @@
 

 using namespace ndn;

 

+class Logger

+{

+public:

+

+  Logger()

+  {

+    logLocation_ = "";

+  }

+

+  void

+  shutdownLogger()

+  {

+    if (logFile_.is_open())

+    {

+      log("Terminating Logging Operations" , true, true);

+      logFile_.close();

+    }

+  }

+

+  static std::string

+  getTimestamp()

+  {

+    boost::posix_time::ptime now;

+    now = boost::posix_time::second_clock::local_time();

+    return to_simple_string(now);

+  }

+

+  void

+  log( std::string logLine, bool printTime, bool printToConsole )

+  {

+    if( logLocation_.length() > 0 )

+    {

+      if (printTime)

+        logFile_ << getTimestamp() << " - ";

+      logFile_ << logLine << std::endl;

+      logFile_.flush();

+      if (printToConsole)

+      {

+        if (printTime)

+          std::cout << getTimestamp() << " - ";

+        std::cout << logLine << std::endl;

+      }

+    }

+    else

+    {

+      if (printTime)

+        std::cout << getTimestamp() << " - ";

+      std::cout << logLine << std::endl;

+    }

+  }

+

+  void

+  initializeLog( std::string instanceId )

+  {

+    char* variableValue = std::getenv("NDN_TRAFFIC_LOGFOLDER");

+    std::string logFilename;

+    logLocation_ = "";

+    if (variableValue != NULL)

+      logLocation_ = variableValue;

+    if (boost::filesystem::exists(boost::filesystem::path(logLocation_)))

+    {

+      if (boost::filesystem::is_directory(boost::filesystem::path(logLocation_)))

+      {

+        logFilename = logLocation_+"/NDNTrafficServer_"+instanceId+".log";

+        logFile_.open(logFilename.c_str(), std::ofstream::out | std::ofstream::trunc);

+        if (logFile_.is_open())

+          std::cout << "Log File Initialized: " << logFilename << std::endl;

+        else

+        {

+          std::cout << "ERROR - Unable To Initialize A Log File At: " << logLocation_ << std::endl

+                    << "Using Default Output For Logging." << std::endl;

+          logLocation_ = "";

+        }

+      }

+      else

+      {

+        std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Should Be A Folder." << std::endl

+                  << "Using Default Output For Logging." << std::endl;

+        logLocation_ = "";

+      }

+    }

+    else

+    {

+      std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Not Set." << std::endl

+                << "Using Default Output For Logging." << std::endl;

+      logLocation_ = "";

+    }

+  }

+

+private:

+

+  std::string logLocation_;

+  std::ofstream logFile_;

+

+};

+

+

 class NdnTrafficServer

 {

 public:

 

-  NdnTrafficServer( char* programName ) : ioService_(new boost::asio::io_service), face_(ioService_)

+  NdnTrafficServer( char* programName ) : ioService_(new boost::asio::io_service), face_(ioService_), keyChain_()

   {

-    std::stringstream randomId;

     std::srand(std::time(0));

-    randomId << std::rand();

-    instanceId_ = randomId.str();

+    instanceId_ = toString(std::rand());

     programName_ = programName;

     contentDelayTime_ = getDefaultContentDelayTime();

-    logLocation_ = "";

+    totalRegistrationsFailed_ = 0;

     configurationFile_ = "";

+    totalInterestReceived_ = 0;

   }

 

-  NdnTrafficServer()

-  : keyChain_()

+  class DataTrafficConfiguration

   {

+  public:

+

+    DataTrafficConfiguration()

+    {

+      name = "";

+      contentType = -1;

+      freshnessPeriod = -1;

+      contentBytes = -1;

+      content = "";

+      totalInterestReceived = 0;

+    }

+

+    void

+    printTrafficConfiguration( Logger& logger )

+    {

+      std::string detail;

+      detail = "";

+      if (name != "")

+        detail += "Name="+name+", ";

+      if (contentType >= 0)

+        detail += "ContentType="+toString(contentType)+", ";

+      if (freshnessPeriod >= 0)

+        detail += "FreshnessPeriod="+toString(freshnessPeriod)+", ";

+      if (contentBytes >= 0)

+        detail += "ContentBytes="+toString(contentBytes)+", ";

+      if (content != "")

+        detail += "Content="+content+", ";

+      if (detail.length() >= 0)

+        detail = detail.substr(0, detail.length()-2);

+      logger.log(detail, false, false);

+    }

+

+

+    bool

+    extractParameterValue( std::string detail, std::string& parameter, std::string& value )

+    {

+      int i;

+      std::string allowedCharacters = ":/+._-%";

+      parameter = "";

+      value = "";

+      i = 0;

+      while (detail[i] != '=' && i < detail.length())

+      {

+        parameter += detail[i];

+        i++;

+      }

+      if (i == detail.length())

+        return false;

+      i++;

+      while ((std::isalnum(detail[i]) || allowedCharacters.find(detail[i]) != std::string::npos) && i < detail.length())

+      {

+        value += detail[i];

+        i++;

+      }

+      if(parameter == "" || value == "")

+        return false;

+      return true;

+    }

+

+    bool

+    processConfigurationDetail( std::string detail, Logger& logger, int lineNumber )

+    {

+      std::string parameter, value;

+      if (extractParameterValue(detail, parameter, value))

+      {

+        if (parameter == "Name")

+          name = value;

+        else if (parameter == "ContentType")

+          contentType = toInteger(value);

+        else if (parameter == "FreshnessPeriod")

+          freshnessPeriod = toInteger(value);

+        else if (parameter == "ContentBytes")

+          contentBytes = toInteger(value);

+        else if (parameter == "Content")

+          content = value;

+        else

+          logger.log("Line "+toString(lineNumber)+" \t- Invalid Parameter='"+parameter+"'", false, true);

+      }

+      else

+      {

+        logger.log("Line "+toString(lineNumber)+" \t- Improper Traffic Configuration Line- "+detail, false, true);

+        return false;

+      }

+      return true;

+    }

+

+    bool

+    checkTrafficDetailCorrectness()

+    {

+      return true;

+    }

+

+    std::string name;

+    int contentType;

+    int freshnessPeriod;

+    int contentBytes;

+    std::string content;

+    int totalInterestReceived;

+

+  };

+

+  std::string

+  getDefaultContent()

+  {

+    return "";

+  }

+

+  static std::string

+  toString( int integerValue )

+  {

+    std::stringstream stream;

+    stream << integerValue;

+    return stream.str();

+  }

+

+  static int

+  toInteger( std::string stringValue )

+  {

+    int integerValue;

+    std::stringstream stream(stringValue);

+    stream >> integerValue;

+    return integerValue;

   }

 

   void

@@ -66,44 +283,174 @@
   void

   signalHandler()

   {

+    logger_.shutdownLogger();

     face_.shutdown();

     ioService_.reset();

+    logStatistics();

     exit(1);

   }

 

   void

-  initializeLog()

+  logStatistics()

   {

-    char* variableValue = std::getenv("NDN_TRAFFIC_LOGFOLDER");

-    if (variableValue != NULL)

-      logLocation_ = variableValue;

-

-    if (boost::filesystem::exists(boost::filesystem::path(logLocation_)))

+    int patternId;

+    logger_.log("\n\n== Interest Traffic Report ==\n", false, true);

+    logger_.log("Total Traffic Pattern Types = "+toString((int)trafficPattern_.size()), false, true);

+    logger_.log("Total Interests Received    = "+toString(totalInterestReceived_), false, true);

+    for (patternId=0; patternId<trafficPattern_.size(); patternId++)

     {

-      if (boost::filesystem::is_directory(boost::filesystem::path(logLocation_)))

+      logger_.log("\nTraffic Pattern Type #"+toString(patternId+1), false, true);

+      trafficPattern_[patternId].printTrafficConfiguration(logger_);

+      logger_.log("Total Interests Received    = "+toString(trafficPattern_[patternId].totalInterestReceived)+"\n", false, true);

+    }

+  }

+

+  bool

+  checkTrafficPatternCorrectness()

+  {

+    return true;

+  }

+

+  void

+  analyzeConfigurationFile()

+  {

+    int patternId;

+    int lineNumber;

+    bool skipLine;

+    std::string patternLine;

+    std::ifstream patternFile;

+    logger_.log("Analyzing Traffic Configuration File: " + configurationFile_, true, true);

+    patternFile.open(configurationFile_.c_str());

+    if (patternFile.is_open())

+    {

+      patternId = 0;

+      lineNumber = 0;

+      while (getline(patternFile, patternLine))

       {

-        logLocation_ += "/NDNTrafficServer_"+instanceId_+".log";

-        std::cout << "Log File Initialized: " << logLocation_ << std::endl;

+        lineNumber++;

+        if (std::isalpha(patternLine[0]))

+        {

+          DataTrafficConfiguration dataData;

+          skipLine = false;

+          patternId++;

+          if (dataData.processConfigurationDetail(patternLine, logger_, lineNumber))

+          {

+            while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))

+            {

+              lineNumber++;

+              if (!dataData.processConfigurationDetail(patternLine, logger_, lineNumber))

+              {

+                skipLine = true;

+                break;

+              }

+            }

+            lineNumber++;

+          }

+          else

+            skipLine = true;

+          if( !skipLine )

+          {

+            if (dataData.checkTrafficDetailCorrectness())

+              trafficPattern_.push_back(dataData);

+          }

+        }

       }

-      else

+      patternFile.close();

+      if (!checkTrafficPatternCorrectness())

       {

-        std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Should Be A Folder.\n"

-                     "Using Default Output For Logging." << std::endl;

-        logLocation_ = "";

+        logger_.log("ERROR - Traffic Configuration Provided Is Not Proper- " + configurationFile_, false, true);

+        logger_.shutdownLogger();

+        exit(1);

+      }

+      logger_.log("Traffic Configuration File Processing Completed\n", true, false);

+      for (patternId = 0; patternId < trafficPattern_.size(); patternId++)

+      {

+        logger_.log("Traffic Pattern Type #"+toString(patternId+1), false, false);

+        trafficPattern_[patternId].printTrafficConfiguration(logger_);

+        logger_.log("", false, false);

       }

     }

     else

     {

-      std::cout << "Environment Variable NDN_TRAFFIC_LOGFOLDER Not Set.\n"

-                   "Using Default Output For Logging." << std::endl;

-      logLocation_ = "";

+      logger_.log("ERROR - Unable To Open Traffic Configuration File: " + configurationFile_, false, true);

+      logger_.shutdownLogger();

+      exit(1);

     }

   }

 

   void

   initializeTrafficConfiguration()

   {

-    std::cout << "Traffic Configuration File: " << configurationFile_ << std::endl;

+    if (boost::filesystem::exists(boost::filesystem::path(configurationFile_)))

+    {

+      if(boost::filesystem::is_regular_file(boost::filesystem::path(configurationFile_)))

+      {

+        analyzeConfigurationFile();

+      }

+      else

+      {

+        logger_.log("ERROR - Traffic Configuration File Is Not A Regular File: " + configurationFile_, false, true);

+        logger_.shutdownLogger();

+        exit(1);

+      }

+    }

+    else

+    {

+      logger_.log("ERROR - Traffic Configuration File Does Not Exist: " + configurationFile_, false, true);

+      logger_.shutdownLogger();

+      exit(1);

+    }

+  }

+

+  static std::string

+  getRandomByteString( int randomSize )

+  {

+    int i;

+    std::string characterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvw0123456789";

+    std::string randomData;

+    for (i=0; i<randomSize; i++)

+      randomData += characterSet[std::rand() % characterSet.length()];

+    return randomData;

+  }

+

+  void

+  onInterest( const Name& name, const Interest& interest, int patternId )

+  {

+    std::string content, logLine;

+    content = "";

+    logLine = "";

+    Data data(interest.getName());

+    if (trafficPattern_[patternId].contentType >= 0)

+      data.setContentType(trafficPattern_[patternId].contentType);

+    if (trafficPattern_[patternId].freshnessPeriod >= 0)

+      data.setFreshnessPeriod(trafficPattern_[patternId].freshnessPeriod);

+    if (trafficPattern_[patternId].contentBytes >= 0)

+      content = getRandomByteString(trafficPattern_[patternId].contentBytes);

+    if (trafficPattern_[patternId].content != "")

+      content = trafficPattern_[patternId].content;

+    data.setContent((const uint8_t*)content.c_str(), content.length());

+    keyChain_.sign(data);

+    totalInterestReceived_++;

+    trafficPattern_[patternId].totalInterestReceived++;

+    logLine += "Interest Received          - PatternID="+toString(patternId);

+    logLine += ", GlobalID="+toString(totalInterestReceived_);

+    logLine += ", LocalID="+toString(trafficPattern_[patternId].totalInterestReceived);

+    logLine += ", Name="+trafficPattern_[patternId].name;

+    logger_.log(logLine, true, false);

+    face_.put(data);

+  }

+

+  void

+  onRegisterFailed( const ndn::Name& prefix, const std::string& reason, int patternId )

+  {

+    std::string logLine;

+    logLine = "";

+    logLine += "Prefix Registration Failed - PatternID="+toString(patternId);

+    logLine += ", Name="+trafficPattern_[patternId].name;

+    logger_.log(logLine, true, true);

+    totalRegistrationsFailed_++;

+    if (totalRegistrationsFailed_ == trafficPattern_.size())

+      signalHandler();

   }

 

   void

@@ -111,20 +458,43 @@
   {

     boost::asio::signal_set signalSet(*ioService_, SIGINT, SIGTERM);

     signalSet.async_wait(boost::bind(&NdnTrafficServer::signalHandler, this));

-    initializeLog();

+    logger_.initializeLog(instanceId_);

     initializeTrafficConfiguration();

+

+    int patternId;

+    for (patternId=0; patternId<trafficPattern_.size(); patternId++ )

+    {

+      face_.setInterestFilter(  trafficPattern_[patternId].name,

+                                func_lib::bind( &NdnTrafficServer::onInterest,

+                                                this, _1, _2,

+                                                patternId),

+                                func_lib::bind( &NdnTrafficServer::onRegisterFailed,

+                                                this, _1, _2,

+                                                patternId));

+    }

+

+    try {

+      face_.processEvents();

+    }

+    catch(std::exception &e) {

+      logger_.log("ERROR: "+(std::string)e.what(), true, true);

+      logger_.shutdownLogger();

+    }

   }

 

 private:

 

   KeyChain keyChain_;

   std::string programName_;

+  std::string instanceId_;

   int contentDelayTime_;

-  std::string logLocation_;

+  int totalRegistrationsFailed_;

+  Logger logger_;

   std::string configurationFile_;

   ptr_lib::shared_ptr<boost::asio::io_service> ioService_;

   Face face_;

-  std::string instanceId_;

+  std::vector<DataTrafficConfiguration> trafficPattern_;

+  int totalInterestReceived_;

 

 };