#include <anna/core/mt/Guard.hpp>
-
-namespace anna {
-namespace diameter {
-namespace codec {
-
-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-by-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-by-end-id: Message end by 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\
-";
-
-
-}
-}
-}
-
using namespace anna::diameter::codec;
//------------------------------------------------------------------------------
//----------------------------------------------------- EngineImpl::EngineImpl()
//------------------------------------------------------------------------------
-EngineImpl::EngineImpl(const char* className) :
+EngineImpl::EngineImpl(const char* className, const stack::Dictionary * dictionary) :
anna::Component(className),
- a_dictionary(NULL),
+ a_dictionary(dictionary),
a_validationDepth(ValidationDepth::FirstError),
a_validationMode(ValidationMode::AfterDecoding),
+ a_singleFailedAVP(true),
a_ignoreFlags(false),
- a_selectStackWithApplicationId(false),
a_fixMode(FixMode::BeforeEncoding) {
anna::diameter::sccs::activate();
anna::xml::functions::initialize();
- a_dtd.initialize(MessageDTD);
-}
-
-
-//------------------------------------------------------------------------------
-//-------------------------------------------------- EngineImpl::setDictionary()
-//------------------------------------------------------------------------------
-const anna::diameter::stack::Dictionary *EngineImpl::setDictionary(unsigned int stackId) throw() {
- a_dictionary = (stack::Engine::instantiate()).getDictionary(stackId);
- return a_dictionary;
}
if((result = allocateAvp()) == NULL)
throw anna::RuntimeException("diameter::codec::EngineImpl::allocateAvp returns NULL", ANNA_FILE_LOCATION);
+ // Sets engine
+ result->setEngine((Engine*)this);
+
//result->clear(); better clear this at releaseAvp(), see class-help implementation example
if(id) result->setId(*id);
if((result = allocateMessage()) == NULL)
throw anna::RuntimeException("diameter::codec::EngineImpl::allocateMessage returns NULL", ANNA_FILE_LOCATION);
+ // Sets engine
+ result->setEngine((Engine*)this);
+
//result->clear(); better clear this at releaseMessage(), see class-help implementation example
if(id) result->setId(*id);
result += asText(a_validationDepth);
result += "\nValidationMode: ";
result += asText(a_validationMode);
+ result += "\nSingle Failed-AVP: ";
+ result += a_singleFailedAVP ? "yes" : "no";
result += "\nIgnore flags: ";
result += a_ignoreFlags ? "yes" : "no";
result += "\nFixMode: ";
anna::xml::Node* result = parent->createChild("diameter.codec.EngineImpl");
result->createAttribute("ValidationDepth", asText(a_validationDepth));
result->createAttribute("ValidationMode", asText(a_validationMode));
+ result->createAttribute("SingleFailedAVP", a_singleFailedAVP ? "yes" : "no");
result->createAttribute("IgnoreFlags", a_ignoreFlags ? "yes" : "no");
result->createAttribute("FixMode", asText(a_fixMode));
- anna::xml::Node* dictionary = result->createChild("EngineImpl.ActivatedDictionary");
+ result->createChild("EngineImpl.ActivatedDictionary");
if(a_dictionary) a_dictionary->asXML(result);