From 0c646b4aa99a84ef6976a51b6d4554aea11ded35 Mon Sep 17 00:00:00 2001 From: Eduardo Ramos Testillano Date: Mon, 6 Apr 2015 02:11:05 +0200 Subject: [PATCH] New features --- example/diameter/pcapDecoder/main.cpp | 5 +- example/diameter/stackManagement/main.cpp | 2 +- example/diameter/tme/main.cpp | 4 +- .../anna/core/util/MultiRangeExpression.hpp | 48 ++++++++++++++++++- include/anna/diameter/stack/Avp.hpp | 3 +- include/anna/diameter/stack/Dictionary.hpp | 4 +- include/anna/diameter/stack/Engine.hpp | 11 +++++ source/core/util/MultiRangeExpression.cpp | 43 +++++++++++++++++ source/diameter/stack/Engine.cpp | 27 +++++++++-- 9 files changed, 134 insertions(+), 13 deletions(-) diff --git a/example/diameter/pcapDecoder/main.cpp b/example/diameter/pcapDecoder/main.cpp index 8029b51..30d9cba 100644 --- a/example/diameter/pcapDecoder/main.cpp +++ b/example/diameter/pcapDecoder/main.cpp @@ -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 = diff --git a/example/diameter/stackManagement/main.cpp b/example/diameter/stackManagement/main.cpp index 96645b3..2526a7a 100644 --- a/example/diameter/stackManagement/main.cpp +++ b/example/diameter/stackManagement/main.cpp @@ -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 ,\n i.e. '%s avps.xml commands.xml'", exec.c_str(), exec.c_str()); _exit(msg); } diff --git a/example/diameter/tme/main.cpp b/example/diameter/tme/main.cpp index 08e5f9f..68e2295 100644 --- a/example/diameter/tme/main.cpp +++ b/example/diameter/tme/main.cpp @@ -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 += " "; + if (argc < 2) { + std::string msg = "Usage: "; msg += exec; msg += " "; msg += "\n xml directory: contains the xml files needed, which are:"; msg += "\n"; msg += "\n avps_ietf.xml"; diff --git a/include/anna/core/util/MultiRangeExpression.hpp b/include/anna/core/util/MultiRangeExpression.hpp index 665094a..ab3273c 100644 --- a/include/anna/core/util/MultiRangeExpression.hpp +++ b/include/anna/core/util/MultiRangeExpression.hpp @@ -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(); + } }; }; diff --git a/include/anna/diameter/stack/Avp.hpp b/include/anna/diameter/stack/Avp.hpp index 9a124e5..1c2de1d 100644 --- a/include/anna/diameter/stack/Avp.hpp +++ b/include/anna/diameter/stack/Avp.hpp @@ -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); diff --git a/include/anna/diameter/stack/Dictionary.hpp b/include/anna/diameter/stack/Dictionary.hpp index e5eece2..bd4cd4d 100644 --- a/include/anna/diameter/stack/Dictionary.hpp +++ b/include/anna/diameter/stack/Dictionary.hpp @@ -110,10 +110,12 @@ public: typedef std::map 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; diff --git a/include/anna/diameter/stack/Engine.hpp b/include/anna/diameter/stack/Engine.hpp index 165d779..ca3f758 100644 --- a/include/anna/diameter/stack/Engine.hpp +++ b/include/anna/diameter/stack/Engine.hpp @@ -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 diff --git a/source/core/util/MultiRangeExpression.cpp b/source/core/util/MultiRangeExpression.cpp index 75ca563..3c2307d 100644 --- a/source/core/util/MultiRangeExpression.cpp +++ b/source/core/util/MultiRangeExpression.cpp @@ -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(); +} + diff --git a/source/diameter/stack/Engine.cpp b/source/diameter/stack/Engine.cpp index 7a0f799..07daa79 100644 --- a/source/diameter/stack/Engine.cpp +++ b/source/diameter/stack/Engine.cpp @@ -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(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(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); -- 2.20.1