New features
authorEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Mon, 6 Apr 2015 00:11:05 +0000 (02:11 +0200)
committerEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Mon, 6 Apr 2015 00:11:05 +0000 (02:11 +0200)
example/diameter/pcapDecoder/main.cpp
example/diameter/stackManagement/main.cpp
example/diameter/tme/main.cpp
include/anna/core/util/MultiRangeExpression.hpp
include/anna/diameter/stack/Avp.hpp
include/anna/diameter/stack/Dictionary.hpp
include/anna/diameter/stack/Engine.hpp
source/core/util/MultiRangeExpression.cpp
source/diameter/stack/Engine.cpp

index 8029b51..30d9cba 100644 (file)
@@ -327,7 +327,8 @@ void _exit(const std::string &message, int resultCode = 1) {
 //-------------------------------------------------------------------
 int main(int argc, char **argv) {
   std::string exec = argv[0];
-  std::string filetrace = exec.substr(exec.find_last_of("/") + 1) + ".trace";
+  std::string execBN = exec.substr(exec.find_last_of("/") + 1);
+  std::string filetrace = execBN + ".trace";
   std::cout << std::endl;
 
   //check command line arguments
@@ -352,7 +353,7 @@ int main(int argc, char **argv) {
             << (ignoreFlags ? "non strict" : "strict") << std::endl;
   // Logger and engines:
   Logger::setLevel(Logger::Debug);
-  Logger::initialize("pcapDecoder", new TraceWriter(filetrace.c_str(), 2048000));
+  Logger::initialize(execBN.c_str(), new TraceWriter(filetrace.c_str(), 2048000));
   anna::diameter::codec::Engine *codecEngine =
     new anna::diameter::codec::Engine();
   anna::diameter::stack::Engine &stackEngine =
index 96645b3..2526a7a 100644 (file)
@@ -67,7 +67,7 @@ int main(int argc, char** argv) {
    std::string exec = argv[0];
    std::string param = argv[1] ? argv[1] : "";
 
-   if (param == "") {
+   if (argc < 2) {
       std::string msg = anna::functions::asString("Usage: %s <list of xml dictionaries overloaded>,\n     i.e. '%s avps.xml commands.xml'", exec.c_str(), exec.c_str());
       _exit(msg);
    }
index 08e5f9f..68e2295 100644 (file)
@@ -85,8 +85,8 @@ int main(int argc, char** argv) {
   std::string exec = argv[0];
   std::string param = argv[1] ? argv[1] : "";
 
-  if (param == "") {
-    std::string msg = "Use: "; msg += exec; msg += " <xml directory>";
+  if (argc < 2) {
+    std::string msg = "Usage: "; msg += exec; msg += " <xml directory>";
     msg += "\n     xml directory: contains the xml files needed, which are:";
     msg += "\n";
     msg += "\n                       avps_ietf.xml";
index 665094a..ab3273c 100644 (file)
@@ -63,18 +63,62 @@ public:
   ~MultiRangeExpression() {};
 
 
-  // get
+  /**
+  * Gets the configured literal by mean #setLiteral or #addLiteral
+  *
+  * @return Literal
+  */
   const char * getLiteral(void) const throw() { return a_literal.c_str(); }
+
+  /**
+  * Gets expanded representation for stored literal. E.g.: '1-3,8,10' => '1,2,3,7,8,10'
+  *
+  * @return Expanded literal
+  */
   std::string getExpandedLiteral(void) const throw();
 
+  /**
+  * Simplify stored literal. E.g.: '1,1,1,2,3,7,8,10' => '1-3,8,10' and returns it.
+  *
+  * @return Simplified literal
+  */
+  const char * simplifyLiteral(void) throw();
+
   // helpers
+
+  /**
+  * Returns true if the value provided is contained in the multirange expression literal
+  *
+  * @param value Value to be tested
+  * @return True or false
+  */
   bool contain(const unsigned int & value) const throw() { return (a_data.find(value) != a_data.end()); }
 
-  // set
+  // setters
+
+  /**
+  * Configures a new literal
+  *
+  * @param l Literal to be stored
+  */
   void setLiteral(const char * l) throw() {
     a_literal = l ? l : "";
     refresh();
   }
+
+  /**
+  * Accumulates the provided literal over the stored literal
+  * You could simplify with #simplifyLiteral, because perhaps there is overlapping between current literal and provided one.
+  *
+  * @param l Literal to be added
+  */
+  void addLiteral(const char * l) throw() {
+    if (l) {
+      a_literal += ",";
+      a_literal += l;
+    }
+    refresh();
+  }
 };
 
 };
index 9a124e5..1c2de1d 100644 (file)
@@ -229,10 +229,11 @@ public:
   void setFormatName(const std::string & fn) throw() { a_formatName = fn; }
   void setVbit(const FlagRule::_v &v) throw() { a_vBit = v; }
   void setMbit(const FlagRule::_v &m) throw() { a_mBit = m; }
-  void setPbit(const FlagRule::_v &p) throw() { a_pBit = p; }
+  void setPbit(const FlagRule::_v &p) throw() { a_pBit = p; } // deprecated flag ...
   void setMayEncrypt(bool me) throw() { a_mayEncrypt = me; }
 
   void setEnums(const char * e) throw() { a_enums.setLiteral(e); }
+  void addEnums(const char * e) throw() { a_enums.addLiteral(e); a_enums.simplifyLiteral(); }
 
   // After format configuration:
   void addLabel(const std::string & data,  const std::string & alias) throw(anna::RuntimeException);
index e5eece2..bd4cd4d 100644 (file)
@@ -110,10 +110,12 @@ public:
   typedef std::map<CommandId, Command, lessCommand> command_container;
   typedef command_container::const_iterator const_command_iterator;
 
+protected:
+  std::string a_name;
+
 private:
 
   bool a_allowUpdates;
-  std::string a_name;
   format_container a_formats;
   vendor_container a_vendors;
   avp_container a_avps;
index 165d779..ca3f758 100644 (file)
@@ -145,6 +145,17 @@ public:
   */
   Dictionary * createDictionary(int stackId, const std::string & xmlPathFile = "") throw(anna::RuntimeException);
 
+  /**
+  * Register a externally created Dictionary or a derived class from Dictionary
+  *
+  * @param stackId Stack identifier for provided dictionary. We recommend to use the Diameter 'Application-Id' unless
+  * the application is going to use dictionaries covering different applications (which is not very usual).
+  * @param dictionary Externally created dictionary
+  *
+  * @return Dictionary registered. When exception happen, dictionary can be accessed by #getDictionary
+  */
+  Dictionary * registerDictionary(int stackId, Dictionary *dictionary) throw(anna::RuntimeException);
+
   /**
   * Loads an XML dictionary document over the diameter stack identifiers (one or more stack id's).
   * Passing more than one stack id, synchronized loadings are performed, which could be useful when
index 75ca563..3c2307d 100644 (file)
@@ -109,3 +109,46 @@ std::string anna::MultiRangeExpression::getExpandedLiteral(void) const throw() {
   return (result);
 }
 
+
+//------------------------------------------------------------------------------
+//-------------------------------------- MultiRangeExpression::simplifyLiteral()
+//------------------------------------------------------------------------------
+const char * anna::MultiRangeExpression::simplifyLiteral(void) throw() {
+
+  if (a_data.size() == 0) return NULL;
+
+  std::map < unsigned int, int/*dummy*/ >::const_iterator it;
+  std::map < unsigned int, int/*dummy*/ >::const_iterator it_min(a_data.begin());
+  std::map < unsigned int, int/*dummy*/ >::const_iterator it_max(a_data.end());
+
+  unsigned int min = UINT_MAX;
+  unsigned int max = 0;
+  unsigned int value;
+  unsigned int prevValue = a_data.begin()->first;
+
+  a_literal = "";
+
+  for(it = it_min; it != it_max; it++) {
+    value = (*it).first;
+    if (value < min) min = value;
+    if (value - prevValue > 1) {
+      a_literal += anna::functions::asString(min);
+      a_literal += "-";
+      a_literal += anna::functions::asString(max);
+      a_literal += ",";
+      min = value;
+    }
+    if (value > max) max = value;
+
+    prevValue = value;
+  }
+
+  a_literal += anna::functions::asString(min);
+  if (max != min) {
+    a_literal += "-";
+    a_literal += anna::functions::asString(max);
+  }
+
+  return a_literal.c_str();
+}
+
index 7a0f799..07daa79 100644 (file)
@@ -204,19 +204,38 @@ std::string anna::diameter::stack::Engine::asString(void) const throw() {
 
 
 //------------------------------------------------------------------------------
-//--------------------------------------------------- Engine::createDictionary()
+//------------------------------------------------- Engine::registerDictionary()
 //------------------------------------------------------------------------------
-anna::diameter::stack::Dictionary *  anna::diameter::stack::Engine::createDictionary(int stackId, const std::string & xmlPathFile) throw(anna::RuntimeException) {
+anna::diameter::stack::Dictionary * anna::diameter::stack::Engine::registerDictionary(int stackId, Dictionary *dictionary) throw(anna::RuntimeException) {
   Dictionary * result = const_cast<Dictionary *>(getDictionary(stackId));
 
+  if(!dictionary)
+    throw anna::RuntimeException("Cannot provide a NULL dictionary. It must be previously allocated", ANNA_FILE_LOCATION);
+
   if(result) {  // if exists, launch exception
     throw anna::RuntimeException("Such provided stack id has already been created. Removes it before call this method", ANNA_FILE_LOCATION);
   } else { // new stack
-    a_stacks[stackId] = new Dictionary(); // no need for singleton destructor
+    a_stacks[stackId] = dictionary; // no need for singleton destructor
     const_stack_iterator it = a_stacks.find(stackId);
-    result = (Dictionary *)(*it).second;
+    //result = (Dictionary *)(*it).second;
+    result = dictionary;
   }
 
+  return result;
+}
+
+//------------------------------------------------------------------------------
+//--------------------------------------------------- Engine::createDictionary()
+//------------------------------------------------------------------------------
+anna::diameter::stack::Dictionary *  anna::diameter::stack::Engine::createDictionary(int stackId, const std::string & xmlPathFile) throw(anna::RuntimeException) {
+  Dictionary * result = const_cast<Dictionary *>(getDictionary(stackId));
+
+  if(result)  // if exists, launch exception
+    throw anna::RuntimeException("Such provided stack id has already been created. Removes it before call this method", ANNA_FILE_LOCATION);
+
+  // Register a new dictionary:
+  result = registerDictionary(stackId, new Dictionary());
+
   if(xmlPathFile != "") {
     try {
       result->load(xmlPathFile);