Remove warnings
[anna.git] / include / anna / diameter / codec / functions.hpp
index 770fcc1..acafa64 100644 (file)
 #define anna_diameter_codec_functions_hpp
 
 
-// Local
+// Project
 #include <anna/diameter/defines.hpp>
-
 #include <anna/core/RuntimeException.hpp>
+#include <anna/xml/xml.hpp>
 
 // STL
 #include <string>
@@ -41,6 +41,79 @@ namespace diameter {
 namespace codec {
 
 
+static const char *MessageDTD = "\
+<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
+<!-- Diameter message DTD -->\n\
+\n\
+<!ELEMENT message (avp*)>\n\
+<!ELEMENT avp (avp*)>\n\
+\n\
+<!ATTLIST message version CDATA #IMPLIED name CDATA #IMPLIED code CDATA #IMPLIED flags CDATA #IMPLIED p-bit (yes | no) #IMPLIED e-bit (yes | no) #IMPLIED t-bit (yes | no) #IMPLIED application-id CDATA #REQUIRED hop-by-hop-id CDATA #IMPLIED end-to-end-id CDATA #IMPLIED>\n\
+<!--\n\
+   version: Diameter version. Sets '1' by default\n\
+   name:    Command name within working stack (dictionary identifier)\n\
+   p-bit:   (P)roxiable bit flag (yes, no). By default is 'no'\n\
+   e-bit:   (E)rror bit flag (yes, no). By default is 'no'\n\
+   t-bit:   Potentially re-(T)ransmitted bit flag (yes, no). By default is 'no'\n\
+\n\
+   In order to get more coding capabilities, command code and flags could be established instead of former fields,\n\
+    but neither of them are allowed if the other are present (and vice versa):\n\
+\n\
+   code:    Command code\n\
+   flags:   Command flags byte value (0-255) where standard bit set for flags is 'RPET rrrr': (R)equest, (P)roxiable, (E)rror, Potentially re-(T)ransmitted message and (r)eserved\n\
+\n\
+\n\
+   application-id:   Message application id\n\
+   hop-by-hop-id:    Message hop by hop id. Sets '0' by default\n\
+   end-to-end-id:    Message end to end id. Sets '0' by default\n\
+-->\n\
+\n\
+<!ATTLIST avp name CDATA #IMPLIED code CDATA #IMPLIED vendor-code CDATA #IMPLIED flags CDATA #IMPLIED data CDATA #IMPLIED hex-data CDATA #IMPLIED alias CDATA #IMPLIED>\n\
+<!--\n\
+   name:   Avp name within working stack (dictionary identifier)\n\
+\n\
+   In order to get more coding capabilities, avp code, vendor-id and flags could be established instead of former avp name,\n\
+    but neither of them are allowed if 'name' is provided (and vice versa):\n\
+\n\
+   code:          Avp code\n\
+   vendor-code:   Avp vendor code\n\
+   flags:         Avp flags byte value (0-255) where standard bit set for flags is 'VMPr rrrr': (V)endor-specific, (M)andatory, end to end encry(P)tion and r(eserved)\n\
+   alias:         Descriptive/helper field for certain numeric data values. Aliases are defined at diameter dictionary, but are ignored (not checked) at xml message parsing\n\
+                  The reason to include it in dtd definition, is because xml messages traced by the diameter codec could add alias field for some Avps\n\
+\n\
+\n\
+   data:          Natural string representation for avp data. Specially applicable with numbers and printable strings, but also\n\
+                   useful for certain formats which could be easily understandable in such friendly/smart representation. We will\n\
+                   achieve different human-readable strings depending on data format:\n\
+\n\
+                     [ OctetString ] (if printable, but not recommended)\n\
+                     [ Integer32, Integer64, Unsigned32, Unsigned64, Float32, Float64 ] (normal number representation)\n\
+                     [ Time ] (NTP timestamp, normal number representation)\n\
+                     [ Address ] ('<type (IANA Address Family Number)>|<value>' representation; i.e. '1|192.168.0.1'(IPv4), '8|34616279266'(E164), etc.\n\
+                                 Type (and pipe) field could be avoided for IPv4 and IPv6 address types (a light parse checking is done: one colon for\n\
+                                 IPv6, one dot for IPv4). Internal engine always includes type on data field, which is also recommended for inputs.\n\
+                                 Currently, only IPv4, IPv6 and E164 address types have a known printable presentation, anyway using printable format\n\
+                                 for another types will encode the address value directly as E164 does)\n\
+                     [ UTF8String, DiameterIdentity, DiameterURI ] (printable)\n\
+                     [ IPFilterRule, QoSFilterRule ] (uses ASCII charset, printable)\n\
+\n\
+                     New application formats must define specific natural representation for internal raw data\n\
+\n\
+   hex-data:      Hexadecimal octet sequence representation (i.e. 'af012fb3', with even number of digits). Suitable for whatever kind\n\
+                   of diameter format, but mandatory for non printable information. OctetString usually transport non human-readable\n\
+                   data and should better be encoded within this field although being printable. Unknown avps (which fails identifying\n\
+                   provided name or code/vendor-code) must always use this representation.\n\
+\n\
+   Xml representation for decoded messages shows natural content except for 'OctetString' format and unknown avps. Anyway, when printable,\n\
+    OctetString could show such information at data field apart from hex-data, because many implementations use this format to transport\n\
+    readable-string data. In general, one of the data fields is mandatory except for 'Grouped' type (its data is another level of avps).\n\
+   Application-specific formats must decide the way to represent its contents, being recommended to use a natural representation if possible,\n\
+    because xml is read by humans with testing and monitoring purposes.\n\
+-->\n\
+\n\
+";
+
+
 // Used for alarms, tracing and Failed-AVP construction:
 typedef struct parent {
 
@@ -82,51 +155,75 @@ struct functions {
 
 
   /**
-  * Decodes a Command Header. This helper cannot check boundaries. start pointer must be a valid command context.
-  *
-  * @param start Must be a valid command start (point to the command version byte).
-  * @param version Diameter version.
-  * @param length Message length.
-  * @param flags Command flags.
-  * @param id Command identification (code, request<true,false>).
-  * @param appId Application-ID.
-  * @param hbh Hop-by-Hop Identifier.
-  * @param ete End-to-End Identifier.
-  */
+   * Decodes a Command Header. This helper cannot check boundaries. start pointer must be a valid command context.
+   *
+   * @param start Must be a valid command start (point to the command version byte).
+   * @param version Diameter version.
+   * @param length Message length.
+   * @param flags Command flags.
+   * @param id Command identification (code, request<true,false>).
+   * @param appId Application-ID.
+   * @param hbh Hop-by-Hop Identifier.
+   * @param ete End-to-End Identifier.
+   */
   static void decodeCommandHeader(const char *start, char & version, U24 & length, char & flags, CommandId & id, int & appId, int & hbh, int & ete) throw(anna::RuntimeException);
 
   /**
-  * Decodes an AVP. This helper cannot check boundaries. start pointer must be a valid avp context.
-  *
-  * @param start Must be a valid avp start (point to the 32-bits avp code word).
-  * @param id Avp identification (code, vendorId).
-  * @param flags Avp flags byte.
-  * @param length Avp length (includes code, flags, length itself, vendorId if exists and data length).
-  * @param data Avp data part.
-  */
+   * Decodes an AVP. This helper cannot check boundaries. start pointer must be a valid avp context.
+   *
+   * @param start Must be a valid avp start (point to the 32-bits avp code word).
+   * @param id Avp identification (code, vendorId).
+   * @param flags Avp flags byte.
+   * @param length Avp length (includes code, flags, length itself, vendorId if exists and data length).
+   * @param data Avp data part.
+   */
   static void decodeAVP(const char *start, AvpId & id, char & flags, int & length, std::string & data) throw(anna::RuntimeException);
 
   /**
-  * Gets the next AVP pointer reference starting from a first-avp datablock. It could be the first avp within
-  * a command, or within an grouped avp.
-  *
-  * @param avpsDB AVPs set as datablock
-  * @param start Point to start the search. Must be a valid avp start (point to the 32-bits avp code word).
-  *
-  * @return Pointer to the next AVP found. NULL if no more.
-  */
-  static const char * nextAVP(const anna::DataBlock & avpsDB, const char *start) throw(anna::RuntimeException);
+   * Gets the next AVP pointer reference starting from a first-avp data block. It could be the first avp within
+   * a command, or within an grouped avp.
+   *
+   * @param avpsDB AVP data block buffer pointer
+   * @param avpsLen AVP data block buffer length
+   * @param start Point to start the search. Must be a valid avp start (point to the 32-bits avp code word).
+   *
+   * @return Pointer to the next AVP found. NULL if no more.
+   */
+  static const char * nextAVP(const char *avpsDB, int avpsLen, const char *start) throw(anna::RuntimeException);
+
+  //  /**
+  //  * Gets the next AVP pointer reference starting from a first-avp datablock. It could be the first avp within
+  //  * a command, or within an grouped avp.
+  //  *
+  //  * @param avpsDB AVPs set as datablock
+  //  * @param start Point to start the search. Must be a valid avp start (point to the 32-bits avp code word).
+  //  *
+  //  * @return Pointer to the next AVP found. NULL if no more.
+  //  */
+  //  static const char * nextAVP(const anna::DataBlock & avpsDB, const char *start) throw(anna::RuntimeException);
 
   /**
-  * Gets the next AVP pointer reference within an AVPs set datablock with a certain AVP identification.
-  *
-  * @param avpsDB AVPs set as datablock
-  * @param id Avp identification (code, vendorId).
-  * @param n Ocurrence number (first avp, second avp, etc.)
-  *
-  * @return Pointer to first AVP found with identification provided. NULL if not found.
-  */
-  static const char * findAVP(const anna::DataBlock & avpsDB, const AvpId & id, int n = 1) throw(anna::RuntimeException);
+   * Gets the next AVP pointer reference within an AVPs set data block with a certain AVP identification.
+   *
+   * @param avpsDB AVP data block buffer pointer
+   * @param avpsLen AVP data block buffer length
+   * @param id Avp identification (code, vendorId).
+   * @param n Ocurrence number (first avp, second avp, etc.). 1 by default.
+   *
+   * @return Pointer to first AVP found with identification provided. NULL if not found.
+   */
+  static const char *findAVP(const char *avpsDB, int avpsLen, const diameter::AvpId & id, int n = 1) throw(anna::RuntimeException);
+
+  //  /**
+  //  * Gets the next AVP pointer reference within an AVPs set datablock with a certain AVP identification.
+  //  *
+  //  * @param avpsDB AVPs set as datablock
+  //  * @param id Avp identification (code, vendorId).
+  //  * @param n Ocurrence number (first avp, second avp, etc.). 1 by default.
+  //  *
+  //  * @return Pointer to first AVP found with identification provided. NULL if not found.
+  //  */
+  //  static const char * findAVP(const anna::DataBlock & avpsDB, const AvpId & id, int n = 1) throw(anna::RuntimeException);
 
 
 
@@ -134,6 +231,94 @@ struct functions {
   static void setHopByHop(anna::DataBlock &, HopByHop) throw(anna::RuntimeException);
   static void setEndToEnd(anna::DataBlock &, EndToEnd) throw(anna::RuntimeException);
   static void setPotentiallyReTransmittedMessageBit(const anna::DataBlock & db, bool activate = true) throw(anna::RuntimeException);
+
+
+  /**
+     Interpret a xml file in order to create a memory xml document.
+     The xml file is based on this message DTD:
+
+     <pre>
+     <!ELEMENT message (avp*)>
+     <!ELEMENT avp (avp*)>
+
+     <!ATTLIST message version CDATA #IMPLIED name CDATA #IMPLIED code CDATA #IMPLIED flags CDATA #IMPLIED application-id CDATA #REQUIRED hop-by-hop-id CDATA #IMPLIED end-to-end-id CDATA #IMPLIED>
+     <!--
+        version: Diameter version. Sets '1' by default
+        name:    Command name within working stack (dictionary identifier)
+
+        In order to get more coding capabilities, command code and flags could be established instead of former command name,
+         but neither of them are allowed if 'name' is provided (and vice versa):
+
+        code:    Command code
+        flags:   Command flags byte value (0-255) where standard bit set for flags is 'RPET rrrr': (R)equest, (P)roxiable, (E)rror, Potentially re-(T)ransmitted message and (r)eserved
+
+
+        application-id:   Message application id
+        hop-by-hop-id:    Message hop by hop id. Sets '0' by default
+        end-to-end-id:    Message end to end id. Sets '0' by default
+     -->
+
+     <!ATTLIST avp name CDATA #IMPLIED code CDATA #IMPLIED vendor-code CDATA #IMPLIED flags CDATA #IMPLIED data CDATA #IMPLIED hex-data CDATA #IMPLIED>
+     <!--
+        name:   Avp name within working stack (dictionary identifier)
+
+        In order to get more coding capabilities, avp code, vendor-id and flags could be established instead of former avp name,
+         but neither of them are allowed if 'name' is provided (and vice versa):
+
+        code:          Avp code
+        vendor-code:   Avp vendor code
+        flags:         Avp flags byte value (0-255) where standard bit set for flags is 'VMPr rrrr': (V)endor-specific, (M)andatory, end to end encry(P)tion and r(eserved)
+
+
+        data:          Natural string representation for avp data. Specially applicable with numbers and printable strings, but also
+                        useful for certain formats which could be easily understandable in such friendly/smart representation. We will
+                        achieve different human-readable strings depending on data format:
+
+                          [ OctetString ] (if printable, but not recommended)
+                          [ Integer32, Integer64, Unsigned32, Unsigned64, Float32, Float64 ] (normal number representation)
+                          [ Time ] (NTP timestamp, normal number representation)
+                          [ Address ] (auto detects IPv4 or IPv6 address version, then only ip address is specified: IPv4 with dots, IPv6 with colons)
+                          [ UTF8String, DiameterIdentity, DiameterURI ] (printable)
+                          [ IPFilterRule, QoSFilterRule ] (uses ASCII charset, printable)
+
+                          New application formats must define specific natural representation for internal raw data
+
+        hex-data:      Hexadecimal octet sequence representation (i.e. 'af012fb3', with even number of digits). Suitable for whatever kind
+                        of diameter format, but mandatory for non printable information. OctetString usually transport non human-readable
+                        data and should better be encoded within this field although being printable. Unknown avps (which fails identifying
+                        provided name or code/vendor-code) must always use this representation.
+
+        Xml representation for decoded messages shows natural content except for 'OctetString' format and unknown avps. Anyway, when printable,
+         OctetString could show such information at data field apart from hex-data, because many implementations use this format to transport
+         readable-string data. In general, one of the data fields is mandatory except for 'Grouped' type (its data is another level of avps).
+        Application-specific formats must decide the way to represent its contents, being recommended to use a natural representation if possible,
+         because xml is read by humans with testing and monitoring purposes.
+     -->
+     </pre>
+
+     @param xmlDocument XML document allocated by the user of the function (anna::xml::DocumentMemory xmlDocument)
+     @param xmlPathFile Complete path file to the xml document which represents the diameter message
+     @see messageXmlDocumentFromXmlString
+
+     @warning Whatever you will do with the xml document, will be only valid inside the scope of such xml document.
+     For example, you could load the document to be decoded over a codec Message by mean #Message::fromXML (using
+     the xml document #getRootNode) during document lifetime. After that, it could be destroyed.
+   */
+  static void messageXmlDocumentFromXmlFile(anna::xml::DocumentFile &xmlDocument, const std::string & xmlPathFile) throw(anna::RuntimeException);
+
+  /**
+     Interpret xml string representation in order to create a memory xml document.
+     DTD validation is used in the same way that #messageXmlDocumentFromXmlFile does.
+
+     @param xmlDocument XML document allocated by the user of the function (anna::xml::DocumentMemory xmlDocument)
+     @param xmlString XML string representation of the diameter message
+     @see messageXmlDocumentFromXmlFile
+
+     @warning Whatever you will do with the xml document, will be only valid inside the scope of such xml document.
+     For example, you could load the document to be decoded over a codec Message by mean #Message::fromXML (using
+     the xml document #getRootNode) during document lifetime. After that, it could be destroyed.
+   */
+  static void messageXmlDocumentFromXmlString(anna::xml::DocumentFile &xmlDocument, const std::string &xmlString) throw(anna::RuntimeException);
 };