X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=source%2Fdiameter%2Fcodec%2FMessage.cpp;h=31b7d14a6f2f67127d42ca327f9c5a8b2d372aec;hb=8b8309d46e9ccc968d3a315e86e70c5a806706d0;hp=6f906f85fe6750a00cd38070efba59475c093a51;hpb=08bdffbddf4bc0938eadec51af88de18734beda3;p=anna.git diff --git a/source/diameter/codec/Message.cpp b/source/diameter/codec/Message.cpp index 6f906f8..31b7d14 100644 --- a/source/diameter/codec/Message.cpp +++ b/source/diameter/codec/Message.cpp @@ -1,37 +1,9 @@ -// ANNA - Anna is Not Nothingness Anymore -// -// (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo -// -// http://redmine.teslayout.com/projects/anna-suite -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Authors: eduardo.ramos.testillano@gmail.com -// cisco.tierra@gmail.com +// ANNA - Anna is Not Nothingness Anymore // +// // +// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo // +// // +// See project site at http://redmine.teslayout.com/projects/anna-suite // +// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE // // Local @@ -44,6 +16,7 @@ #include // REQUIRED_WORDS #include #include +#include #include #include #include @@ -84,7 +57,7 @@ const U8 Message::TBitMask(0x10); //------------------------------------------------------------------------------ //----------------------------------------------------------- Message::Message() //------------------------------------------------------------------------------ -Message::Message() : a_forCode(true) { +Message::Message(Engine *engine) : a_engine(engine), a_forCode(true) { initialize(); } @@ -92,7 +65,7 @@ Message::Message() : a_forCode(true) { //------------------------------------------------------------------------------ //----------------------------------------------------------- Message::Message() //------------------------------------------------------------------------------ -Message::Message(CommandId id) : a_forCode(true) { +Message::Message(CommandId id, Engine *engine) : a_engine(engine), a_forCode(true) { initialize(); setId(id); } @@ -106,11 +79,34 @@ Message::~Message() { } +//------------------------------------------------------------------------------ +//--------------------------------------------------------- Message::setEngine() +//------------------------------------------------------------------------------ +void Message::setEngine(Engine *engine) throw() { + + 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; + } + + a_engine = engine; +} + + //------------------------------------------------------------------------------ //--------------------------------------------------------- Message::getEngine() //------------------------------------------------------------------------------ Engine * Message::getEngine() const throw(anna::RuntimeException) { - return a_engine ? a_engine : (a_engine = anna::functions::component (ANNA_FILE_LOCATION)); + if(!a_engine) + throw anna::RuntimeException("Invalid codec engine reference (NULL). Use setEngine() to set the corresponding codec engine", ANNA_FILE_LOCATION); + + return a_engine; + } @@ -118,7 +114,6 @@ Engine * Message::getEngine() const throw(anna::RuntimeException) { //-------------------------------------------------------- Message::initialize() //------------------------------------------------------------------------------ void Message::initialize() throw() { - a_engine = NULL; a_version = 1; a_id = CommandId(0, false); a_flags = 0x00; @@ -134,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(); @@ -143,6 +138,7 @@ void Message::clear() throw(anna::RuntimeException) { a_finds.clear(); // Initialize: initialize(); + if (resetEngine) a_engine = NULL; } @@ -154,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; }; @@ -169,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; } @@ -189,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; } @@ -201,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; @@ -227,6 +229,27 @@ void Message::setId(const char *name) throw(anna::RuntimeException) { } +//------------------------------------------------------------------------------ +//-------------------------------------------------- Message::setApplicationId() +//------------------------------------------------------------------------------ +void Message::setApplicationId(U32 aid) throw(anna::RuntimeException) { + a_applicationId = aid; + + // Automatic engine configuration: + if (a_engine) return; + + // 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; } + a_engine = em.getCodecEngine(aid); + } +} + + //------------------------------------------------------------------------------ //------------------------------------------------------------ Message::addAvp() //------------------------------------------------------------------------------ @@ -235,6 +258,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() //------------------------------------------------------------------------------ @@ -279,12 +313,12 @@ 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(); + clear(false /* respect engine */); // EXCEPTION MANAGEMENT IN THIS METHOD // =================================== // DECODE PHASE @@ -294,7 +328,7 @@ void Message::decode(const anna::DataBlock &db, Message *ptrAnswer) throw(anna:: // // VALIDATION PHASE // Launch exception on first validation error (validateAll == false), or log warning reporting all validation errors when - // complete validation is desired (validateAll == true, engine default) launching a final exception like "decoded an invalid message". + // complete validation is desired (validateAll == true, engine default) launching a final exception like "the decoded message is invalid". // OAM OamModule &oamModule = OamModule::instantiate(); @@ -331,9 +365,9 @@ void Message::decode(const anna::DataBlock &db, Message *ptrAnswer) throw(anna:: U24 code = DECODE3BYTES_INDX_VALUETYPE(buffer, 5, U24); - setId(CommandId(code, requestBit() /* based on a_flags */)); + a_id = CommandId(code, requestBit() /* based on a_flags */); - a_applicationId = DECODE4BYTES_INDX_VALUETYPE(buffer, 8, U32); + setApplicationId(DECODE4BYTES_INDX_VALUETYPE(buffer, 8, U32)); // centralize set, because it could be used for stack selection. a_hopByHop = DECODE4BYTES_INDX_VALUETYPE(buffer, 12, U32); @@ -377,14 +411,14 @@ void Message::decode(const anna::DataBlock &db, Message *ptrAnswer) throw(anna:: while(avpPos < dataBytes) { try { - avp = getEngine()->allocateAvp(); + avp = getEngine()->createAvp(NULL); db_aux.assign(startData + avpPos, dataBytes - avpPos /* is valid to pass total length (indeed i don't know the real avp length) because it will be limited and this has deep copy disabled (no memory is reserved) */); avp -> decode(db_aux, parent, answer); } 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; } @@ -400,16 +434,16 @@ 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(); if((vmode == Engine::ValidationMode::AfterDecoding) || (vmode == Engine::ValidationMode::Always)) if(!valid(answer)) - throw anna::RuntimeException("Decoded an invalid message. See previous report on warning-level traces", ANNA_FILE_LOCATION); + throw anna::RuntimeException("The decoded message is invalid. See previous report on warning-level traces", ANNA_FILE_LOCATION); } @@ -464,29 +498,31 @@ 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. // Probably the RFC wants to give freedom to the application layer, but it is recommended to // have only one child (wrong avp) inside a unique message Failed-AVP to ease the Result-Code - // correspondence. Anyway, this behaviour could be easily opened commenting condition block (*). + // correspondence. Anyway, this behaviour could be easily opened by mean 'setSingleFailedAVP(false)' Avp *theFailedAvp = getAvp(helpers::base::AVPID__Failed_AVP, 1, anna::Exception::Mode::Ignore); if (theFailedAvp) { - LOGDEBUG(anna::Logger::debug("Failed-AVP has already been added. RFC 6733 Section 7.5 recommends to store only the first error found", ANNA_FILE_LOCATION)); - return; + if (getEngine()->getSingleFailedAVP()) { + LOGDEBUG(anna::Logger::debug("Failed-AVP has already been added. RFC 6733 Section 7.5 recommends to store only the first error found", ANNA_FILE_LOCATION)); + return; + } } // Section 7.5 RFC 6733: A Diameter message SHOULD contain one Failed-AVP AVP @@ -494,17 +530,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); } @@ -513,7 +549,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: @@ -521,8 +557,10 @@ 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)) + 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 @@ -542,9 +580,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); ); } @@ -645,7 +683,7 @@ const anna::DataBlock & Message::code() throw(anna::RuntimeException) { // Pre-Validation Engine::ValidationMode::_v vmode = getEngine()->getValidationMode(); - if((vmode == Engine::ValidationMode::BeforeCoding) || (vmode == Engine::ValidationMode::Always)) { + if((vmode == Engine::ValidationMode::BeforeEncoding) || (vmode == Engine::ValidationMode::Always)) { if(!valid()) throw anna::RuntimeException("Try to encode an invalid message. See previous report on warning-level traces", ANNA_FILE_LOCATION); } @@ -653,13 +691,13 @@ const anna::DataBlock & Message::code() throw(anna::RuntimeException) { // Pre-Fixing Engine::FixMode::_v fmode = getEngine()->getFixMode(); - if((fmode == Engine::FixMode::BeforeCoding) || (fmode == Engine::FixMode::Always)) fix(); + if((fmode == Engine::FixMode::BeforeEncoding) || (fmode == Engine::FixMode::Always)) fix(); // 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(); @@ -713,35 +751,40 @@ 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::loadXMLFile() //------------------------------------------------------------------------------ -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::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 */); @@ -752,10 +795,13 @@ 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(false /* respect engine */); + if(version) { i_aux = version->getIntegerValue(); @@ -768,6 +814,10 @@ void Message::fromXML(const anna::xml::Node* messageNode) throw(anna::RuntimeExc a_version = i_aux; } + // Application-id + // This is called before any operation which needs to know about the stack elements (this could set the dictionary) + setApplicationId(appid->getIntegerValue()); + // Dictionary const stack::Dictionary * dictionary = getEngine()->getDictionary(); const stack::Command *stackCommand = NULL; @@ -798,6 +848,7 @@ void Message::fromXML(const anna::xml::Node* messageNode) throw(anna::RuntimeExc } setId(stackCommand->getId()); + // 'P', 'E' and 'T' flags: bool activateP = pbit ? (pbit->getValue() == "yes") : false; bool activateE = ebit ? (ebit->getValue() == "yes") : false; @@ -848,24 +899,11 @@ void Message::fromXML(const anna::xml::Node* messageNode) throw(anna::RuntimeExc a_flags = i_aux; int flagsBCK = a_flags; // Final assignments - setId(CommandId(u_code, requestBit() /* based on a_flags */)); + a_id = CommandId(u_code, requestBit() /* based on a_flags */); // Flags could have been updated regarding dictionary, but during parsing we must respect xml file: a_flags = flagsBCK; } - // Application-id - u_aux = appid->getIntegerValue(); - - /* - if(u_aux < 0) { - std::string msg = "Error processing command getValue(); - msg += "': negative values are not allowed"; - throw anna::RuntimeException(msg, ANNA_FILE_LOCATION); - } - */ - - setApplicationId(u_aux); - // Hob-by-hop-id if(hbh) { u_aux = hbh->getIntegerValue(); @@ -876,7 +914,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); @@ -891,7 +929,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); @@ -908,7 +946,7 @@ void Message::fromXML(const anna::xml::Node* messageNode) throw(anna::RuntimeExc } try { - avp = getEngine()->allocateAvp(); + avp = getEngine()->createAvp(NULL); avp -> fromXML(*it); } catch(anna::RuntimeException &ex) { getEngine()->releaseAvp(avp); @@ -920,36 +958,11 @@ 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() //------------------------------------------------------------------------------ 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(); @@ -971,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++) {