//-------------------------------------------------------------------
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
<< (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 =
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);
}
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";
~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();
+ }
};
};
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);
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;
*/
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
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();
+}
+
//------------------------------------------------------------------------------
-//--------------------------------------------------- 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);