X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=source%2Fdiameter%2Fcodec%2FMessage.cpp;fp=source%2Fdiameter%2Fcodec%2FMessage.cpp;h=b5d87f6e2fbc349fdfa29fff8f70d718ccc085c3;hb=e80e62a5cf9aacad1a9551c68c432147ef98cd29;hp=35db12908c35dc8e49a023095ac1c9b14be9f9c1;hpb=c7742e2134826a05ee9c6bf89eebaa726dae0d1b;p=anna.git diff --git a/source/diameter/codec/Message.cpp b/source/diameter/codec/Message.cpp index 35db129..b5d87f6 100644 --- a/source/diameter/codec/Message.cpp +++ b/source/diameter/codec/Message.cpp @@ -16,6 +16,7 @@ #include // REQUIRED_WORDS #include #include +#include #include #include #include @@ -78,12 +79,26 @@ Message::~Message() { } +//------------------------------------------------------------------------------ +//--------------------------------------------------------- Message::setEngine() +//------------------------------------------------------------------------------ +void Message::setEngine(Engine *engine) throw() { + + if (a_engine && engine != a_engine) { + LOGWARNING(anna::Logger::warning("Ignored: it is not a good practice to change the codec engine once assigned. Clear the message first to set the engine again.", ANNA_FILE_LOCATION)); + return; + } + + a_engine = engine; +} + + //------------------------------------------------------------------------------ //--------------------------------------------------------- Message::getEngine() //------------------------------------------------------------------------------ Engine * Message::getEngine() const throw(anna::RuntimeException) { if(!a_engine) - throw anna::RuntimeException("Invalid codec engine reference (NULL)", ANNA_FILE_LOCATION); + throw anna::RuntimeException("Invalid codec engine reference (NULL). Use setEngine() to set the corresponding codec engine", ANNA_FILE_LOCATION); return a_engine; @@ -208,11 +223,17 @@ void Message::setId(const char *name) throw(anna::RuntimeException) { void Message::setApplicationId(U32 aid) throw(anna::RuntimeException) { a_applicationId = aid; - // Default behaviour: - if (!getEngine()->hasSelectStackWithApplicationId()) return; + // Automatic engine configuration: + if (a_engine) return; - // Adapts for Application-ID stack identifier: - getEngine()->setDictionary(aid); + // Codec engine manager (a multithreaded application, normally does not achieve this point, because + // messages are prepared for each interface with the corresponding codec engine) + anna::diameter::codec::EngineManager &em = anna::diameter::codec::EngineManager::instantiate(); + if (em.selectFromApplicationId()) { + Engine *monostackEngine = em.getMonoStackCodecEngine(); + if (monostackEngine) { a_engine = monostackEngine; return; } + a_engine = em.getCodecEngine(aid); + } } @@ -224,6 +245,17 @@ Avp * Message::addAvp(const char *name) throw(anna::RuntimeException) { } +//------------------------------------------------------------------------------ +//------------------------------------------------------------ Message::addAvp() +//------------------------------------------------------------------------------ +Avp * Message::addAvp(Avp * avp) throw() { + if(!avp) return NULL; + if (avp->getEngine() != getEngine()) return NULL; + addChild(avp); + return avp; +} + + //------------------------------------------------------------------------------ //--------------------------------------------------------- Message::removeAvp() //------------------------------------------------------------------------------ @@ -268,10 +300,10 @@ U24 Message::getLength() const throw() { void Message::decode(const anna::DataBlock &db, Message *ptrAnswer) throw(anna::RuntimeException) { // Trace LOGDEBUG( - anna::xml::Node root("Message::decode"); - std::string trace = "DataBlock to decode:\n"; - trace += db.asString(); - anna::Logger::debug(trace, ANNA_FILE_LOCATION); + anna::xml::Node root("Message::decode"); + std::string trace = "DataBlock to decode:\n"; + trace += db.asString(); + anna::Logger::debug(trace, ANNA_FILE_LOCATION); ); clear(); // EXCEPTION MANAGEMENT IN THIS METHOD @@ -372,8 +404,8 @@ void Message::decode(const anna::DataBlock &db, Message *ptrAnswer) throw(anna:: } catch(anna::RuntimeException &ex) { getEngine()->releaseAvp(avp); LOGWARNING( - anna::Logger::warning(ex.getText(), ANNA_FILE_LOCATION); - anna::Logger::warning("Although a decoding error was found, validation could be checked because message could be enough for the application", ANNA_FILE_LOCATION); + anna::Logger::warning(ex.getText(), ANNA_FILE_LOCATION); + anna::Logger::warning("Although a decoding error was found, validation could be checked because message could be enough for the application", ANNA_FILE_LOCATION); ); break; } @@ -389,9 +421,9 @@ void Message::decode(const anna::DataBlock &db, Message *ptrAnswer) throw(anna:: // Trace LOGDEBUG( - std::string trace = "Message decoded:\n"; - trace += asXMLString(); - anna::Logger::debug(trace, ANNA_FILE_LOCATION); + std::string trace = "Message decoded:\n"; + trace += asXMLString(); + anna::Logger::debug(trace, ANNA_FILE_LOCATION); ); // Post-Validation Engine::ValidationMode::_v vmode = getEngine()->getValidationMode(); @@ -453,19 +485,19 @@ void Message::setFailedAvp(const parent_t &parent, AvpId wrong, const char *wron if(isRequest()) return; -// RFC 6733: -// -// 7.5. Failed-AVP AVP -// -// The Failed-AVP AVP (AVP Code 279) is of type Grouped and provides -// debugging information in cases where a request is rejected or not -// fully processed due to erroneous information in a specific AVP. The -// value of the Result-Code AVP will provide information on the reason -// for the Failed-AVP AVP. A Diameter answer message SHOULD contain an -// instance of the Failed-AVP AVP that corresponds to the error -// indicated by the Result-Code AVP. For practical purposes, this -// Failed-AVP would typically refer to the first AVP processing error -// that a Diameter node encounters. + // RFC 6733: + // + // 7.5. Failed-AVP AVP + // + // The Failed-AVP AVP (AVP Code 279) is of type Grouped and provides + // debugging information in cases where a request is rejected or not + // fully processed due to erroneous information in a specific AVP. The + // value of the Result-Code AVP will provide information on the reason + // for the Failed-AVP AVP. A Diameter answer message SHOULD contain an + // instance of the Failed-AVP AVP that corresponds to the error + // indicated by the Result-Code AVP. For practical purposes, this + // Failed-AVP would typically refer to the first AVP processing error + // that a Diameter node encounters. // Although the Failed-AVP definition has cardinality 1* and Failed-AVP itself is defined in // most of the command codes as *[Failed-AVP], i think this is not a deliberate ambiguity. @@ -485,17 +517,17 @@ void Message::setFailedAvp(const parent_t &parent, AvpId wrong, const char *wron Avp *leaf = theFailedAvp; LOGDEBUG( - std::string msg = "Adding to Failed-AVP, the wrong avp "; - msg += wrongName ? wrongName : (anna::diameter::functions::avpIdAsPairString(wrong)); - msg += " found inside "; - msg += parent.asString(); + std::string msg = "Adding to Failed-AVP, the wrong avp "; + msg += wrongName ? wrongName : (anna::diameter::functions::avpIdAsPairString(wrong)); + msg += " found inside "; + msg += parent.asString(); - anna::Logger::debug(msg, ANNA_FILE_LOCATION); + anna::Logger::debug(msg, ANNA_FILE_LOCATION); ); std::vector::const_iterator it; for(it = parent.AvpsId.begin(); it != parent.AvpsId.end(); it++) - leaf = leaf->addAvp(*it); + leaf = leaf->addAvp(*it); leaf->addAvp(wrong); } @@ -504,7 +536,7 @@ void Message::setFailedAvp(const parent_t &parent, AvpId wrong, const char *wron //------------------------------------------------------------------------------ //----------------------------------------------- Message::setStandardToAnswer() //------------------------------------------------------------------------------ -void Message::setStandardToAnswer(const Message &request, const std::string &originHost, const std::string &originRealm, int resultCode) throw() { +void Message::setStandardToAnswer(const Message &request, const std::string &originHost, const std::string &originRealm, int resultCode) throw(anna::RuntimeException) { if(!request.getId().second) return; // Message header: @@ -513,7 +545,7 @@ void Message::setStandardToAnswer(const Message &request, const std::string &ori const Avp *reqSessionId = request.getAvp(helpers::base::AVPID__Session_Id, 1, anna::Exception::Mode::Ignore); if(reqSessionId) - if(!getAvp(helpers::base::AVPID__Session_Id, 1, anna::Exception::Mode::Ignore)) + if(!getAvp(helpers::base::AVPID__Session_Id, 1, anna::Exception::Mode::Ignore)) addAvp(helpers::base::AVPID__Session_Id)->getUTF8String()->setValue(reqSessionId->getUTF8String()->getValue()); // Origin-Host & Realm @@ -533,9 +565,9 @@ void Message::setStandardToAnswer(const Message &request, const std::string &ori // Fix: fix(); LOGDEBUG( - std::string msg = "Completed answer:\n"; - msg += asXMLString(); - anna::Logger::debug(msg, ANNA_FILE_LOCATION); + std::string msg = "Completed answer:\n"; + msg += asXMLString(); + anna::Logger::debug(msg, ANNA_FILE_LOCATION); ); } @@ -648,9 +680,9 @@ const anna::DataBlock & Message::code() throw(anna::RuntimeException) { // Trace LOGDEBUG( - std::string trace = "Message to code:\n"; - trace += asXMLString(); - anna::Logger::debug(trace, ANNA_FILE_LOCATION); + std::string trace = "Message to code:\n"; + trace += asXMLString(); + anna::Logger::debug(trace, ANNA_FILE_LOCATION); ); // Memory allocation U24 length = getLength(); @@ -704,29 +736,24 @@ const anna::DataBlock & Message::code() throw(anna::RuntimeException) { // Trace LOGDEBUG( - std::string trace = "DataBlock encoded:\n"; - trace += a_forCode.asString(); -// trace += "\nAs continuous hexadecimal string:\n"; -// trace += anna::functions::asHexString(a_forCode); - anna::Logger::debug(trace, ANNA_FILE_LOCATION); + std::string trace = "DataBlock encoded:\n"; + trace += a_forCode.asString(); + // trace += "\nAs continuous hexadecimal string:\n"; + // trace += anna::functions::asHexString(a_forCode); + anna::Logger::debug(trace, ANNA_FILE_LOCATION); ); return a_forCode; } - //------------------------------------------------------------------------------ -//----------------------------------------------------- Message::fromXMLString() +//----------------------------------------------------------- Message::loadXML() //------------------------------------------------------------------------------ -void Message::fromXMLString(const std::string &xmlString) throw(anna::RuntimeException) { - LOGDEBUG(anna::Logger::debug("Reading diameter message from xml string representation", ANNA_FILE_LOCATION)); - anna::xml::DocumentMemory xmlDocument; // has private copy constructor defined but not implemented to avoid inhenrit/copy (is very heavy) - const anna::xml::Node *rootNode; - xmlDocument.initialize(xmlString.c_str()); - rootNode = xmlDocument.parse(getEngine()->getDTD()); // Parsing: fail here if xml violates dtd - LOGDEBUG(anna::Logger::debug("Read OK from XML string representation", ANNA_FILE_LOCATION)); - fromXML(rootNode); -} +void Message::loadXML(const std::string &xmlPathFile) throw(anna::RuntimeException) { + anna::xml::DocumentFile xmlDocument; + anna::diameter::codec::functions::messageXmlDocumentFromXmlFile(xmlDocument, xmlPathFile); + fromXML(xmlDocument.getRootNode()); +} //------------------------------------------------------------------------------ //----------------------------------------------------------- Message::fromXML() @@ -861,7 +888,7 @@ void Message::fromXML(const anna::xml::Node* messageNode) throw(anna::RuntimeExc msg += "': negative values are not allowed"; throw anna::RuntimeException(msg, ANNA_FILE_LOCATION); } - */ + */ } else u_aux = 0; setHopByHop(u_aux); @@ -876,7 +903,7 @@ void Message::fromXML(const anna::xml::Node* messageNode) throw(anna::RuntimeExc msg += "': negative values are not allowed"; throw anna::RuntimeException(msg, ANNA_FILE_LOCATION); } - */ + */ } else u_aux = 0; setEndToEnd(u_aux); @@ -905,31 +932,6 @@ void Message::fromXML(const anna::xml::Node* messageNode) throw(anna::RuntimeExc } -//------------------------------------------------------------------------------ -//----------------------------------------------------------- Message::loadXML() -//------------------------------------------------------------------------------ -void Message::loadXML(const std::string & xmlPathFile) throw(anna::RuntimeException) { - LOGDEBUG( - std::string trace = "Loading diameter message from file '"; - trace += xmlPathFile; - trace += "'"; - anna::Logger::debug(trace, ANNA_FILE_LOCATION); - ); - anna::xml::DocumentFile xmlDocument; // has private copy constructor defined but not implemented to avoid inhenrit/copy (is very heavy) - const anna::xml::Node *rootNode; - xmlDocument.initialize(xmlPathFile.c_str()); // fail here is i/o error - rootNode = xmlDocument.parse(getEngine()->getDTD()); // Parsing: fail here if xml violates dtd - LOGDEBUG( - std::string trace = "Loaded XML file ("; - trace += xmlPathFile; - trace += "):\n"; - trace += anna::xml::Compiler().apply(rootNode); - anna::Logger::debug(trace, ANNA_FILE_LOCATION); - ); - fromXML(rootNode); -} - - //------------------------------------------------------------------------------ //------------------------------------------------------------- Message::asXML() //------------------------------------------------------------------------------