X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=source%2Fdiameter%2Fcodec%2FMessage.cpp;h=a686c71dcf33e327eaaa840ed7704395032f1f85;hb=415985b3f67878c2e3cee785a0b1cb36f4eff901;hp=b5d87f6e2fbc349fdfa29fff8f70d718ccc085c3;hpb=e80e62a5cf9aacad1a9551c68c432147ef98cd29;p=anna.git diff --git a/source/diameter/codec/Message.cpp b/source/diameter/codec/Message.cpp index b5d87f6..a686c71 100644 --- a/source/diameter/codec/Message.cpp +++ b/source/diameter/codec/Message.cpp @@ -84,7 +84,12 @@ Message::~Message() { //------------------------------------------------------------------------------ void Message::setEngine(Engine *engine) throw() { - if (a_engine && engine != a_engine) { + if (!engine) { + LOGWARNING(anna::Logger::warning("Ignored: you must assign a valid codec engine. If you want to set NULL engine, clear the message", ANNA_FILE_LOCATION)); + return; + } + + 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; } @@ -124,7 +129,7 @@ void Message::initialize() throw() { //------------------------------------------------------------------------------ //------------------------------------------------------------- Message::clear() //------------------------------------------------------------------------------ -void Message::clear() throw(anna::RuntimeException) { +void Message::clear(bool resetEngine) throw(anna::RuntimeException) { for(avp_iterator it = avp_begin(); it != avp_end(); it++) { /*avp(it)->clear(); */getEngine()->releaseAvp(Avp::avp(it)); } a_avps.clear(); @@ -133,6 +138,7 @@ void Message::clear() throw(anna::RuntimeException) { a_finds.clear(); // Initialize: initialize(); + if (resetEngine) a_engine = NULL; } @@ -144,7 +150,9 @@ bool Message::flagsOK(int &rc) const throw() { const stack::Command *stackCommand = getStackCommand(); if(!stackCommand) { - anna::Logger::error("Impossible to decide if flags are correct because stack command is not identified. Assume flags ok", ANNA_FILE_LOCATION); + std::string msg = "Impossible to decide if flags are correct because stack command is not identified. Assume flags ok for Message "; + msg += anna::diameter::functions::commandIdAsPairString(a_id); + anna::Logger::error(msg, ANNA_FILE_LOCATION); //rc = helpers::base::AVPVALUES__Result_Code::?????; return true; }; @@ -159,12 +167,16 @@ bool Message::flagsOK(int &rc) const throw() { if(stackCommand->isRequest() != isRequest()) ok = false; // en teoria es imposible salir por aqui: blindado en la dtd if(isRequest() && errorBit()) { - anna::Logger::error("E(rror) bit is not allowed at diameter requests", ANNA_FILE_LOCATION); + std::string msg = "E(rror) bit is not allowed at diameter requests as "; + msg += stackCommand->getName(); + anna::Logger::error(msg, ANNA_FILE_LOCATION); ok = false; } if(isAnswer() && potentiallyReTransmittedMessageBit()) { - anna::Logger::error("T(Potentially re-transmitted message) bit is not allowed at diameter answers", ANNA_FILE_LOCATION); + std::string msg = "T(Potentially re-transmitted message) bit is not allowed at diameter answers as "; + msg += stackCommand->getName(); + anna::Logger::error(msg, ANNA_FILE_LOCATION); ok = false; } @@ -179,7 +191,9 @@ bool Message::flagsOK(int &rc) const throw() { // is set to one (1) or the bits in the Diameter header are set // incorrectly. if((a_flags & 0x0f) != 0x00) { - anna::Logger::error("Any (or more than one) of the reserved message flags bit has been activated. Reserved bits must be null", ANNA_FILE_LOCATION); + std::string msg = "Any (or more than one) of the reserved message flags bit has been activated. Reserved bits must be null. Message is "; + msg += stackCommand->getName(); + anna::Logger::error(msg, ANNA_FILE_LOCATION); rc = helpers::base::AVPVALUES__Result_Code::DIAMETER_INVALID_BIT_IN_HEADER; return false; } @@ -191,9 +205,7 @@ bool Message::flagsOK(int &rc) const throw() { //------------------------------------------------------------------------------ //------------------------------------------------------------- Message::setId() //------------------------------------------------------------------------------ -void Message::setId(CommandId id, bool _clear) throw(anna::RuntimeException) { - // Clear class content: - if(_clear) clear(); +void Message::setId(CommandId id) throw(anna::RuntimeException) { // Id assignment: a_id = id; @@ -229,6 +241,7 @@ void Message::setApplicationId(U32 aid) throw(anna::RuntimeException) { // 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.size() == 0) return; if (em.selectFromApplicationId()) { Engine *monostackEngine = em.getMonoStackCodecEngine(); if (monostackEngine) { a_engine = monostackEngine; return; } @@ -305,7 +318,7 @@ void Message::decode(const anna::DataBlock &db, Message *ptrAnswer) throw(anna:: trace += db.asString(); anna::Logger::debug(trace, ANNA_FILE_LOCATION); ); - clear(); + clear(false /* respect engine */); // EXCEPTION MANAGEMENT IN THIS METHOD // =================================== // DECODE PHASE @@ -544,6 +557,8 @@ void Message::setStandardToAnswer(const Message &request, const std::string &ori // Session-Id if exists: const Avp *reqSessionId = request.getAvp(helpers::base::AVPID__Session_Id, 1, anna::Exception::Mode::Ignore); + LOGDEBUG(anna::Logger::debug("Check answer message AVPs Session-Id, Origin-Host and Origin-Realm => replace them if missing, with request session-id & node configuration:", ANNA_FILE_LOCATION)); + if(reqSessionId) if(!getAvp(helpers::base::AVPID__Session_Id, 1, anna::Exception::Mode::Ignore)) addAvp(helpers::base::AVPID__Session_Id)->getUTF8String()->setValue(reqSessionId->getUTF8String()->getValue()); @@ -746,20 +761,30 @@ const anna::DataBlock & Message::code() throw(anna::RuntimeException) { } //------------------------------------------------------------------------------ -//----------------------------------------------------------- Message::loadXML() +//------------------------------------------------------- Message::loadXMLFile() //------------------------------------------------------------------------------ -void Message::loadXML(const std::string &xmlPathFile) throw(anna::RuntimeException) { +void Message::loadXMLFile(const std::string &xmlPathFile) throw(anna::RuntimeException) { anna::xml::DocumentFile xmlDocument; anna::diameter::codec::functions::messageXmlDocumentFromXmlFile(xmlDocument, xmlPathFile); fromXML(xmlDocument.getRootNode()); } +//------------------------------------------------------------------------------ +//----------------------------------------------------- Message::loadXMLString() +//------------------------------------------------------------------------------ +void Message::loadXMLString(const std::string &xmlString) throw(anna::RuntimeException) { + + anna::xml::DocumentMemory xmlDocument; + anna::diameter::codec::functions::messageXmlDocumentFromXmlString(xmlDocument, xmlString); + fromXML(xmlDocument.getRootNode()); +} + //------------------------------------------------------------------------------ //----------------------------------------------------------- Message::fromXML() //------------------------------------------------------------------------------ void Message::fromXML(const anna::xml::Node* messageNode) throw(anna::RuntimeException) { - // + // const anna::xml::Attribute *version, *name, *code, *flags, *pbit, *ebit, *tbit, *appid, *hbh, *ete; version = messageNode->getAttribute("version", false /* no exception */); name = messageNode->getAttribute("name", false /* no exception */); @@ -770,12 +795,12 @@ void Message::fromXML(const anna::xml::Node* messageNode) throw(anna::RuntimeExc tbit = messageNode->getAttribute("t-bit", false /* no exception */); appid = messageNode->getAttribute("application-id"); // required hbh = messageNode->getAttribute("hop-by-hop-id", false /* no exception */); - ete = messageNode->getAttribute("end-by-end-id", false /* no exception */); + ete = messageNode->getAttribute("end-to-end-id", false /* no exception */); int i_aux; unsigned int u_aux; // Clear the message - clear(); + clear(false /* respect engine */); if(version) { i_aux = version->getIntegerValue(); @@ -822,7 +847,8 @@ void Message::fromXML(const anna::xml::Node* messageNode) throw(anna::RuntimeExc throw anna::RuntimeException(msg, ANNA_FILE_LOCATION); } - setId(stackCommand->getId(), false /* don't clear */); + setId(stackCommand->getId()); + // 'P', 'E' and 'T' flags: bool activateP = pbit ? (pbit->getValue() == "yes") : false; bool activateE = ebit ? (ebit->getValue() == "yes") : false; @@ -936,7 +962,7 @@ void Message::fromXML(const anna::xml::Node* messageNode) throw(anna::RuntimeExc //------------------------------------------------------------- Message::asXML() //------------------------------------------------------------------------------ anna::xml::Node* Message::asXML(anna::xml::Node* parent) const throw() { - // + // anna::xml::Node* result = parent->createChild("message"); // Dictionary stack command: const stack::Command *stackCommand = getStackCommand(); @@ -958,7 +984,7 @@ anna::xml::Node* Message::asXML(anna::xml::Node* parent) const throw() { result->createAttribute("application-id", anna::functions::asString(a_applicationId)); result->createAttribute("hop-by-hop-id", anna::functions::asString(a_hopByHop)); - result->createAttribute("end-by-end-id", anna::functions::asString(a_endToEnd)); + result->createAttribute("end-to-end-id", anna::functions::asString(a_endToEnd)); // Avps: for(const_avp_iterator it = avp_begin(); it != avp_end(); it++) { @@ -972,9 +998,16 @@ anna::xml::Node* Message::asXML(anna::xml::Node* parent) const throw() { //------------------------------------------------------------------------------ //------------------------------------------------------- Message::asXMLString() //------------------------------------------------------------------------------ -std::string Message::asXMLString() const throw() { +std::string Message::asXMLString(bool normalize) const throw() { anna::xml::Node root("root"); - return anna::xml::Compiler().apply(asXML(&root)); + + anna::xml::Compiler::Mode::_v mode = normalize ? anna::xml::Compiler::Mode::Sort : anna::xml::Compiler::Mode::Visual; + std::string result = anna::xml::Compiler().apply(asXML(&root), mode); + + if (normalize) + result.erase(std::remove(result.begin(), result.end(), '\n'), result.end()); + + return result; } @@ -983,5 +1016,6 @@ std::string Message::asXMLString() const throw() { //------------------------------------------------------------------------------ bool Message::isLike(const std::string &pattern) const throw() { anna::RegularExpression re(pattern); - return re.isLike(asXMLString()); + return re.isLike(asXMLString(true /* normalize by mean sorting attribute names and removing new lines */)); } +