1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
9 #ifndef anna_diameter_codec_Avp_hpp
10 #define anna_diameter_codec_Avp_hpp
14 #include <anna/config/defines.hpp>
15 #include <anna/diameter/defines.hpp>
16 #include <anna/diameter/codec/basetypes/basetypes.hpp>
17 #include <anna/diameter/codec/functions.hpp>
18 #include <anna/diameter/stack/Avp.hpp>
20 #include <anna/core/RuntimeException.hpp>
26 //------------------------------------------------------------------------------
27 //---------------------------------------------------------------------- #define
28 //------------------------------------------------------------------------------
64 class DiameterIdentity;
77 typedef std::map < int /* key: insertion pos */, Avp* > avp_container;
78 typedef avp_container::iterator avp_iterator;
79 typedef avp_container::const_iterator const_avp_iterator;
81 // Cache avp-find system
82 typedef std::pair < AvpId, unsigned int /* position */ > find_key;
83 typedef std::map<find_key, Avp*> find_container;
84 typedef std::map<find_key, Avp*>::iterator find_iterator;
87 using namespace basetypes;
90 * Diameter avp generic container
92 * RFC 3588 Diameter Based Protocol September 2003
95 * The fields in the AVP header MUST be sent in network byte order. The
96 * format of the header is:
99 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
100 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
102 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
103 * | AVP Flags | AVP Length |
104 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
105 * | Vendor-ID (opt) |
106 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
111 * AVP Flags: V (vendor-specific), M (mandatory), P (end to end encryption)
117 * The AVP Length field is three octets, and indicates the number of
118 * octets in this AVP including the AVP Code, AVP Length, AVP Flags,
119 * Vendor-ID field (if present) and the AVP data.
121 * Vendor-ID: IANA "SMI Network Management Private Enterprise Codes" [ASSIGNNO]
122 * http://www.iana.org/assignments/enterprise-numbers
127 AvpId a_id; // code and vendor-code
131 int a_insertionPositionForChilds; // used at grouped type
134 // --- Developer notes ---
135 // 'AVP Length' does not include posible data padding. Thanks to this, 'Data Length'
136 // is the difference between 'AVP Length' and sum of code, length, flags and
137 // optionally the vendor-ID (all of them are 32-bit boundary), that is to say:
138 // 8 or 12 (vendor-specific avps).
140 // Grouped avps 'AVP Length' includes own headers plus the total length of all
141 // underlying AVPs, including their headers and padding, then 'AVP Length' is
142 // always multiple of 4 (library will check this), and smae for 'Data Length'
143 // which is an 'whole avp Length with padding' itself.
146 OctetString *a_OctetString;
147 Integer32 *a_Integer32;
148 Integer64 *a_Integer64;
149 Unsigned32 *a_Unsigned32;
150 Unsigned64 *a_Unsigned64;
153 avp_container a_avps; // Grouped
156 UTF8String *a_UTF8String;
157 DiameterIdentity *a_DiameterIdentity;
158 DiameterURI *a_DiameterURI;
159 Enumerated *a_Enumerated;
160 IPFilterRule *a_IPFilterRule;
161 QoSFilterRule *a_QoSFilterRule;
165 find_container a_finds; // fast access for grouped and message first-level avps
168 // Static functions are used when you want a function that is the same for every instance of a class. Such functions do not have access
169 // to "this" pointer and thus cannot access any non static fields. They are used often when you want a function that can be used without
170 // instantiating the class. Friend functions are functions which are not in the class and you want to give them access to private members
173 // Common (also for Message class)
174 static avp_iterator avp_find(avp_container &avps, AvpId id, unsigned int position) throw();
175 static const_avp_iterator avp_find(const avp_container &avps, AvpId id, unsigned int position) throw() {
176 return (const_avp_iterator)avp_find((avp_container &)avps, id, position);
178 static Avp * addAvp(avp_container &avps, int &insertionPositionForChilds, AvpId id, Engine *engine) throw();
179 static bool removeAvp(avp_container &avps, find_container &finds, AvpId id, int ocurrence, Engine *engine) throw();
180 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();
181 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
182 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);
183 static int countAvp(const avp_container &avps, AvpId id) throw();
184 static const Avp* firstAvp(const avp_container &avps, AvpId id) throw();
185 static int countChilds(const avp_container &avps) throw();
186 static int addChild(avp_container &avps, int &insertionPositionForChilds, Avp *avp) throw() {
189 avps[insertionPositionForChilds++] = avp;
190 return insertionPositionForChilds;
192 static const anna::diameter::stack::Avp *getStackAvp(AvpId id, Engine *engine) throw();
193 const Avp* _getAvp(const char *name, int ocurrence, anna::Exception::Mode::_v emode) const throw(anna::RuntimeException);
194 const Avp* _getAvp(AvpId id, int ocurrence, anna::Exception::Mode::_v emode) const throw(anna::RuntimeException);
197 avp_iterator avp_begin() throw() { return a_avps.begin(); }
198 avp_iterator avp_end() throw() { return a_avps.end(); }
199 static Avp* avp(avp_iterator ii) throw() { return ii->second; }
200 const_avp_iterator avp_begin() const throw() { return a_avps.begin(); }
201 const_avp_iterator avp_end() const throw() { return a_avps.end(); }
202 static const Avp* avp(const_avp_iterator ii) throw() { return ii->second; }
205 bool flagsOK() const throw(); // flags coherence regarding dictionary. Only must be called when AVP is identified at the dictionary.
206 int addChild(Avp *avp) throw(anna::RuntimeException) { assertFormat("Grouped"); return addChild(a_avps, a_insertionPositionForChilds, avp); }
207 bool hasChildren() throw() { return a_avps.size() != 0; }
209 static bool contain(const_avp_iterator begin, const_avp_iterator end, const Avp *parent) throw() { return true; }
213 Fix grouped content regarding dictionary avp positions.
214 Avp could remain invalid because of possible fixed/mandatory avps.
215 This is useful to give flexibility to the application during message construction before encoding or representing the data.
216 Is not recommended to fix a recently decoded message because possible validation problems will be hidden.
221 Validates an Avp regarding dictionary rules like enumerated range, flags coherence, mandatory and fixed types, cardinality qualifiers, etc.
223 @param parent Parent description. Internally used for alarms, tracing and Failed-AVP construction
224 @param answer Answer could be modified with any validation problem during requests validation
226 @return Boolean indicating validation result
228 bool valid(const anna::diameter::codec::parent_t & parent, Message *answer) const throw(anna::RuntimeException);
231 Decodes buffer provided over class content. If an error ocurred, decoding will stop launching exception (fatal error) or a warning trace (perhaps the achieved
232 message is valid against all odds then validation will go on). In case that validation is enabled (codec::Engine::ValidationMode) an exception will be launched
233 depending on validation depth (codec::Engine::ValidationDepth).
235 @param db Buffer data block processed
236 @param parent Parent description. Internally used for alarms, tracing and Failed-AVP construction
237 @param answer Answer built for request decoding/validation
239 void decode(const anna::DataBlock &db, const anna::diameter::codec::parent_t & parent, Message *answer) throw(anna::RuntimeException);
242 /////////////////////////////////////////////
243 // Inherit format-specific virtual methods //
244 /////////////////////////////////////////////
247 * Initializes Avp class information.
248 * Default implementation supports all anna::diameter formats (including derived ones).
249 * Diameter basic formats are managed at #initialize, which will invoke this method at the end.
251 virtual void initializeByFormat() throw() {};
254 * Gets avp data-part length.
255 * Default implementation supports all anna::diameter formats (including derived ones).
256 * Diameter basic formats are managed at #initialize, which will invoke this method at the end.
258 * @param stackFormat Stack avp format in which data extraction is based.
260 * @return Avp data-part size.
262 virtual U24 getLengthByFormat(const anna::diameter::stack::Format *stackFormat) const throw() { return 0; };
265 Gets data or hexadecimal data depending on avp format, for xml creating
266 Default implementation supports all anna::diameter formats (including derived ones).
267 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
269 \param isHex Hexadecimal/Natural data when apply.
270 \param stackFormat Stack avp format in which data extraction is based.
271 \return xml data representation
273 virtual std::string getXMLdataByFormat(bool & isHex, const anna::diameter::stack::Format *stackFormat) const throw() { return ""; };
276 Interpret xml data in order to dump over the class content.
277 Default implementation supports all anna::diameter formats (including derived ones).
278 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
280 \param data Avp data attribute
281 \param hexData Avp hex-data attribute
282 \param stackFormat Stack avp format in which data extraction is based.
284 virtual void fromXMLByFormat(const anna::xml::Attribute* data, const anna::xml::Attribute* hexData, const anna::diameter::stack::Format *stackFormat) throw(anna::RuntimeException) {};
288 Encodes buffer with the class content.
289 Default implementation supports all anna::diameter formats (including derived ones).
290 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
292 @param dataPart Data-part begin pointer
293 @param stackFormat Stack avp format in which data extraction is based.
295 virtual void codeByFormat(char* dataPart, const anna::diameter::stack::Format *stackFormat) const throw(anna::RuntimeException) {};
299 Decodes Avp data part.
300 Default implementation supports all anna::diameter formats (including derived ones).
301 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
303 @param buffer Avp data part start pointer
304 @param size Avp data part size
305 @param stackFormat Stack avp format in which data extraction is based.
307 virtual void decodeDataPartByFormat(const char * buffer, int size, const anna::diameter::stack::Format *stackFormat) throw(anna::RuntimeException) {};
310 Reserves memory for data part depending on avp format for the identifier provided.
311 Default implementation supports all anna::diameter formats (including derived ones).
312 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
314 @param stackFormat Stack avp format in which data extraction is based.
316 virtual void allocationByFormat(const anna::diameter::stack::Format *stackFormat) throw() {};
319 * Clears Avp data-part format containers.
321 virtual void clearByFormat() throw() {};
328 mutable Engine *a_engine;
330 /** Codec Engine getter: avoids have to create base engine when using its child */
331 virtual Engine * getEngine() const throw(anna::RuntimeException);
334 * Initializes Avp class information.
336 void initialize() throw();
339 * Assert format regarding dictionary
341 void assertFormat(const std::string &name) const throw(anna::RuntimeException);
344 * Gets avp total length based on internal data part and header configuration.
345 * Padding octets are not included, only header and data part length.
346 * The only format which always have total length equal to sum of all its parts is Grouped,
347 * because of the 4-multiple nature of its data part length.
349 U24 getLength() const throw();
352 Gets data or hexadecimal data depending on avp format, for xml creating
354 \param isHex Hexadecimal/Natural data when apply.
355 \param stackFormat Stack avp format in which data extraction is based.
356 \return xml data representation
358 std::string getXMLdata(bool & isHex, const anna::diameter::stack::Format *stackFormat) const throw();
362 Decodes Avp data part.
364 @param buffer Avp data part start pointer
365 @param size Avp data part size
366 @param parent Parent description. Internally used for alarms, tracing and Failed-AVP construction
367 @param answer Answer built for request decoding/validation
369 void decodeDataPart(const char * buffer, int size, const anna::diameter::codec::parent_t & parent, Message *answer) throw(anna::RuntimeException);
375 * Default constructor
376 * @param engine Codec engine used
378 Avp(Engine *engine = NULL);
381 * Identified constructor
382 * @param id Avp identifier as pair (code,vendor-id).
383 * @param engine Codec engine used
385 Avp(AvpId id, Engine *engine = NULL);
389 * Sets the codec engine
391 * Once assigned (here or at constructor), this method SHALL NOT be used anymore.
392 * Also, the associated dictionary SHOULD NOT BE CHANGED through the engine,
393 * unless you know what are you doing. If you want to reconfigure the engine,
394 * first #clear the avp and then you could reuse the same object with
395 * different configurations (execution contexts).
397 * Setting a new different engine with different stack, even same engine where the
398 * stack has been dynamically changed, could cause a bad behaviour depending on the
399 * changes: in general, if the dictionary grows, nothing bad will happen, but if
400 * you remove or modified some elements which were processed with a certain format,
401 * will be interpreted as 'unknown' with the new dictionary, and then some problems
402 * may occur. If you add elements (vendors, avps, messages) is not a problem.
404 void setEngine(Engine *engine) throw();
408 static const int HeaderLengthVactive;
409 static const int HeaderLengthVinactive;
418 // (encry)P(tion) (end to end encryption)
419 // r(eserved) - these flag bits are reserved for future use, and
420 // MUST be set to zero, and ignored by the receiver.
421 static const U8 VBitMask;
422 static const U8 MBitMask;
423 static const U8 PBitMask;
434 * Clears and initializes Avp class information.
435 * Application should clear auxiliary avp objects before setting data in a new context.
437 void clear() throw(anna::RuntimeException);
441 Sets the avp identifier and clear the former content.
442 Internally reserves memory for data part depending on avp format for the identifier provided.
443 This must be called at first place because Avp class content is cleared when identifier is configured.
444 Generic AVP assignment have no sense and will be ignored.
446 @param id Avp identifier as pair (code,vendor-id).
448 void setId(AvpId id) throw(anna::RuntimeException);
451 Same as #setId but providing dictionary logical name for Avp searched
453 void setId(const char *name) throw(anna::RuntimeException);
456 Sets/unsets M bit activation.
457 Application should not have to use this because dictionary information is used in order to configure flags when Avp identifier is stored.
458 Anyway, could be useful when build unknown-type avps.
460 The 'M' Bit, known as the Mandatory bit, indicates whether support of the AVP is required. If an AVP with the 'M' bit set is received by
461 a Diameter client, server, proxy, or translation agent and either the AVP or its value is unrecognized, the message MUST be rejected.
462 Diameter Relay and redirect agents MUST NOT reject messages with unrecognized AVPs.
464 @param activate Activates/deactivates the bit. True by default.
466 void setMandatoryBit(bool activate = true) throw() { if(activate) a_flags |= MBitMask; else a_flags &= (~MBitMask); }
469 Sets/unsets P bit activation.
470 Application should not have to use this because dictionary information is used in order to configure flags when Avp identifier is stored.
471 Anyway, could be useful when build unknown-type avps.
473 @param activate Activates/deactivates the bit. True by default.
475 void setEncryptionBit(bool activate = true) throw() { if(activate) a_flags |= PBitMask; else a_flags &= (~PBitMask); }
479 Adds an avp child providing its identifier and reserve internal memory it.
480 An exception is launched is the Avp over which we add the new avp, is not a grouped avp.
482 @param id Avp identifier as pair (code,vendor-id).
484 @return Pointer to the new created avp.
486 Avp * addAvp(AvpId id) throw(anna::RuntimeException) { assertFormat("Grouped"); return addAvp(a_avps, a_insertionPositionForChilds, id, getEngine()); }
490 Same as #addAvp but providing dictionary logical name for Avp searched
492 Avp * addAvp(const char *name) throw(anna::RuntimeException);
495 Adds an avp child providing a persistent pointer (must be maintained by application).
496 An exception is launched is the Avp over which we add the new avp, is not a grouped avp.
497 It is not allowed to add an avp with no codec engine configured, neither if the engine
500 @param avp Avp external pointer. If NULL provided, nothing is done and NULL returned.
501 Also NULL returned for bad engine configuration.
503 @return Pointer to the added avp (again).
505 Avp * addAvp(Avp * avp) throw(anna::RuntimeException);
509 /** Access content for OctetString Avp in order to set data part */
510 OctetString * getOctetString() throw(anna::RuntimeException) { assertFormat("OctetString"); return a_OctetString; }
511 /** Access content for Integer32 Avp in order to set data part */
512 Integer32 * getInteger32() throw(anna::RuntimeException) { assertFormat("Integer32"); return a_Integer32; }
513 /** Access content for Integer64 Avp in order to set data part */
514 Integer64 * getInteger64() throw(anna::RuntimeException) { assertFormat("Integer64"); return a_Integer64; }
515 /** Access content for Unsigned32 Avp in order to set data part */
516 Unsigned32 * getUnsigned32() throw(anna::RuntimeException) { assertFormat("Unsigned32"); return a_Unsigned32; }
517 /** Access content for Unsigned64 Avp in order to set data part */
518 Unsigned64 * getUnsigned64() throw(anna::RuntimeException) { assertFormat("Unsigned64"); return a_Unsigned64; }
519 /** Access content for Float32 Avp in order to set data part */
520 Float32 * getFloat32() throw(anna::RuntimeException) { assertFormat("Float32"); return a_Float32; }
521 /** Access content for Float64 Avp in order to set data part */
522 Float64 * getFloat64() throw(anna::RuntimeException) { assertFormat("Float64"); return a_Float64; }
523 /** Access content for Address Avp in order to set data part */
524 Address * getAddress() throw(anna::RuntimeException) { assertFormat("Address"); return a_Address; }
525 /** Access content for Time Avp in order to set data part */
526 Time * getTime() throw(anna::RuntimeException) { assertFormat("Time"); return a_Time; }
527 /** Access content for UTF8String Avp in order to set data part */
528 UTF8String * getUTF8String() throw(anna::RuntimeException) { assertFormat("UTF8String"); return a_UTF8String; }
529 /** Access content for DiameterIdentity Avp in order to set data part */
530 DiameterIdentity * getDiameterIdentity() throw(anna::RuntimeException) { assertFormat("DiameterIdentity"); return a_DiameterIdentity; }
531 /** Access content for DiameterURI Avp in order to set data part */
532 DiameterURI * getDiameterURI() throw(anna::RuntimeException) { assertFormat("DiameterURI"); return a_DiameterURI; }
533 /** Access content for Enumerated Avp in order to set data part */
534 Enumerated * getEnumerated() throw(anna::RuntimeException) { assertFormat("Enumerated"); return a_Enumerated; }
535 /** Access content for IPFilterRule Avp in order to set data part */
536 IPFilterRule * getIPFilterRule() throw(anna::RuntimeException) { assertFormat("IPFilterRule"); return a_IPFilterRule; }
537 /** Access content for QoSFilterRule Avp in order to set data part */
538 QoSFilterRule * getQoSFilterRule() throw(anna::RuntimeException) { assertFormat("QoSFilterRule"); return a_QoSFilterRule; }
539 /** Access content for Unknown Avp in order to set data part */
540 Unknown * getUnknown() throw(anna::RuntimeException) { assertFormat("Unknown"); return a_Unknown; }
544 Removes an Avp within grouped type (first level) and free resources.
546 @param id Avp identifier (pair code + vendor-id).
547 @param ocurrence Order of appearance for the searched avp. Zero value means remove all avps with provided identifier at first level (no recursiveness would be allowed in the API in order to avoid unexpected behaviour).
548 Negative values could be used to reverse access positions: i.e. -1 is the last ocurrence, -2 is the second to last (penultimate), etc.
550 @return Returns true if something was removed. False in other cases (including i.e. when this Avp is empty or is not a grouped avp).
552 bool removeAvp(AvpId id, int ocurrence = 1) throw(anna::RuntimeException) { assertFormat("Grouped"); return removeAvp(a_avps, (find_container&)a_finds, id, ocurrence, getEngine()); }
556 Same as #removeAvp but providing dictionary logical name for Avp searched
558 bool removeAvp(const char *name, int ocurrence = 1) throw(anna::RuntimeException);
563 Gets Avp identifier as pair (code, vendor-id).
565 const AvpId & getId() const throw() { return a_id; }
570 int getVendorId() const throw() { return a_id.second; }
573 Gets stack avp (dictionary avp reference).
575 const anna::diameter::stack::Avp *getStackAvp() const throw(anna::RuntimeException) { return getStackAvp(a_id, getEngine()); }
577 /** Returns V bit activation state */
578 bool vendorBit() const throw() { return ((a_flags & VBitMask) != 0x00); }
580 /** Returns M bit activation state */
581 bool mandatoryBit() const throw() { return ((a_flags & MBitMask) != 0x00); }
583 /** Returns P bit activation state */
584 bool encryptionBit() const throw() { return ((a_flags & PBitMask) != 0x00); }
587 /** Access content for OctetString Avp */
588 const OctetString * getOctetString() const throw(anna::RuntimeException) { assertFormat("OctetString"); return a_OctetString; }
589 /** Access content for Integer32 Avp */
590 const Integer32 * getInteger32() const throw(anna::RuntimeException) { assertFormat("Integer32"); return a_Integer32; }
591 /** Access content for Integer64 Avp */
592 const Integer64 * getInteger64() const throw(anna::RuntimeException) { assertFormat("Integer64"); return a_Integer64; }
593 /** Access content for Unsigned32 Avp */
594 const Unsigned32 * getUnsigned32() const throw(anna::RuntimeException) { assertFormat("Unsigned32"); return a_Unsigned32; }
595 /** Access content for Unsigned64 Avp */
596 const Unsigned64 * getUnsigned64() const throw(anna::RuntimeException) { assertFormat("Unsigned64"); return a_Unsigned64; }
597 /** Access content for Float32 Avp */
598 const Float32 * getFloat32() const throw(anna::RuntimeException) { assertFormat("Float32"); return a_Float32; }
599 /** Access content for Float64 Avp */
600 const Float64 * getFloat64() const throw(anna::RuntimeException) { assertFormat("Float64"); return a_Float64; }
603 Access content for Grouped Avp. Exception mode allows different combinations like cascade access:
607 message->getAvp(anna::diameter::helpers::base::AVP__Multiple_Services_Credit_Control, anna::Exception::Mode::Throw)
608 ->getAvp(anna::diameter::helpers::base::AVP__Rating_Group, anna::Exception::Mode::Throw);
610 catch(anna::RuntimeException) {;}
616 const Avp *mscc = message->getAvp(anna::diameter::helpers::base::AVP__Multiple_Services_Credit_Control);
618 if (mscc) rg = mscc->getAvp(anna::diameter::helpers::base::AVP__Rating_Group);
621 Replacing procedures becomes easy because an Avp can be searched and its pointer reconfigured by mean #setId and data part setters.
622 Deleting procedures must use #removeAvp.
623 Access is internally cached to speed up the search operations. This cache is reset after calling #fix or #removeAvp methods.
625 @param id Avp identifier (pair code + vendor-id).
626 @param ocurrence Order of appearance for the searched avp. Zero position is rejected, but negative values could be used to reverse
627 access positions: i.e. -1 is the last ocurrence, -2 is the second to last (penultimate), etc.
628 @param emode Excepcion mode handling when avp is not found: Ignore (no action is taken but debug trace), Throw (excepcion launched, by default), Trace (trace warning).
629 If avp format is not grouped, always exception will be launched and no matter what mode is provided. It would be a development
630 error and must be solved.
632 const Avp* getAvp(AvpId id, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) const throw(anna::RuntimeException) {
633 return _getAvp(id, ocurrence, emode);
636 Avp* getAvp(AvpId id, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException) {
637 return const_cast<Avp*>(_getAvp(id, ocurrence, emode));
641 Same as #getAvp but providing dictionary logical name for Avp searched
643 const Avp* getAvp(const char *name, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) const throw(anna::RuntimeException) {
644 return _getAvp(name, ocurrence, emode);
647 Avp* getAvp(const char *name, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException) {
648 return const_cast<Avp*>(_getAvp(name, ocurrence, emode));
653 /** Access content for Address Avp */
654 const Address * getAddress() const throw(anna::RuntimeException) { assertFormat("Address"); return a_Address; }
655 /** Access content for Time Avp */
656 const Time * getTime() const throw(anna::RuntimeException) { assertFormat("Time"); return a_Time; }
657 /** Access content for UTF8String Avp */
658 const UTF8String * getUTF8String() const throw(anna::RuntimeException) { assertFormat("UTF8String"); return a_UTF8String; }
659 /** Access content for DiameterIdentity Avp */
660 const DiameterIdentity * getDiameterIdentity() const throw(anna::RuntimeException) { assertFormat("DiameterIdentity"); return a_DiameterIdentity; }
661 /** Access content for DiameterURI Avp */
662 const DiameterURI * getDiameterURI() const throw(anna::RuntimeException) { assertFormat("DiameterURI"); return a_DiameterURI; }
663 /** Access content for Enumerated Avp */
664 const Enumerated * getEnumerated() const throw(anna::RuntimeException) { assertFormat("Enumerated"); return a_Enumerated; }
665 /** Access content for IPFilterRule Avp */
666 const IPFilterRule * getIPFilterRule() const throw(anna::RuntimeException) { assertFormat("IPFilterRule"); return a_IPFilterRule; }
667 /** Access content for QoSFilterRule Avp */
668 const QoSFilterRule * getQoSFilterRule() const throw(anna::RuntimeException) { assertFormat("QoSFilterRule"); return a_QoSFilterRule; }
669 /** Access content for Unknown Avp */
670 const Unknown * getUnknown() const throw(anna::RuntimeException) { assertFormat("Unknown"); return a_Unknown; }
674 Decodes buffer provided over class content. If an error ocurred, decoding will stop launching exception (fatal error) or a warning trace (perhaps the achieved
675 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
676 depending on validation depth (codec::Engine::ValidationDepth).
678 Useful as serialization procedure with #code
680 @param db Buffer data block processed
682 void decode(const anna::DataBlock &db) throw(anna::RuntimeException);
686 Interpret xml data in order to dump over the class content.
688 \param avpNode Avp root node
690 void fromXML(const anna::xml::Node* avpNode) throw(anna::RuntimeException);
694 Encodes buffer with the class content. This method is internally used to encode diameter messages, but is declared as public, to allow
695 its use as serialization procedure. Then, it's assumed that this Avp is valid (validation shall be applied as part of a whole diameter
696 message but nothing will be verified now).
698 * @param buffer Raw data to be encoded (shall be externally allocated)
699 * @param size Size of raw data to be encoded
701 void code(char* buffer, int &size) const throw(anna::RuntimeException);
707 Class xml representation
708 \param parent Parent XML node on which hold this instance information.
709 \return XML document with relevant information for this instance.
711 anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
714 Class xml string representation
715 \return XML string representation with relevant information for this instance.
717 std::string asXMLString() const throw();
720 Comparison operator by mean serialization
722 @param a1 Instance 1 for Avp class
723 @param a2 Instance 2 for Avp class
725 @return Comparison result
727 friend bool operator == (const Avp & a1, const Avp & a2) throw() { return (a1.asXMLString() == a2.asXMLString()); }
730 Match a regular expression (string pattern) regarding xml string serialization for this avp.
731 This works same as #Message::isLike
733 @param pattern Pattern to match
735 \return Returns the match result
737 bool isLike(const std::string &pattern) const throw();
740 Counts the number of ocurrences of Avps (first level) with the identifier provided
742 @param id Avp identifier (pair code + vendor-id).
744 int countAvp(AvpId id) const throw(anna::RuntimeException) { assertFormat("Grouped"); return countAvp(a_avps, id); }
747 Same as #countAvp but providing dictionary logical name for Avp searched
749 int countAvp(const char *name) const throw(anna::RuntimeException);
752 Counts the number of children within a grouped avp
754 @param id Avp identifier (pair code + vendor-id).
756 int countChilds() const throw(anna::RuntimeException) { assertFormat("Grouped"); return countChilds(a_avps); }
759 The 'M' Bit, known as the Mandatory bit, indicates whether support of the AVP is required. If an AVP with the 'M' bit set is received by
760 a Diameter client, server, proxy, or translation agent and either the AVP or its value is unrecognized, the message MUST be rejected.
761 Diameter Relay and redirect agents MUST NOT reject messages with unrecognized AVPs.
763 Default implementation launch alarm and counter indicating the anomaly but don't launch exception (traces at warning level).
764 Relay and Redirect agents could reimplement this method to avoid oam management (another way is avoid alarm/counter registration on
765 these applications). Result-Code DIAMETER_AVP_UNSUPPORTED will be stored for possible answer message.
767 virtual void unknownAvpWithMandatoryBit() const throw(anna::RuntimeException);
770 friend class Message;