1 // ANNA - Anna is Not Nothingness Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // http://redmine.teslayout.com/projects/anna-suite
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
37 #ifndef anna_diameter_codec_Avp_hpp
38 #define anna_diameter_codec_Avp_hpp
42 #include <anna/config/defines.hpp>
43 #include <anna/diameter/defines.hpp>
44 #include <anna/diameter/codec/basetypes/basetypes.hpp>
45 #include <anna/diameter/stack/Avp.hpp>
47 #include <anna/core/RuntimeException.hpp>
53 //------------------------------------------------------------------------------
54 //---------------------------------------------------------------------- #define
55 //------------------------------------------------------------------------------
91 class DiameterIdentity;
104 typedef std::map < int /* key: insertion pos */, Avp* > avp_container;
105 typedef avp_container::iterator avp_iterator;
106 typedef avp_container::const_iterator const_avp_iterator;
108 // Cache avp-find system
109 typedef std::pair < AvpId, unsigned int /* position */ > find_key;
110 typedef std::map<find_key, Avp*> find_container;
111 typedef std::map<find_key, Avp*>::iterator find_iterator;
114 using namespace basetypes;
117 * Diameter avp generic container
119 * RFC 3588 Diameter Based Protocol September 2003
122 * The fields in the AVP header MUST be sent in network byte order. The
123 * format of the header is:
126 * 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
127 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
129 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
130 * | AVP Flags | AVP Length |
131 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
132 * | Vendor-ID (opt) |
133 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
138 * AVP Flags: V (vendor-specific), M (mandatory), P (end to end encryption)
144 * The AVP Length field is three octets, and indicates the number of
145 * octets in this AVP including the AVP Code, AVP Length, AVP Flags,
146 * Vendor-ID field (if present) and the AVP data.
148 * Vendor-ID: IANA "SMI Network Management Private Enterprise Codes" [ASSIGNNO]
149 * http://www.iana.org/assignments/enterprise-numbers
154 AvpId a_id; // code and vendor-code
158 int a_insertionPositionForChilds; // used at grouped type
161 // --- Developer notes ---
162 // 'AVP Length' does not include posible data padding. Thanks to this, 'Data Length'
163 // is the difference between 'AVP Length' and sum of code, length, flags and
164 // optionally the vendor-ID (all of them are 32-bit boundary), that is to say:
165 // 8 or 12 (vendor-specific avps).
167 // Grouped avps 'AVP Length' includes own headers plus the total length of all
168 // underlying AVPs, including their headers and padding, then 'AVP Length' is
169 // always multiple of 4 (library will check this), and smae for 'Data Length'
170 // which is an 'whole avp Length with padding' itself.
173 OctetString *a_OctetString;
174 Integer32 *a_Integer32;
175 Integer64 *a_Integer64;
176 Unsigned32 *a_Unsigned32;
177 Unsigned64 *a_Unsigned64;
180 avp_container a_avps; // Grouped
183 UTF8String *a_UTF8String;
184 DiameterIdentity *a_DiameterIdentity;
185 DiameterURI *a_DiameterURI;
186 Enumerated *a_Enumerated;
187 IPFilterRule *a_IPFilterRule;
188 QoSFilterRule *a_QoSFilterRule;
192 find_container a_finds; // fast access for grouped and message first-level avps
195 // 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
196 // 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
197 // instantiating the class. Friend functions are functions which are not in the class and you want to give them access to private members
200 // Common (also for Message class)
201 static avp_iterator avp_find(avp_container &avps, AvpId id, unsigned int position) throw();
202 static const_avp_iterator avp_find(const avp_container &avps, AvpId id, unsigned int position) throw() {
203 return (const_avp_iterator)avp_find((avp_container &)avps, id, position);
205 static Avp * addAvp(avp_container &avps, int &insertionPositionForChilds, AvpId id, Engine *engine) throw();
206 static bool removeAvp(avp_container &avps, find_container &finds, AvpId id, int ocurrence, Engine *engine) throw();
207 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();
208 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
209 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);
210 static int countAvp(const avp_container &avps, AvpId id) throw();
211 static const Avp* firstAvp(const avp_container &avps, AvpId id) throw();
212 static int countChilds(const avp_container &avps) throw();
213 static int addChild(avp_container &avps, int &insertionPositionForChilds, Avp *avp) throw() {
216 avps[insertionPositionForChilds++] = avp;
217 return insertionPositionForChilds;
219 static const anna::diameter::stack::Avp *getStackAvp(AvpId id, Engine *engine) throw();
220 const Avp* _getAvp(const char *name, int ocurrence, anna::Exception::Mode::_v emode) const throw(anna::RuntimeException);
221 const Avp* _getAvp(AvpId id, int ocurrence, anna::Exception::Mode::_v emode) const throw(anna::RuntimeException);
224 avp_iterator avp_begin() throw() { return a_avps.begin(); }
225 avp_iterator avp_end() throw() { return a_avps.end(); }
226 static Avp* avp(avp_iterator ii) throw() { return ii->second; }
227 const_avp_iterator avp_begin() const throw() { return a_avps.begin(); }
228 const_avp_iterator avp_end() const throw() { return a_avps.end(); }
229 static const Avp* avp(const_avp_iterator ii) throw() { return ii->second; }
232 bool flagsOK() const throw(); // flags coherence regarding dictionary. Only must be called when AVP is identified at the dictionary.
233 int addChild(Avp *avp) throw(anna::RuntimeException) { assertFormat("Grouped"); return addChild(a_avps, a_insertionPositionForChilds, avp); }
234 bool hasChildren() throw() { return a_avps.size() != 0; }
236 static bool contain(const_avp_iterator begin, const_avp_iterator end, const Avp *parent) throw() { return true; }
240 Fix grouped content regarding dictionary avp positions.
241 Avp could remain invalid because of possible fixed/mandatory avps.
242 This is useful to give flexibility to the application during message construction before encoding or representing the data.
243 Is not recommended to fix a recently decoded message because possible validation problems will be hidden.
248 Validates an Avp regarding dictionary rules like enumerated range, flags coherence, mandatory and fixed types, cardinality qualifiers, etc.
250 @param parentDescription Parent description. Internally used for alarms and tracing
251 @param answer Answer could be modified with any validation problem during requests validation
253 @return Boolean indicating validation result
255 bool valid(const std::string & parentDescription, Message *answer) const throw(anna::RuntimeException);
258 Decodes buffer provided over class content. If an error ocurred, decoding will stop launching exception (fatal error) or a warning trace (perhaps the achieved
259 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
260 depending on validation depth (codec::Engine::ValidationDepth).
262 @param db Buffer data block processed
263 @param answer Answer built for request decoding/validation
265 void decode(const anna::DataBlock &db, Message *answer) throw(anna::RuntimeException);
268 /////////////////////////////////////////////
269 // Inherit format-specific virtual methods //
270 /////////////////////////////////////////////
273 * Initializes Avp class information.
274 * Default implementation supports all anna::diameter formats (including derived ones).
275 * Diameter basic formats are managed at #initialize, which will invoke this method at the end.
277 virtual void initializeByFormat() throw() {};
280 * Gets avp data-part length.
281 * Default implementation supports all anna::diameter formats (including derived ones).
282 * Diameter basic formats are managed at #initialize, which will invoke this method at the end.
284 * @param stackFormat Stack avp format in which data extraction is based.
286 * @return Avp data-part size.
288 virtual U24 getLengthByFormat(const anna::diameter::stack::Format *stackFormat) const throw() { return 0; };
291 Gets data or hexadecimal data depending on avp format, for xml creating
292 Default implementation supports all anna::diameter formats (including derived ones).
293 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
295 \param isHex Hexadecimal/Natural data when apply.
296 \param stackFormat Stack avp format in which data extraction is based.
297 \return xml data representation
299 virtual std::string getXMLdataByFormat(bool & isHex, const anna::diameter::stack::Format *stackFormat) const throw() { return ""; };
302 Interpret xml data in order to dump over the class content.
303 Default implementation supports all anna::diameter formats (including derived ones).
304 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
306 \param data Avp data attribute
307 \param hexData Avp hex-data attribute
308 \param stackFormat Stack avp format in which data extraction is based.
310 virtual void fromXMLByFormat(const anna::xml::Attribute* data, const anna::xml::Attribute* hexData, const anna::diameter::stack::Format *stackFormat) throw(anna::RuntimeException) {};
314 Encodes buffer with the class content.
315 Default implementation supports all anna::diameter formats (including derived ones).
316 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
318 @param dataPart Data-part begin pointer
319 @param stackFormat Stack avp format in which data extraction is based.
321 virtual void codeByFormat(char* dataPart, const anna::diameter::stack::Format *stackFormat) const throw(anna::RuntimeException) {};
325 Decodes Avp data part.
326 Default implementation supports all anna::diameter formats (including derived ones).
327 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
329 @param buffer Avp data part start pointer
330 @param size Avp data part size
331 @param stackFormat Stack avp format in which data extraction is based.
333 virtual void decodeDataPartByFormat(const char * buffer, int size, const anna::diameter::stack::Format *stackFormat) throw(anna::RuntimeException) {};
336 Reserves memory for data part depending on avp format for the identifier provided.
337 Default implementation supports all anna::diameter formats (including derived ones).
338 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
340 @param stackFormat Stack avp format in which data extraction is based.
342 virtual void allocationByFormat(const anna::diameter::stack::Format *stackFormat) throw() {};
345 * Clears Avp data-part format containers.
347 virtual void clearByFormat() throw() {};
354 mutable Engine *a_engine;
356 /** Codec Engine getter: avoids have to create base engine when using its child */
357 virtual Engine * getEngine() const throw(anna::RuntimeException);
360 * Initializes Avp class information.
362 void initialize() throw();
365 * Assert format regarding dictionary
367 void assertFormat(const std::string &name) const throw(anna::RuntimeException);
370 * Gets avp total length based on internal data part and header configuration.
371 * Padding octets are not included, only header and data part length.
372 * The only format which always have total length equal to sum of all its parts is Grouped,
373 * because of the 4-multiple nature of its data part length.
375 U24 getLength() const throw();
378 Gets data or hexadecimal data depending on avp format, for xml creating
380 \param isHex Hexadecimal/Natural data when apply.
381 \param stackFormat Stack avp format in which data extraction is based.
382 \return xml data representation
384 std::string getXMLdata(bool & isHex, const anna::diameter::stack::Format *stackFormat) const throw();
387 Interpret xml data in order to dump over the class content.
389 \param avpNode Avp root node
391 void fromXML(const anna::xml::Node* avpNode) throw(anna::RuntimeException);
395 Encodes buffer with the class content.
397 * @param buffer Raw data to be encoded
398 * @param size Size of raw data to be encoded
400 void code(char* buffer, int &size) const throw(anna::RuntimeException);
404 Decodes Avp data part.
406 @param buffer Avp data part start pointer
407 @param size Avp data part size
408 @param answer Answer built for request decoding/validation
410 void decodeDataPart(const char * buffer, int size, Message *answer) throw(anna::RuntimeException);
416 * Default constructor
421 * Identified constructor
422 * @param id Avp identifier as pair (code,vendor-id).
428 static const int HeaderLengthVactive;
429 static const int HeaderLengthVinactive;
438 // (encry)P(tion) (end to end encryption)
439 // r(eserved) - these flag bits are reserved for future use, and
440 // MUST be set to zero, and ignored by the receiver.
441 static const U8 VBitMask;
442 static const U8 MBitMask;
443 static const U8 PBitMask;
454 * Clears and initializes Avp class information.
455 * Application should clear auxiliary avp objects before setting data in a new context.
457 void clear() throw(anna::RuntimeException);
461 Sets the avp identifier and clear the former content.
462 Internally reserves memory for data part depending on avp format for the identifier provided.
463 This must be called at first place because Avp class content is cleared when identifier is configured.
464 Generic AVP assignment have no sense and will be ignored.
466 @param id Avp identifier as pair (code,vendor-id).
468 void setId(AvpId id) throw(anna::RuntimeException);
471 Same as #setId but providing dictionary logical name for Avp searched
473 void setId(const char *name) throw(anna::RuntimeException);
476 Sets/unsets M bit activation.
477 Application should not have to use this because dictionary information is used in order to configure flags when Avp identifier is stored.
478 Anyway, could be useful when build unknown-type avps.
480 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
481 a Diameter client, server, proxy, or translation agent and either the AVP or its value is unrecognized, the message MUST be rejected.
482 Diameter Relay and redirect agents MUST NOT reject messages with unrecognized AVPs.
484 @param activate Activates/deactivates the bit. True by default.
486 void setMandatoryBit(bool activate = true) throw() { if(activate) a_flags |= MBitMask; else a_flags &= (~MBitMask); }
489 Sets/unsets P bit activation.
490 Application should not have to use this because dictionary information is used in order to configure flags when Avp identifier is stored.
491 Anyway, could be useful when build unknown-type avps.
493 @param activate Activates/deactivates the bit. True by default.
495 void setEncryptionBit(bool activate = true) throw() { if(activate) a_flags |= PBitMask; else a_flags &= (~PBitMask); }
499 Adds an avp child providing its identifier and reserve internal memory it.
500 An exception is launched is the Avp is not a grouped avp.
502 @param id Avp identifier as pair (code,vendor-id).
504 @return Pointer to the new created avp.
506 Avp * addAvp(AvpId id) throw(anna::RuntimeException) { assertFormat("Grouped"); return addAvp(a_avps, a_insertionPositionForChilds, id, getEngine()); }
510 Same as #addAvp but providing dictionary logical name for Avp searched
512 Avp * addAvp(const char *name) throw(anna::RuntimeException);
516 Adds an avp child providing a persistent pointer (must be maintained by application).
517 An exception is launched is the Avp is not a grouped avp.
519 @param avp Avp external pointer. If NULL provided, nothing is done and NULL returned.
521 @return Pointer to the added avp (again).
523 Avp * addAvp(Avp * avp) throw(anna::RuntimeException) { if(!avp) return NULL; addChild(avp); return avp; }
526 /** Access content for OctetString Avp in order to set data part */
527 OctetString * getOctetString() throw(anna::RuntimeException) { assertFormat("OctetString"); return a_OctetString; }
528 /** Access content for Integer32 Avp in order to set data part */
529 Integer32 * getInteger32() throw(anna::RuntimeException) { assertFormat("Integer32"); return a_Integer32; }
530 /** Access content for Integer64 Avp in order to set data part */
531 Integer64 * getInteger64() throw(anna::RuntimeException) { assertFormat("Integer64"); return a_Integer64; }
532 /** Access content for Unsigned32 Avp in order to set data part */
533 Unsigned32 * getUnsigned32() throw(anna::RuntimeException) { assertFormat("Unsigned32"); return a_Unsigned32; }
534 /** Access content for Unsigned64 Avp in order to set data part */
535 Unsigned64 * getUnsigned64() throw(anna::RuntimeException) { assertFormat("Unsigned64"); return a_Unsigned64; }
536 /** Access content for Float32 Avp in order to set data part */
537 Float32 * getFloat32() throw(anna::RuntimeException) { assertFormat("Float32"); return a_Float32; }
538 /** Access content for Float64 Avp in order to set data part */
539 Float64 * getFloat64() throw(anna::RuntimeException) { assertFormat("Float64"); return a_Float64; }
540 /** Access content for Address Avp in order to set data part */
541 Address * getAddress() throw(anna::RuntimeException) { assertFormat("Address"); return a_Address; }
542 /** Access content for Time Avp in order to set data part */
543 Time * getTime() throw(anna::RuntimeException) { assertFormat("Time"); return a_Time; }
544 /** Access content for UTF8String Avp in order to set data part */
545 UTF8String * getUTF8String() throw(anna::RuntimeException) { assertFormat("UTF8String"); return a_UTF8String; }
546 /** Access content for DiameterIdentity Avp in order to set data part */
547 DiameterIdentity * getDiameterIdentity() throw(anna::RuntimeException) { assertFormat("DiameterIdentity"); return a_DiameterIdentity; }
548 /** Access content for DiameterURI Avp in order to set data part */
549 DiameterURI * getDiameterURI() throw(anna::RuntimeException) { assertFormat("DiameterURI"); return a_DiameterURI; }
550 /** Access content for Enumerated Avp in order to set data part */
551 Enumerated * getEnumerated() throw(anna::RuntimeException) { assertFormat("Enumerated"); return a_Enumerated; }
552 /** Access content for IPFilterRule Avp in order to set data part */
553 IPFilterRule * getIPFilterRule() throw(anna::RuntimeException) { assertFormat("IPFilterRule"); return a_IPFilterRule; }
554 /** Access content for QoSFilterRule Avp in order to set data part */
555 QoSFilterRule * getQoSFilterRule() throw(anna::RuntimeException) { assertFormat("QoSFilterRule"); return a_QoSFilterRule; }
556 /** Access content for Unknown Avp in order to set data part */
557 Unknown * getUnknown() throw(anna::RuntimeException) { assertFormat("Unknown"); return a_Unknown; }
561 Removes an Avp within grouped type (first level) and free resources.
563 @param id Avp identifier (pair code + vendor-id).
564 @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).
565 Negative values could be used to reverse access positions: i.e. -1 is the last ocurrence, -2 is the second to last (penultimate), etc.
567 @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).
569 bool removeAvp(AvpId id, int ocurrence = 1) throw(anna::RuntimeException) { assertFormat("Grouped"); return removeAvp(a_avps, (find_container&)a_finds, id, ocurrence, getEngine()); }
573 Same as #removeAvp but providing dictionary logical name for Avp searched
575 bool removeAvp(const char *name, int ocurrence = 1) throw(anna::RuntimeException);
580 Gets Avp identifier as pair (code, vendor-id).
582 const AvpId & getId() const throw() { return a_id; }
587 int getVendorId() const throw() { return a_id.second; }
590 Gets stack avp (dictionary avp reference).
592 const anna::diameter::stack::Avp *getStackAvp() const throw(anna::RuntimeException) { return getStackAvp(a_id, getEngine()); }
594 /** Returns V bit activation state */
595 bool vendorBit() const throw() { return ((a_flags & VBitMask) != 0x00); }
597 /** Returns M bit activation state */
598 bool mandatoryBit() const throw() { return ((a_flags & MBitMask) != 0x00); }
600 /** Returns P bit activation state */
601 bool encryptionBit() const throw() { return ((a_flags & PBitMask) != 0x00); }
604 /** Access content for OctetString Avp */
605 const OctetString * getOctetString() const throw(anna::RuntimeException) { assertFormat("OctetString"); return a_OctetString; }
606 /** Access content for Integer32 Avp */
607 const Integer32 * getInteger32() const throw(anna::RuntimeException) { assertFormat("Integer32"); return a_Integer32; }
608 /** Access content for Integer64 Avp */
609 const Integer64 * getInteger64() const throw(anna::RuntimeException) { assertFormat("Integer64"); return a_Integer64; }
610 /** Access content for Unsigned32 Avp */
611 const Unsigned32 * getUnsigned32() const throw(anna::RuntimeException) { assertFormat("Unsigned32"); return a_Unsigned32; }
612 /** Access content for Unsigned64 Avp */
613 const Unsigned64 * getUnsigned64() const throw(anna::RuntimeException) { assertFormat("Unsigned64"); return a_Unsigned64; }
614 /** Access content for Float32 Avp */
615 const Float32 * getFloat32() const throw(anna::RuntimeException) { assertFormat("Float32"); return a_Float32; }
616 /** Access content for Float64 Avp */
617 const Float64 * getFloat64() const throw(anna::RuntimeException) { assertFormat("Float64"); return a_Float64; }
620 Access content for Grouped Avp. Exception mode allows different combinations like cascade access:
624 message->getAvp(anna::diameter::helpers::base::AVP__Multiple_Services_Credit_Control, anna::Exception::Mode::Throw)
625 ->getAvp(anna::diameter::helpers::base::AVP__Rating_Group, anna::Exception::Mode::Throw);
627 catch(anna::RuntimeException) {;}
633 const Avp *mscc = message->getAvp(anna::diameter::helpers::base::AVP__Multiple_Services_Credit_Control);
635 if (mscc) rg = mscc->getAvp(anna::diameter::helpers::base::AVP__Rating_Group);
638 Replacing procedures becomes easy because an Avp can be searched and its pointer reconfigured by mean #setId and data part setters.
639 Deleting procedures must use #removeAvp.
640 Access is internally cached to speed up the search operations. This cache is reset after calling #fix or #removeAvp methods.
642 @param id Avp identifier (pair code + vendor-id).
643 @param ocurrence Order of appearance for the searched avp. Zero position is rejected, but negative values could be used to reverse
644 access positions: i.e. -1 is the last ocurrence, -2 is the second to last (penultimate), etc.
645 @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).
646 If avp format is not grouped, always exception will be launched and no matter what mode is provided. It would be a development
647 error and must be solved.
649 const Avp* getAvp(AvpId id, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) const throw(anna::RuntimeException) {
650 return _getAvp(id, ocurrence, emode);
653 Avp* getAvp(AvpId id, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException) {
654 return const_cast<Avp*>(_getAvp(id, ocurrence, emode));
658 Same as #getAvp but providing dictionary logical name for Avp searched
660 const Avp* getAvp(const char *name, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) const throw(anna::RuntimeException) {
661 return _getAvp(name, ocurrence, emode);
664 Avp* getAvp(const char *name, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException) {
665 return const_cast<Avp*>(_getAvp(name, ocurrence, emode));
670 /** Access content for Address Avp */
671 const Address * getAddress() const throw(anna::RuntimeException) { assertFormat("Address"); return a_Address; }
672 /** Access content for Time Avp */
673 const Time * getTime() const throw(anna::RuntimeException) { assertFormat("Time"); return a_Time; }
674 /** Access content for UTF8String Avp */
675 const UTF8String * getUTF8String() const throw(anna::RuntimeException) { assertFormat("UTF8String"); return a_UTF8String; }
676 /** Access content for DiameterIdentity Avp */
677 const DiameterIdentity * getDiameterIdentity() const throw(anna::RuntimeException) { assertFormat("DiameterIdentity"); return a_DiameterIdentity; }
678 /** Access content for DiameterURI Avp */
679 const DiameterURI * getDiameterURI() const throw(anna::RuntimeException) { assertFormat("DiameterURI"); return a_DiameterURI; }
680 /** Access content for Enumerated Avp */
681 const Enumerated * getEnumerated() const throw(anna::RuntimeException) { assertFormat("Enumerated"); return a_Enumerated; }
682 /** Access content for IPFilterRule Avp */
683 const IPFilterRule * getIPFilterRule() const throw(anna::RuntimeException) { assertFormat("IPFilterRule"); return a_IPFilterRule; }
684 /** Access content for QoSFilterRule Avp */
685 const QoSFilterRule * getQoSFilterRule() const throw(anna::RuntimeException) { assertFormat("QoSFilterRule"); return a_QoSFilterRule; }
686 /** Access content for Unknown Avp */
687 const Unknown * getUnknown() const throw(anna::RuntimeException) { assertFormat("Unknown"); return a_Unknown; }
693 Class xml representation
694 \param parent Parent XML node on which hold this instance information.
695 \return XML document with relevant information for this instance.
697 anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
700 Class xml string representation
701 \return XML string representation with relevant information for this instance.
703 std::string asXMLString() const throw();
706 Counts the number of ocurrences of Avps (first level) with the identifier provided
708 @param id Avp identifier (pair code + vendor-id).
710 int countAvp(AvpId id) const throw(anna::RuntimeException) { assertFormat("Grouped"); return countAvp(a_avps, id); }
713 Same as #countAvp but providing dictionary logical name for Avp searched
715 int countAvp(const char *name) const throw(anna::RuntimeException);
718 Counts the number of children within a grouped avp
720 @param id Avp identifier (pair code + vendor-id).
722 int countChilds() const throw(anna::RuntimeException) { assertFormat("Grouped"); return countChilds(a_avps); }
725 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
726 a Diameter client, server, proxy, or translation agent and either the AVP or its value is unrecognized, the message MUST be rejected.
727 Diameter Relay and redirect agents MUST NOT reject messages with unrecognized AVPs.
729 Default implementation launch alarm and counter indicating the anomaly but don't launch exception (traces at warning level).
730 Realy and Redirect agents could reimplement this method to avoid oam management (another way is avoid alarm/counter registration on
731 these applications). Result-Code DIAMETER_AVP_UNSUPPORTED will be stored for possible answer message.
733 @param answer Answer built for request decoding/validation
735 virtual void unknownAvpWithMandatoryBit(Message *answer) const throw(anna::RuntimeException);
738 friend class Message;