Ensures normalization on waitfe/fc-xml operations
[anna.git] / include / anna / diameter / codec / Avp.hpp
index cd6c100..2454d4d 100644 (file)
@@ -1,37 +1,9 @@
-// ANNA - Anna is Not 'N' Anymore
-//
-// (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
-//
-// https://bitbucket.org/testillano/anna
-//
-// 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 Google Inc. 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 //
 
 
 #ifndef anna_diameter_codec_Avp_hpp
 
 
 #ifndef anna_diameter_codec_Avp_hpp
@@ -42,8 +14,8 @@
 #include <anna/config/defines.hpp>
 #include <anna/diameter/defines.hpp>
 #include <anna/diameter/codec/basetypes/basetypes.hpp>
 #include <anna/config/defines.hpp>
 #include <anna/diameter/defines.hpp>
 #include <anna/diameter/codec/basetypes/basetypes.hpp>
+#include <anna/diameter/codec/functions.hpp>
 #include <anna/diameter/stack/Avp.hpp>
 #include <anna/diameter/stack/Avp.hpp>
-#include <anna/diameter/helpers/tme/codectypes/codectypes.hpp>
 
 #include <anna/core/RuntimeException.hpp>
 
 
 #include <anna/core/RuntimeException.hpp>
 
@@ -70,17 +42,6 @@ namespace anna {
 namespace diameter {
 
 
 namespace diameter {
 
 
-namespace helpers {
-namespace tme {
-namespace codectypes {
-class Unsigned16;
-class ISDNNumber;
-class ISDNAddress;
-}
-}
-}
-
-
 namespace stack {
 class Dictionary;
 class Format;
 namespace stack {
 class Dictionary;
 class Format;
@@ -124,7 +85,6 @@ typedef std::map<find_key, Avp*>::iterator find_iterator;
 
 
 using namespace basetypes;
 
 
 using namespace basetypes;
-using namespace helpers::tme::codectypes;
 
 /**
 * Diameter avp generic container
 
 /**
 * Diameter avp generic container
@@ -201,14 +161,6 @@ class Avp {
   QoSFilterRule *a_QoSFilterRule;
   Unknown *a_Unknown;
 
   QoSFilterRule *a_QoSFilterRule;
   Unknown *a_Unknown;
 
-  // Derived formats ////////////////////////////////////////////
-  /* TME */
-  ISDNNumber *a_ISDNNumber;
-  ISDNAddress *a_ISDNAddress;
-  Unsigned16 *a_Unsigned16;
-
-
-
   // Grouped helpers
   find_container a_finds; // fast access for grouped and message first-level avps
 
   // Grouped helpers
   find_container a_finds; // fast access for grouped and message first-level avps
 
@@ -226,7 +178,7 @@ class Avp {
   static Avp * addAvp(avp_container &avps, int &insertionPositionForChilds, AvpId id, Engine *engine) throw();
   static bool removeAvp(avp_container &avps, find_container &finds, AvpId id, int ocurrence, Engine *engine) throw();
   static void fix(avp_container &avps, find_container &finds, int &insertionPositionForChilds, anna::diameter::stack::const_avprule_iterator ruleBegin, anna::diameter::stack::const_avprule_iterator ruleEnd) throw();
   static Avp * addAvp(avp_container &avps, int &insertionPositionForChilds, AvpId id, Engine *engine) throw();
   static bool removeAvp(avp_container &avps, find_container &finds, AvpId id, int ocurrence, Engine *engine) throw();
   static void fix(avp_container &avps, find_container &finds, int &insertionPositionForChilds, anna::diameter::stack::const_avprule_iterator ruleBegin, anna::diameter::stack::const_avprule_iterator ruleEnd) throw();
-  static bool validLevel(const avp_container &avps, anna::diameter::stack::const_avprule_iterator ruleBegin, anna::diameter::stack::const_avprule_iterator ruleEnd, Engine * engine, const std::string & parentDescription, Message *answer) throw(anna::RuntimeException); // validates mandatory/fixed and cardinality
+  static bool validLevel(const avp_container &avps, anna::diameter::stack::const_avprule_iterator ruleBegin, anna::diameter::stack::const_avprule_iterator ruleEnd, Engine * engine, const anna::diameter::codec::parent_t & parent, Message *answer) throw(anna::RuntimeException); // validates mandatory/fixed and cardinality
   static const Avp* getAvp(const avp_container &avps, find_container &finds, AvpId id, int ocurrence, Engine *engine, anna::Exception::Mode::_v emode) throw(anna::RuntimeException);
   static int countAvp(const avp_container &avps, AvpId id) throw();
   static const Avp* firstAvp(const avp_container &avps, AvpId id) throw();
   static const Avp* getAvp(const avp_container &avps, find_container &finds, AvpId id, int ocurrence, Engine *engine, anna::Exception::Mode::_v emode) throw(anna::RuntimeException);
   static int countAvp(const avp_container &avps, AvpId id) throw();
   static const Avp* firstAvp(const avp_container &avps, AvpId id) throw();
@@ -250,7 +202,6 @@ class Avp {
   static const Avp* avp(const_avp_iterator ii) throw() { return ii->second; }
 
   // Internal
   static const Avp* avp(const_avp_iterator ii) throw() { return ii->second; }
 
   // Internal
-  void assertFormat(const std::string &name) const throw(anna::RuntimeException);
   bool flagsOK() const throw(); // flags coherence regarding dictionary. Only must be called when AVP is identified at the dictionary.
   int addChild(Avp *avp) throw(anna::RuntimeException) { assertFormat("Grouped"); return addChild(a_avps, a_insertionPositionForChilds, avp); }
   bool hasChildren() throw() { return a_avps.size() != 0; }
   bool flagsOK() const throw(); // flags coherence regarding dictionary. Only must be called when AVP is identified at the dictionary.
   int addChild(Avp *avp) throw(anna::RuntimeException) { assertFormat("Grouped"); return addChild(a_avps, a_insertionPositionForChilds, avp); }
   bool hasChildren() throw() { return a_avps.size() != 0; }
@@ -269,12 +220,12 @@ class Avp {
   /**
      Validates an Avp regarding dictionary rules like enumerated range, flags coherence, mandatory and fixed types, cardinality qualifiers, etc.
 
   /**
      Validates an Avp regarding dictionary rules like enumerated range, flags coherence, mandatory and fixed types, cardinality qualifiers, etc.
 
-     @param parentDescription Parent description. Internally used for alarms and tracing
+     @param parent Parent description. Internally used for alarms, tracing and Failed-AVP construction
      @param answer Answer could be modified with any validation problem during requests validation
 
      @return Boolean indicating validation result
   */
      @param answer Answer could be modified with any validation problem during requests validation
 
      @return Boolean indicating validation result
   */
-  bool valid(const std::string & parentDescription, Message *answer) const throw(anna::RuntimeException);
+  bool valid(const anna::diameter::codec::parent_t & parent, Message *answer) const throw(anna::RuntimeException);
 
   /**
      Decodes buffer provided over class content. If an error ocurred, decoding will stop launching exception (fatal error) or a warning trace (perhaps the achieved
 
   /**
      Decodes buffer provided over class content. If an error ocurred, decoding will stop launching exception (fatal error) or a warning trace (perhaps the achieved
@@ -282,9 +233,10 @@ class Avp {
      depending on validation depth (codec::Engine::ValidationDepth).
 
      @param db Buffer data block processed
      depending on validation depth (codec::Engine::ValidationDepth).
 
      @param db Buffer data block processed
+     @param parent Parent description. Internally used for alarms, tracing and Failed-AVP construction
      @param answer Answer built for request decoding/validation
   */
      @param answer Answer built for request decoding/validation
   */
-  void decode(const anna::DataBlock &db, Message *answer) throw(anna::RuntimeException);
+  void decode(const anna::DataBlock &db, const anna::diameter::codec::parent_t & parent, Message *answer) throw(anna::RuntimeException);
 
 
   /////////////////////////////////////////////
 
 
   /////////////////////////////////////////////
@@ -293,80 +245,80 @@ class Avp {
 
   /**
   * Initializes Avp class information.
 
   /**
   * Initializes Avp class information.
-  * Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
+  * Default implementation supports all anna::diameter formats (including derived ones).
   * Diameter basic formats are managed at #initialize, which will invoke this method at the end.
   */
   * Diameter basic formats are managed at #initialize, which will invoke this method at the end.
   */
-  virtual void initializeByFormat() throw();
+  virtual void initializeByFormat() throw() {};
 
   /**
   * Gets avp data-part length.
 
   /**
   * Gets avp data-part length.
-  * Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
+  * Default implementation supports all anna::diameter formats (including derived ones).
   * Diameter basic formats are managed at #initialize, which will invoke this method at the end.
   *
   * @param stackFormat Stack avp format in which data extraction is based.
   *
   * @return Avp data-part size.
   */
   * Diameter basic formats are managed at #initialize, which will invoke this method at the end.
   *
   * @param stackFormat Stack avp format in which data extraction is based.
   *
   * @return Avp data-part size.
   */
-  virtual U24 getLengthByFormat(const anna::diameter::stack::Format *stackFormat) const throw();
+  virtual U24 getLengthByFormat(const anna::diameter::stack::Format *stackFormat) const throw() { return 0; };
 
   /**
      Gets data or hexadecimal data depending on avp format, for xml creating
 
   /**
      Gets data or hexadecimal data depending on avp format, for xml creating
-     Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
+     Default implementation supports all anna::diameter formats (including derived ones).
      Diameter basic formats are managed at #initialize, which will invoke this method at the end.
 
      \param isHex Hexadecimal/Natural data when apply.
      \param stackFormat Stack avp format in which data extraction is based.
      \return xml data representation
   */
      Diameter basic formats are managed at #initialize, which will invoke this method at the end.
 
      \param isHex Hexadecimal/Natural data when apply.
      \param stackFormat Stack avp format in which data extraction is based.
      \return xml data representation
   */
-  virtual std::string getXMLdataByFormat(bool & isHex, const anna::diameter::stack::Format *stackFormat) const throw();
+  virtual std::string getXMLdataByFormat(bool & isHex, const anna::diameter::stack::Format *stackFormat) const throw() { return ""; };
 
   /**
      Interpret xml data in order to dump over the class content.
 
   /**
      Interpret xml data in order to dump over the class content.
-     Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
+     Default implementation supports all anna::diameter formats (including derived ones).
      Diameter basic formats are managed at #initialize, which will invoke this method at the end.
 
      \param data Avp data attribute
      \param hexData Avp hex-data attribute
      \param stackFormat Stack avp format in which data extraction is based.
   */
      Diameter basic formats are managed at #initialize, which will invoke this method at the end.
 
      \param data Avp data attribute
      \param hexData Avp hex-data attribute
      \param stackFormat Stack avp format in which data extraction is based.
   */
-  virtual void fromXMLByFormat(const anna::xml::Attribute* data, const anna::xml::Attribute* hexData, const anna::diameter::stack::Format *stackFormat) throw(anna::RuntimeException);
+  virtual void fromXMLByFormat(const anna::xml::Attribute* data, const anna::xml::Attribute* hexData, const anna::diameter::stack::Format *stackFormat) throw(anna::RuntimeException) {};
 
 
   /**
      Encodes buffer with the class content.
 
 
   /**
      Encodes buffer with the class content.
-     Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
+     Default implementation supports all anna::diameter formats (including derived ones).
      Diameter basic formats are managed at #initialize, which will invoke this method at the end.
 
      @param dataPart Data-part begin pointer
      @param stackFormat Stack avp format in which data extraction is based.
   */
      Diameter basic formats are managed at #initialize, which will invoke this method at the end.
 
      @param dataPart Data-part begin pointer
      @param stackFormat Stack avp format in which data extraction is based.
   */
-  virtual void codeByFormat(char* dataPart, const anna::diameter::stack::Format *stackFormat) const throw(anna::RuntimeException);
+  virtual void codeByFormat(char* dataPart, const anna::diameter::stack::Format *stackFormat) const throw(anna::RuntimeException) {};
 
 
   /**
      Decodes Avp data part.
 
 
   /**
      Decodes Avp data part.
-     Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
+     Default implementation supports all anna::diameter formats (including derived ones).
      Diameter basic formats are managed at #initialize, which will invoke this method at the end.
 
      @param buffer Avp data part start pointer
      @param size Avp data part size
      @param stackFormat Stack avp format in which data extraction is based.
   */
      Diameter basic formats are managed at #initialize, which will invoke this method at the end.
 
      @param buffer Avp data part start pointer
      @param size Avp data part size
      @param stackFormat Stack avp format in which data extraction is based.
   */
-  virtual void decodeDataPartByFormat(const char * buffer, int size, const anna::diameter::stack::Format *stackFormat) throw(anna::RuntimeException);
+  virtual void decodeDataPartByFormat(const char * buffer, int size, const anna::diameter::stack::Format *stackFormat) throw(anna::RuntimeException) {};
 
   /**
      Reserves memory for data part depending on avp format for the identifier provided.
 
   /**
      Reserves memory for data part depending on avp format for the identifier provided.
-     Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
+     Default implementation supports all anna::diameter formats (including derived ones).
      Diameter basic formats are managed at #initialize, which will invoke this method at the end.
 
      @param stackFormat Stack avp format in which data extraction is based.
   */
      Diameter basic formats are managed at #initialize, which will invoke this method at the end.
 
      @param stackFormat Stack avp format in which data extraction is based.
   */
-  virtual void allocationByFormat(const anna::diameter::stack::Format *stackFormat) throw();
+  virtual void allocationByFormat(const anna::diameter::stack::Format *stackFormat) throw() {};
 
   /**
   * Clears Avp data-part format containers.
   */
 
   /**
   * Clears Avp data-part format containers.
   */
-  virtual void clearByFormat() throw();
+  virtual void clearByFormat() throw() {};
 
 
 
 
 
 
@@ -383,6 +335,10 @@ protected:
   */
   void initialize() throw();
 
   */
   void initialize() throw();
 
+  /**
+  * Assert format regarding dictionary
+  */
+  void assertFormat(const std::string &name) const throw(anna::RuntimeException);
 
   /**
   * Gets avp total length based on internal data part and header configuration.
 
   /**
   * Gets avp total length based on internal data part and header configuration.
@@ -401,45 +357,51 @@ protected:
   */
   std::string getXMLdata(bool & isHex, const anna::diameter::stack::Format *stackFormat) const throw();
 
   */
   std::string getXMLdata(bool & isHex, const anna::diameter::stack::Format *stackFormat) const throw();
 
-  /**
-     Interpret xml data in order to dump over the class content.
-
-     \param avpNode Avp root node
-  */
-  void fromXML(const anna::xml::Node* avpNode) throw(anna::RuntimeException);
-
-
-  /**
-     Encodes buffer with the class content.
-
-  * @param buffer Raw data to be encoded
-  * @param size Size of raw data to be encoded
-  */
-  void code(char* buffer, int &size) const throw(anna::RuntimeException);
-
 
   /**
      Decodes Avp data part.
 
      @param buffer Avp data part start pointer
      @param size Avp data part size
 
   /**
      Decodes Avp data part.
 
      @param buffer Avp data part start pointer
      @param size Avp data part size
+     @param parent Parent description. Internally used for alarms, tracing and Failed-AVP construction
      @param answer Answer built for request decoding/validation
   */
      @param answer Answer built for request decoding/validation
   */
-  void decodeDataPart(const char * buffer, int size, Message *answer) throw(anna::RuntimeException);
+  void decodeDataPart(const char * buffer, int size, const anna::diameter::codec::parent_t & parent, Message *answer) throw(anna::RuntimeException);
 
 
 public:
 
   /**
   * Default constructor
 
 
 public:
 
   /**
   * Default constructor
+  * @param engine Codec engine used
   */
   */
-  Avp();
+  Avp(Engine *engine = NULL);
 
   /**
   * Identified constructor
   * @param id Avp identifier as pair (code,vendor-id).
 
   /**
   * Identified constructor
   * @param id Avp identifier as pair (code,vendor-id).
+  * @param engine Codec engine used
   */
   */
-  Avp(AvpId id);
+  Avp(AvpId id, Engine *engine = NULL);
+
+
+  /**
+  * Sets the codec engine
+  *
+  * Once assigned (here or at constructor), this method SHALL NOT be used anymore.
+  * Also, the associated dictionary SHOULD NOT BE CHANGED through the engine,
+  * unless you know what are you doing. If you want to reconfigure the engine,
+  * first #clear the avp and then you could reuse the same object with
+  * different configurations (execution contexts).
+  *
+  * Setting a new different engine with different stack, even same engine where the
+  * stack has been dynamically changed, could cause a bad behaviour depending on the
+  * changes: in general, if the dictionary grows, nothing bad will happen, but if
+  * you remove or modified some elements which were processed with a certain format,
+  * will be interpreted as 'unknown' with the new dictionary, and then some problems
+  * may occur. If you add elements (vendors, avps, messages) is not a problem.
+  */
+  void setEngine(Engine *engine) throw();
 
 
   // Length references
 
 
   // Length references
@@ -463,7 +425,7 @@ public:
   /**
   * Destructor
   */
   /**
   * Destructor
   */
-  ~Avp();
+  virtual ~Avp();
 
 
   // setters
 
 
   // setters
@@ -515,7 +477,7 @@ public:
 
   /**
      Adds an avp child providing its identifier and reserve internal memory it.
 
   /**
      Adds an avp child providing its identifier and reserve internal memory it.
-     An exception is launched is the Avp is not a grouped avp.
+     An exception is launched is the Avp over which we add the new avp, is not a grouped avp.
 
      @param id Avp identifier as pair (code,vendor-id).
 
 
      @param id Avp identifier as pair (code,vendor-id).
 
@@ -529,16 +491,19 @@ public:
   */
   Avp * addAvp(const char *name) throw(anna::RuntimeException);
 
   */
   Avp * addAvp(const char *name) throw(anna::RuntimeException);
 
-
   /**
      Adds an avp child providing a persistent pointer (must be maintained by application).
   /**
      Adds an avp child providing a persistent pointer (must be maintained by application).
-     An exception is launched is the Avp is not a grouped avp.
+     An exception is launched is the Avp over which we add the new avp, is not a grouped avp.
+     It is not allowed to add an avp with no codec engine configured, neither if the engine
+     is not the same.
 
      @param avp Avp external pointer. If NULL provided, nothing is done and NULL returned.
 
      @param avp Avp external pointer. If NULL provided, nothing is done and NULL returned.
+     Also NULL returned for bad engine configuration.
 
      @return Pointer to the added avp (again).
   */
 
      @return Pointer to the added avp (again).
   */
-  Avp * addAvp(Avp * avp) throw(anna::RuntimeException) { if(!avp) return NULL; addChild(avp); return avp; }
+  Avp * addAvp(Avp * avp) throw(anna::RuntimeException);
+
 
   // Data part access
   /** Access content for OctetString Avp in order to set data part */
 
   // Data part access
   /** Access content for OctetString Avp in order to set data part */
@@ -574,15 +539,6 @@ public:
   /** Access content for Unknown Avp in order to set data part */
   Unknown *            getUnknown() throw(anna::RuntimeException) { assertFormat("Unknown"); return a_Unknown; }
 
   /** Access content for Unknown Avp in order to set data part */
   Unknown *            getUnknown() throw(anna::RuntimeException) { assertFormat("Unknown"); return a_Unknown; }
 
-  // Derived formats ////////////////////////////////////////////
-  /* TME */
-  /** Access content for ISDNNumber Avp in order to set data part */
-  ISDNNumber *        getISDNNumber() throw(anna::RuntimeException) { assertFormat("ISDNNumber"); return a_ISDNNumber; }
-  /** Access content for ISDNAddress Avp in order to set data part */
-  ISDNAddress *        getISDNAddress() throw(anna::RuntimeException) { assertFormat("ISDNAddress"); return a_ISDNAddress; }
-  /** Access content for Unsigned16 Avp in order to set data part */
-  Unsigned16 *        getUnsigned16() throw(anna::RuntimeException) { assertFormat("Unsigned16"); return a_Unsigned16; }
-
 
   /**
      Removes an Avp within grouped type (first level) and free resources.
 
   /**
      Removes an Avp within grouped type (first level) and free resources.
@@ -714,14 +670,35 @@ public:
   const Unknown *            getUnknown() const throw(anna::RuntimeException) { assertFormat("Unknown"); return a_Unknown; }
 
 
   const Unknown *            getUnknown() const throw(anna::RuntimeException) { assertFormat("Unknown"); return a_Unknown; }
 
 
-  // Derived formats ////////////////////////////////////////////
-  /* TME */
-  /** Access content for ISDNNumber Avp */
-  const ISDNNumber *         getISDNNumber() const throw(anna::RuntimeException) { assertFormat("ISDNNumber"); return a_ISDNNumber; }
-  /** Access content for ISDNAddress Avp */
-  const ISDNAddress *        getISDNAddress() const throw(anna::RuntimeException) { assertFormat("ISDNAddress"); return a_ISDNAddress; }
-  /** Access content for Unsigned16 Avp */
-  const Unsigned16 *        getUnsigned16() const throw(anna::RuntimeException) { assertFormat("Unsigned16"); return a_Unsigned16; }
+  /**
+     Decodes buffer provided over class content. If an error ocurred, decoding will stop launching exception (fatal error) or a warning trace (perhaps the achieved
+     avp is valid against all odds then validation will go on). In case that validation is enabled (codec::Engine::ValidationMode) an exception will be launched
+     depending on validation depth (codec::Engine::ValidationDepth).
+
+     Useful as serialization procedure with #code
+
+     @param db Buffer data block processed
+  */
+  void decode(const anna::DataBlock &db) throw(anna::RuntimeException);
+
+
+  /**
+     Interpret xml data in order to dump over the class content.
+
+     \param avpNode Avp root node
+  */
+  void fromXML(const anna::xml::Node* avpNode) throw(anna::RuntimeException);
+
+
+  /**
+    Encodes buffer with the class content. This method is internally used to encode diameter messages, but is declared as public, to allow
+    its use as serialization procedure. Then, it's assumed that this Avp is valid (validation shall be applied as part of a whole diameter
+    message but nothing will be verified now).
+
+  * @param buffer Raw data to be encoded (shall be externally allocated)
+  * @param size Size of raw data to be encoded
+  */
+  void code(char* buffer, int &size) const throw(anna::RuntimeException);
 
 
   // Helpers
 
 
   // Helpers
@@ -735,9 +712,32 @@ public:
 
   /**
      Class xml string representation
 
   /**
      Class xml string representation
+     @param normalize Optional normalization which sorts attribute names and removes
+     newlines in the xml representation in order to ease regexp matching.
+
      \return XML string representation with relevant information for this instance.
   */
      \return XML string representation with relevant information for this instance.
   */
-  std::string asXMLString() const throw();
+  std::string asXMLString(bool normalize = false) const throw();
+
+  /**
+     Comparison operator by mean serialization
+
+     @param a1 Instance 1 for Avp class
+     @param a2 Instance 2 for Avp class
+
+     @return Comparison result
+  */
+  friend bool operator == (const Avp & a1, const Avp & a2) throw() { return (a1.asXMLString() == a2.asXMLString()); }
+
+  /**
+     Match a regular expression (string pattern) regarding xml string serialization for this avp.
+     This works same as #Message::isLike
+
+     @param pattern Pattern to match
+
+     \return Returns the match result
+  */
+  bool isLike(const std::string &pattern) const throw();
 
   /**
      Counts the number of ocurrences of Avps (first level) with the identifier provided
 
   /**
      Counts the number of ocurrences of Avps (first level) with the identifier provided
@@ -764,12 +764,10 @@ public:
      Diameter Relay and redirect agents MUST NOT reject messages with unrecognized AVPs.
 
      Default implementation launch alarm and counter indicating the anomaly but don't launch exception (traces at warning level).
      Diameter Relay and redirect agents MUST NOT reject messages with unrecognized AVPs.
 
      Default implementation launch alarm and counter indicating the anomaly but don't launch exception (traces at warning level).
-     Realy and Redirect agents could reimplement this method to avoid oam management (another way is avoid alarm/counter registration on
+     Relay and Redirect agents could reimplement this method to avoid oam management (another way is avoid alarm/counter registration on
      these applications). Result-Code DIAMETER_AVP_UNSUPPORTED will be stored for possible answer message.
      these applications). Result-Code DIAMETER_AVP_UNSUPPORTED will be stored for possible answer message.
-
-     @param answer Answer built for request decoding/validation
   */
   */
-  virtual void unknownAvpWithMandatoryBit(Message *answer) const throw(anna::RuntimeException);
+  virtual void unknownAvpWithMandatoryBit() const throw(anna::RuntimeException);
 
 
   friend class Message;
 
 
   friend class Message;