X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=include%2Fanna%2Fdiameter%2Fcodec%2FEngineImpl.hpp;h=0305727a4ed3a0dc3503fb87625297677a821ee1;hb=220eecc7d53ddb85f72d94d5053738519fd8d27e;hp=753d15e3a791e0b2298d0faaed47ebcf59e7168c;hpb=129500a50678c43ff28fb0054d6197899b8c0b2c;p=anna.git diff --git a/include/anna/diameter/codec/EngineImpl.hpp b/include/anna/diameter/codec/EngineImpl.hpp index 753d15e..0305727 100644 --- a/include/anna/diameter/codec/EngineImpl.hpp +++ b/include/anna/diameter/codec/EngineImpl.hpp @@ -36,8 +36,6 @@ class Dictionary; namespace codec { -extern const char *MessageDTD; - class Message; class Avp; @@ -50,23 +48,15 @@ class Avp; * A child implementation could manage complex Avp classes with new data-part formats. Grouped ones could * allocate new complex Avps through such engine which knows how to allocate this special Avp's (also for * complex Message classes with application-specific setters and getters as credit-control related avps, - * or some another context items). For example helpers for TME scope stands for a new engine component - * called tme::Engine, allocating tme::Avp and tme::Message classes which support three new Avp formats: + * or some another context items). For example tme::Avp and tme::Message classes support three new Avp formats: * ISDNNumber, ISDNAddress and Unsigned16. Anyway, main Message/Avp and Engine classes stand for all contexts * included in anna::diameter, that is to say, whole contexts (at the time only TME) will be included in future * when needed apart from the independent namespace version. Thank to this, single threaded applications could * use whole engine in a easy way. * - * Usually an engine component is associated to a single diameter stack, although single threaded processes could - * use a common engine alternating different stack dictionaries by mean #setDictionary, depending on which kind of - * messages are being analyzed. Although the application must ensure that a single dictionary is activated during - * the same context operations an Avp could be considered as Unknown if was created with another, and we could - * have validation problems (i.e. if mandatory Avp bit is enabled). In general, managing Unknown data-part format - * don't have to be a problem because it is interpreted as OctetString format. Depending on what setters/getters - * we use, it could reach a RuntimeException at our application. - * - * At multithread processes we must use one heir engine per stack and never switching stacks within same component. - * We will use each engine for each context. + * An engine component is associated to a single diameter stack. It is application responsability to use message + * container initialized with the correct codec engine depending on the context. There are helpers to do this at + * anna::diameter::codec::functions::getApplicationId (from xml document or hexadecimal buffer). * * It is recommended to use Message class to create Avps (adding them through pair identification * prototype), but we could create Avps separately (other program section, i.e) and join them after: @@ -75,7 +65,7 @@ class Avp; * 1. Recommended way: * * // Message creation: - * Message * msg = new Message(helpers::base::COMMANDID__Re_Auth_Answer); + * Message * msg = new Message(helpers::base::COMMANDID__Re_Auth_Answer, codecEngine); * // Adding + creation: * Avp * avp_sid = msg->addAvp(helpers::base::AVPID__Session_Id); * Avp * avp_oh = msg->addAvp(helpers::base::AVPID__Origin_Host); @@ -88,12 +78,12 @@ class Avp; * 2. External Avp creation: * * // Message creation: - * Message * msg = new Message(helpers::base::COMMANDID__Re_Auth_Answer); + * Message * msg = new Message(helpers::base::COMMANDID__Re_Auth_Answer, codecEngine); * // Creation: - * Avp * avp_sid = new Avp(helpers::base::AVPID__Session_Id); - * Avp * avp_oh = new Avp(helpers::base::AVPID__Origin_Host); - * Avp * avp_or = new Avp(helpers::base::AVPID__Origin_Realm); - * Avp * avp_rc = new Avp(helpers::base::AVPID__Result_Code); + * Avp * avp_sid = new Avp(helpers::base::AVPID__Session_Id, codecEngine); + * Avp * avp_oh = new Avp(helpers::base::AVPID__Origin_Host, codecEngine); + * Avp * avp_or = new Avp(helpers::base::AVPID__Origin_Realm, codecEngine); + * Avp * avp_rc = new Avp(helpers::base::AVPID__Result_Code, codecEngine); * // Adding: * msg->addAvp(avp_sid); * msg->addAvp(avp_oh); @@ -175,13 +165,11 @@ public: private: - anna::xml::DTDMemory a_dtd; ValidationDepth::_v a_validationDepth; ValidationMode::_v a_validationMode; + bool a_singleFailedAVP; bool a_ignoreFlags; FixMode::_v a_fixMode; - bool a_selectStackWithApplicationId; // default behaviour: let the user switch the stack (false for this boolean) - // Auxiliary const stack::Dictionary * a_dictionary; @@ -195,8 +183,14 @@ public: /** Constructor @param className Logical name for the class. + @param dictionary Diameter dictionary. At single threaded processes, the same codec engine could be used with + different diameter dictionaries (multi-stack applications). In that case the process must switch the stack for + the whole decoding or enconding operation over a Message depending on the context (normally the message header + Application-Id is used as stack identifier). But the smart way implies inherit from this engine creating a + component for each diameter stack managed in the application. Inheritance is mandatory in multi-threaded processes: + one engine, a unique stack. */ - EngineImpl(const char* className); + EngineImpl(const char* className, const stack::Dictionary * dictionary); /** * Destructor @@ -204,54 +198,6 @@ public: virtual ~EngineImpl() {;} - // setters - /** - Sets diameter dictionary loaded at stack engine. It's recommended to configure a valid dictionary - (if not, or NULL provided at #setDictionary, all avps will be managed as 'Unknown' format and all - items will need to be manually updated, i.e. message and avp flags). - - @param dictionary Diameter dictionary. At single threaded processes, the same codec engine could be used with - different diameter dictionaries (multi-stack applications). In that case the process must switch the stack for - the whole decoding or enconding operation over a Message depending on the context (normally the message header - Application-Id is used as stack identifier). But the smart way implies inherit from this engine creating a - component for each diameter stack managed in the application. Inheritance is mandatory in multi-threaded processes: - one engine, a unique stack. - */ - void setDictionary(const stack::Dictionary * dictionary) throw() { a_dictionary = dictionary; } - - /** - * Sets diameter dictionary loaded at stack engine with the provided identifier. - * - * @param stackId Stack identifier. When missing, NULL will be returned - * @return Returns configured dictionary (NULL if stack id was not found) - */ - const stack::Dictionary *setDictionary(unsigned int stackId) throw(); - - - /** - * By default, the user will select the appropiate stack id depending on the context (see #setDictionary), but - * some applications could consider interesting automatic stack selection based on managed messages (incoming - * decoded ones, or built messages to be encoded). By default, on engine construction, no changes are done. - * Multithreaded processes should have a unique codec engine for each managed stack (then you don't have to - * worry about), but mono processes with multistack implementation over the same-unique engine, should activate - * this to have the commonly recommended way to choose the stack: using the Application-Id value. - * - * @warning do not activate in case of multithreaded applications. - * @param enable Activates/deactivates the stack selection from the Application-Id value within the message header. - */ - void selectStackWithApplicationId (bool enable) throw() { a_selectStackWithApplicationId = enable; } - - // getters - - /** - Gets the currently configured behaviour regarding stack selection for multistack codec engines in mono thread - applications. - - @return True if selection is done with the Application-Id. False if no selection is performed (user responsibility). - */ - bool hasSelectStackWithApplicationId (void) throw() { return a_selectStackWithApplicationId; } - - /** Gets currently configured dictionary. NULL if not configured (manual encode/decode operations). @@ -321,12 +267,20 @@ public: */ FixMode::_v getFixMode() const throw() { return a_fixMode; } - + /** + * Sets single FailedAVP. True by default. If false, and more than one wrong avp are found during message + * decoding and or validation, a new Failed-AVP will be added to the dynamic answer provided. The standard + * talks about only one but it is open to do this. + * + * \param single Single Failed-AVP boolean. + */ + void setSingleFailedAVP(bool single = true) throw() { a_singleFailedAVP = single; } /** - DTD document for xml message parsing - */ - const anna::xml::DTDMemory & getDTD() const throw() { return a_dtd; } + * Returns single Failed-AVP boolean. + * \return Failed-AVP could be one (true) or more (false) in answer message. + */ + bool getSingleFailedAVP() const throw() { return a_singleFailedAVP; } /** * Creates a new diameter avp assigning its identifier, using engine resources to allocate memory (recommended