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/codec/functions.hpp>
46 #include <anna/diameter/stack/Avp.hpp>
48 #include <anna/core/RuntimeException.hpp>
54 //------------------------------------------------------------------------------
55 //---------------------------------------------------------------------- #define
56 //------------------------------------------------------------------------------
92 class DiameterIdentity;
105 typedef std::map < int /* key: insertion pos */, Avp* > avp_container;
106 typedef avp_container::iterator avp_iterator;
107 typedef avp_container::const_iterator const_avp_iterator;
109 // Cache avp-find system
110 typedef std::pair < AvpId, unsigned int /* position */ > find_key;
111 typedef std::map<find_key, Avp*> find_container;
112 typedef std::map<find_key, Avp*>::iterator find_iterator;
115 using namespace basetypes;
118 * Diameter avp generic container
120 * RFC 3588 Diameter Based Protocol September 2003
123 * The fields in the AVP header MUST be sent in network byte order. The
124 * format of the header is:
127 * 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
128 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
130 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
131 * | AVP Flags | AVP Length |
132 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
133 * | Vendor-ID (opt) |
134 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
139 * AVP Flags: V (vendor-specific), M (mandatory), P (end to end encryption)
145 * The AVP Length field is three octets, and indicates the number of
146 * octets in this AVP including the AVP Code, AVP Length, AVP Flags,
147 * Vendor-ID field (if present) and the AVP data.
149 * Vendor-ID: IANA "SMI Network Management Private Enterprise Codes" [ASSIGNNO]
150 * http://www.iana.org/assignments/enterprise-numbers
155 AvpId a_id; // code and vendor-code
159 int a_insertionPositionForChilds; // used at grouped type
162 // --- Developer notes ---
163 // 'AVP Length' does not include posible data padding. Thanks to this, 'Data Length'
164 // is the difference between 'AVP Length' and sum of code, length, flags and
165 // optionally the vendor-ID (all of them are 32-bit boundary), that is to say:
166 // 8 or 12 (vendor-specific avps).
168 // Grouped avps 'AVP Length' includes own headers plus the total length of all
169 // underlying AVPs, including their headers and padding, then 'AVP Length' is
170 // always multiple of 4 (library will check this), and smae for 'Data Length'
171 // which is an 'whole avp Length with padding' itself.
174 OctetString *a_OctetString;
175 Integer32 *a_Integer32;
176 Integer64 *a_Integer64;
177 Unsigned32 *a_Unsigned32;
178 Unsigned64 *a_Unsigned64;
181 avp_container a_avps; // Grouped
184 UTF8String *a_UTF8String;
185 DiameterIdentity *a_DiameterIdentity;
186 DiameterURI *a_DiameterURI;
187 Enumerated *a_Enumerated;
188 IPFilterRule *a_IPFilterRule;
189 QoSFilterRule *a_QoSFilterRule;
193 find_container a_finds; // fast access for grouped and message first-level avps
196 // 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
197 // 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
198 // instantiating the class. Friend functions are functions which are not in the class and you want to give them access to private members
201 // Common (also for Message class)
202 static avp_iterator avp_find(avp_container &avps, AvpId id, unsigned int position) throw();
203 static const_avp_iterator avp_find(const avp_container &avps, AvpId id, unsigned int position) throw() {
204 return (const_avp_iterator)avp_find((avp_container &)avps, id, position);
206 static Avp * addAvp(avp_container &avps, int &insertionPositionForChilds, AvpId id, Engine *engine) throw();
207 static bool removeAvp(avp_container &avps, find_container &finds, AvpId id, int ocurrence, Engine *engine) throw();
208 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();
209 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
210 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);
211 static int countAvp(const avp_container &avps, AvpId id) throw();
212 static const Avp* firstAvp(const avp_container &avps, AvpId id) throw();
213 static int countChilds(const avp_container &avps) throw();
214 static int addChild(avp_container &avps, int &insertionPositionForChilds, Avp *avp) throw() {
217 avps[insertionPositionForChilds++] = avp;
218 return insertionPositionForChilds;
220 static const anna::diameter::stack::Avp *getStackAvp(AvpId id, Engine *engine) throw();
221 const Avp* _getAvp(const char *name, int ocurrence, anna::Exception::Mode::_v emode) const throw(anna::RuntimeException);
222 const Avp* _getAvp(AvpId id, int ocurrence, anna::Exception::Mode::_v emode) const throw(anna::RuntimeException);
225 avp_iterator avp_begin() throw() { return a_avps.begin(); }
226 avp_iterator avp_end() throw() { return a_avps.end(); }
227 static Avp* avp(avp_iterator ii) throw() { return ii->second; }
228 const_avp_iterator avp_begin() const throw() { return a_avps.begin(); }
229 const_avp_iterator avp_end() const throw() { return a_avps.end(); }
230 static const Avp* avp(const_avp_iterator ii) throw() { return ii->second; }
233 bool flagsOK() const throw(); // flags coherence regarding dictionary. Only must be called when AVP is identified at the dictionary.
234 int addChild(Avp *avp) throw(anna::RuntimeException) { assertFormat("Grouped"); return addChild(a_avps, a_insertionPositionForChilds, avp); }
235 bool hasChildren() throw() { return a_avps.size() != 0; }
237 static bool contain(const_avp_iterator begin, const_avp_iterator end, const Avp *parent) throw() { return true; }
241 Fix grouped content regarding dictionary avp positions.
242 Avp could remain invalid because of possible fixed/mandatory avps.
243 This is useful to give flexibility to the application during message construction before encoding or representing the data.
244 Is not recommended to fix a recently decoded message because possible validation problems will be hidden.
249 Validates an Avp regarding dictionary rules like enumerated range, flags coherence, mandatory and fixed types, cardinality qualifiers, etc.
251 @param parent Parent description. Internally used for alarms, tracing and Failed-AVP construction
252 @param answer Answer could be modified with any validation problem during requests validation
254 @return Boolean indicating validation result
256 bool valid(const anna::diameter::codec::parent_t & parent, Message *answer) const throw(anna::RuntimeException);
259 Decodes buffer provided over class content. If an error ocurred, decoding will stop launching exception (fatal error) or a warning trace (perhaps the achieved
260 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
261 depending on validation depth (codec::Engine::ValidationDepth).
263 @param db Buffer data block processed
264 @param parent Parent description. Internally used for alarms, tracing and Failed-AVP construction
265 @param answer Answer built for request decoding/validation
267 void decode(const anna::DataBlock &db, const anna::diameter::codec::parent_t & parent, Message *answer) throw(anna::RuntimeException);
270 /////////////////////////////////////////////
271 // Inherit format-specific virtual methods //
272 /////////////////////////////////////////////
275 * Initializes Avp class information.
276 * Default implementation supports all anna::diameter formats (including derived ones).
277 * Diameter basic formats are managed at #initialize, which will invoke this method at the end.
279 virtual void initializeByFormat() throw() {};
282 * Gets avp data-part length.
283 * Default implementation supports all anna::diameter formats (including derived ones).
284 * Diameter basic formats are managed at #initialize, which will invoke this method at the end.
286 * @param stackFormat Stack avp format in which data extraction is based.
288 * @return Avp data-part size.
290 virtual U24 getLengthByFormat(const anna::diameter::stack::Format *stackFormat) const throw() { return 0; };
293 Gets data or hexadecimal data depending on avp format, for xml creating
294 Default implementation supports all anna::diameter formats (including derived ones).
295 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
297 \param isHex Hexadecimal/Natural data when apply.
298 \param stackFormat Stack avp format in which data extraction is based.
299 \return xml data representation
301 virtual std::string getXMLdataByFormat(bool & isHex, const anna::diameter::stack::Format *stackFormat) const throw() { return ""; };
304 Interpret xml data in order to dump over the class content.
305 Default implementation supports all anna::diameter formats (including derived ones).
306 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
308 \param data Avp data attribute
309 \param hexData Avp hex-data attribute
310 \param stackFormat Stack avp format in which data extraction is based.
312 virtual void fromXMLByFormat(const anna::xml::Attribute* data, const anna::xml::Attribute* hexData, const anna::diameter::stack::Format *stackFormat) throw(anna::RuntimeException) {};
316 Encodes buffer with the class content.
317 Default implementation supports all anna::diameter formats (including derived ones).
318 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
320 @param dataPart Data-part begin pointer
321 @param stackFormat Stack avp format in which data extraction is based.
323 virtual void codeByFormat(char* dataPart, const anna::diameter::stack::Format *stackFormat) const throw(anna::RuntimeException) {};
327 Decodes Avp data part.
328 Default implementation supports all anna::diameter formats (including derived ones).
329 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
331 @param buffer Avp data part start pointer
332 @param size Avp data part size
333 @param stackFormat Stack avp format in which data extraction is based.
335 virtual void decodeDataPartByFormat(const char * buffer, int size, const anna::diameter::stack::Format *stackFormat) throw(anna::RuntimeException) {};
338 Reserves memory for data part depending on avp format for the identifier provided.
339 Default implementation supports all anna::diameter formats (including derived ones).
340 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
342 @param stackFormat Stack avp format in which data extraction is based.
344 virtual void allocationByFormat(const anna::diameter::stack::Format *stackFormat) throw() {};
347 * Clears Avp data-part format containers.
349 virtual void clearByFormat() throw() {};
356 mutable Engine *a_engine;
358 /** Codec Engine getter: avoids have to create base engine when using its child */
359 virtual Engine * getEngine() const throw(anna::RuntimeException);
362 * Initializes Avp class information.
364 void initialize() throw();
367 * Assert format regarding dictionary
369 void assertFormat(const std::string &name) const throw(anna::RuntimeException);
372 * Gets avp total length based on internal data part and header configuration.
373 * Padding octets are not included, only header and data part length.
374 * The only format which always have total length equal to sum of all its parts is Grouped,
375 * because of the 4-multiple nature of its data part length.
377 U24 getLength() const throw();
380 Gets data or hexadecimal data depending on avp format, for xml creating
382 \param isHex Hexadecimal/Natural data when apply.
383 \param stackFormat Stack avp format in which data extraction is based.
384 \return xml data representation
386 std::string getXMLdata(bool & isHex, const anna::diameter::stack::Format *stackFormat) const throw();
389 Interpret xml data in order to dump over the class content.
391 \param avpNode Avp root node
393 void fromXML(const anna::xml::Node* avpNode) throw(anna::RuntimeException);
397 Encodes buffer with the class content.
399 * @param buffer Raw data to be encoded
400 * @param size Size of raw data to be encoded
402 void code(char* buffer, int &size) const throw(anna::RuntimeException);
406 Decodes Avp data part.
408 @param buffer Avp data part start pointer
409 @param size Avp data part size
410 @param parent Parent description. Internally used for alarms, tracing and Failed-AVP construction
411 @param answer Answer built for request decoding/validation
413 void decodeDataPart(const char * buffer, int size, const anna::diameter::codec::parent_t & parent, Message *answer) throw(anna::RuntimeException);
419 * Default constructor
424 * Identified constructor
425 * @param id Avp identifier as pair (code,vendor-id).
431 static const int HeaderLengthVactive;
432 static const int HeaderLengthVinactive;
441 // (encry)P(tion) (end to end encryption)
442 // r(eserved) - these flag bits are reserved for future use, and
443 // MUST be set to zero, and ignored by the receiver.
444 static const U8 VBitMask;
445 static const U8 MBitMask;
446 static const U8 PBitMask;
457 * Clears and initializes Avp class information.
458 * Application should clear auxiliary avp objects before setting data in a new context.
460 void clear() throw(anna::RuntimeException);
464 Sets the avp identifier and clear the former content.
465 Internally reserves memory for data part depending on avp format for the identifier provided.
466 This must be called at first place because Avp class content is cleared when identifier is configured.
467 Generic AVP assignment have no sense and will be ignored.
469 @param id Avp identifier as pair (code,vendor-id).
471 void setId(AvpId id) throw(anna::RuntimeException);
474 Same as #setId but providing dictionary logical name for Avp searched
476 void setId(const char *name) throw(anna::RuntimeException);
479 Sets/unsets M bit activation.
480 Application should not have to use this because dictionary information is used in order to configure flags when Avp identifier is stored.
481 Anyway, could be useful when build unknown-type avps.
483 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
484 a Diameter client, server, proxy, or translation agent and either the AVP or its value is unrecognized, the message MUST be rejected.
485 Diameter Relay and redirect agents MUST NOT reject messages with unrecognized AVPs.
487 @param activate Activates/deactivates the bit. True by default.
489 void setMandatoryBit(bool activate = true) throw() { if(activate) a_flags |= MBitMask; else a_flags &= (~MBitMask); }
492 Sets/unsets P bit activation.
493 Application should not have to use this because dictionary information is used in order to configure flags when Avp identifier is stored.
494 Anyway, could be useful when build unknown-type avps.
496 @param activate Activates/deactivates the bit. True by default.
498 void setEncryptionBit(bool activate = true) throw() { if(activate) a_flags |= PBitMask; else a_flags &= (~PBitMask); }
502 Adds an avp child providing its identifier and reserve internal memory it.
503 An exception is launched is the Avp is not a grouped avp.
505 @param id Avp identifier as pair (code,vendor-id).
507 @return Pointer to the new created avp.
509 Avp * addAvp(AvpId id) throw(anna::RuntimeException) { assertFormat("Grouped"); return addAvp(a_avps, a_insertionPositionForChilds, id, getEngine()); }
513 Same as #addAvp but providing dictionary logical name for Avp searched
515 Avp * addAvp(const char *name) throw(anna::RuntimeException);
519 Adds an avp child providing a persistent pointer (must be maintained by application).
520 An exception is launched is the Avp is not a grouped avp.
522 @param avp Avp external pointer. If NULL provided, nothing is done and NULL returned.
524 @return Pointer to the added avp (again).
526 Avp * addAvp(Avp * avp) throw(anna::RuntimeException) { if(!avp) return NULL; addChild(avp); return avp; }
529 /** Access content for OctetString Avp in order to set data part */
530 OctetString * getOctetString() throw(anna::RuntimeException) { assertFormat("OctetString"); return a_OctetString; }
531 /** Access content for Integer32 Avp in order to set data part */
532 Integer32 * getInteger32() throw(anna::RuntimeException) { assertFormat("Integer32"); return a_Integer32; }
533 /** Access content for Integer64 Avp in order to set data part */
534 Integer64 * getInteger64() throw(anna::RuntimeException) { assertFormat("Integer64"); return a_Integer64; }
535 /** Access content for Unsigned32 Avp in order to set data part */
536 Unsigned32 * getUnsigned32() throw(anna::RuntimeException) { assertFormat("Unsigned32"); return a_Unsigned32; }
537 /** Access content for Unsigned64 Avp in order to set data part */
538 Unsigned64 * getUnsigned64() throw(anna::RuntimeException) { assertFormat("Unsigned64"); return a_Unsigned64; }
539 /** Access content for Float32 Avp in order to set data part */
540 Float32 * getFloat32() throw(anna::RuntimeException) { assertFormat("Float32"); return a_Float32; }
541 /** Access content for Float64 Avp in order to set data part */
542 Float64 * getFloat64() throw(anna::RuntimeException) { assertFormat("Float64"); return a_Float64; }
543 /** Access content for Address Avp in order to set data part */
544 Address * getAddress() throw(anna::RuntimeException) { assertFormat("Address"); return a_Address; }
545 /** Access content for Time Avp in order to set data part */
546 Time * getTime() throw(anna::RuntimeException) { assertFormat("Time"); return a_Time; }
547 /** Access content for UTF8String Avp in order to set data part */
548 UTF8String * getUTF8String() throw(anna::RuntimeException) { assertFormat("UTF8String"); return a_UTF8String; }
549 /** Access content for DiameterIdentity Avp in order to set data part */
550 DiameterIdentity * getDiameterIdentity() throw(anna::RuntimeException) { assertFormat("DiameterIdentity"); return a_DiameterIdentity; }
551 /** Access content for DiameterURI Avp in order to set data part */
552 DiameterURI * getDiameterURI() throw(anna::RuntimeException) { assertFormat("DiameterURI"); return a_DiameterURI; }
553 /** Access content for Enumerated Avp in order to set data part */
554 Enumerated * getEnumerated() throw(anna::RuntimeException) { assertFormat("Enumerated"); return a_Enumerated; }
555 /** Access content for IPFilterRule Avp in order to set data part */
556 IPFilterRule * getIPFilterRule() throw(anna::RuntimeException) { assertFormat("IPFilterRule"); return a_IPFilterRule; }
557 /** Access content for QoSFilterRule Avp in order to set data part */
558 QoSFilterRule * getQoSFilterRule() throw(anna::RuntimeException) { assertFormat("QoSFilterRule"); return a_QoSFilterRule; }
559 /** Access content for Unknown Avp in order to set data part */
560 Unknown * getUnknown() throw(anna::RuntimeException) { assertFormat("Unknown"); return a_Unknown; }
564 Removes an Avp within grouped type (first level) and free resources.
566 @param id Avp identifier (pair code + vendor-id).
567 @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).
568 Negative values could be used to reverse access positions: i.e. -1 is the last ocurrence, -2 is the second to last (penultimate), etc.
570 @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).
572 bool removeAvp(AvpId id, int ocurrence = 1) throw(anna::RuntimeException) { assertFormat("Grouped"); return removeAvp(a_avps, (find_container&)a_finds, id, ocurrence, getEngine()); }
576 Same as #removeAvp but providing dictionary logical name for Avp searched
578 bool removeAvp(const char *name, int ocurrence = 1) throw(anna::RuntimeException);
583 Gets Avp identifier as pair (code, vendor-id).
585 const AvpId & getId() const throw() { return a_id; }
590 int getVendorId() const throw() { return a_id.second; }
593 Gets stack avp (dictionary avp reference).
595 const anna::diameter::stack::Avp *getStackAvp() const throw(anna::RuntimeException) { return getStackAvp(a_id, getEngine()); }
597 /** Returns V bit activation state */
598 bool vendorBit() const throw() { return ((a_flags & VBitMask) != 0x00); }
600 /** Returns M bit activation state */
601 bool mandatoryBit() const throw() { return ((a_flags & MBitMask) != 0x00); }
603 /** Returns P bit activation state */
604 bool encryptionBit() const throw() { return ((a_flags & PBitMask) != 0x00); }
607 /** Access content for OctetString Avp */
608 const OctetString * getOctetString() const throw(anna::RuntimeException) { assertFormat("OctetString"); return a_OctetString; }
609 /** Access content for Integer32 Avp */
610 const Integer32 * getInteger32() const throw(anna::RuntimeException) { assertFormat("Integer32"); return a_Integer32; }
611 /** Access content for Integer64 Avp */
612 const Integer64 * getInteger64() const throw(anna::RuntimeException) { assertFormat("Integer64"); return a_Integer64; }
613 /** Access content for Unsigned32 Avp */
614 const Unsigned32 * getUnsigned32() const throw(anna::RuntimeException) { assertFormat("Unsigned32"); return a_Unsigned32; }
615 /** Access content for Unsigned64 Avp */
616 const Unsigned64 * getUnsigned64() const throw(anna::RuntimeException) { assertFormat("Unsigned64"); return a_Unsigned64; }
617 /** Access content for Float32 Avp */
618 const Float32 * getFloat32() const throw(anna::RuntimeException) { assertFormat("Float32"); return a_Float32; }
619 /** Access content for Float64 Avp */
620 const Float64 * getFloat64() const throw(anna::RuntimeException) { assertFormat("Float64"); return a_Float64; }
623 Access content for Grouped Avp. Exception mode allows different combinations like cascade access:
627 message->getAvp(anna::diameter::helpers::base::AVP__Multiple_Services_Credit_Control, anna::Exception::Mode::Throw)
628 ->getAvp(anna::diameter::helpers::base::AVP__Rating_Group, anna::Exception::Mode::Throw);
630 catch(anna::RuntimeException) {;}
636 const Avp *mscc = message->getAvp(anna::diameter::helpers::base::AVP__Multiple_Services_Credit_Control);
638 if (mscc) rg = mscc->getAvp(anna::diameter::helpers::base::AVP__Rating_Group);
641 Replacing procedures becomes easy because an Avp can be searched and its pointer reconfigured by mean #setId and data part setters.
642 Deleting procedures must use #removeAvp.
643 Access is internally cached to speed up the search operations. This cache is reset after calling #fix or #removeAvp methods.
645 @param id Avp identifier (pair code + vendor-id).
646 @param ocurrence Order of appearance for the searched avp. Zero position is rejected, but negative values could be used to reverse
647 access positions: i.e. -1 is the last ocurrence, -2 is the second to last (penultimate), etc.
648 @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).
649 If avp format is not grouped, always exception will be launched and no matter what mode is provided. It would be a development
650 error and must be solved.
652 const Avp* getAvp(AvpId id, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) const throw(anna::RuntimeException) {
653 return _getAvp(id, ocurrence, emode);
656 Avp* getAvp(AvpId id, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException) {
657 return const_cast<Avp*>(_getAvp(id, ocurrence, emode));
661 Same as #getAvp but providing dictionary logical name for Avp searched
663 const Avp* getAvp(const char *name, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) const throw(anna::RuntimeException) {
664 return _getAvp(name, ocurrence, emode);
667 Avp* getAvp(const char *name, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException) {
668 return const_cast<Avp*>(_getAvp(name, ocurrence, emode));
673 /** Access content for Address Avp */
674 const Address * getAddress() const throw(anna::RuntimeException) { assertFormat("Address"); return a_Address; }
675 /** Access content for Time Avp */
676 const Time * getTime() const throw(anna::RuntimeException) { assertFormat("Time"); return a_Time; }
677 /** Access content for UTF8String Avp */
678 const UTF8String * getUTF8String() const throw(anna::RuntimeException) { assertFormat("UTF8String"); return a_UTF8String; }
679 /** Access content for DiameterIdentity Avp */
680 const DiameterIdentity * getDiameterIdentity() const throw(anna::RuntimeException) { assertFormat("DiameterIdentity"); return a_DiameterIdentity; }
681 /** Access content for DiameterURI Avp */
682 const DiameterURI * getDiameterURI() const throw(anna::RuntimeException) { assertFormat("DiameterURI"); return a_DiameterURI; }
683 /** Access content for Enumerated Avp */
684 const Enumerated * getEnumerated() const throw(anna::RuntimeException) { assertFormat("Enumerated"); return a_Enumerated; }
685 /** Access content for IPFilterRule Avp */
686 const IPFilterRule * getIPFilterRule() const throw(anna::RuntimeException) { assertFormat("IPFilterRule"); return a_IPFilterRule; }
687 /** Access content for QoSFilterRule Avp */
688 const QoSFilterRule * getQoSFilterRule() const throw(anna::RuntimeException) { assertFormat("QoSFilterRule"); return a_QoSFilterRule; }
689 /** Access content for Unknown Avp */
690 const Unknown * getUnknown() const throw(anna::RuntimeException) { assertFormat("Unknown"); return a_Unknown; }
696 Class xml representation
697 \param parent Parent XML node on which hold this instance information.
698 \return XML document with relevant information for this instance.
700 anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
703 Class xml string representation
704 \return XML string representation with relevant information for this instance.
706 std::string asXMLString() const throw();
709 Counts the number of ocurrences of Avps (first level) with the identifier provided
711 @param id Avp identifier (pair code + vendor-id).
713 int countAvp(AvpId id) const throw(anna::RuntimeException) { assertFormat("Grouped"); return countAvp(a_avps, id); }
716 Same as #countAvp but providing dictionary logical name for Avp searched
718 int countAvp(const char *name) const throw(anna::RuntimeException);
721 Counts the number of children within a grouped avp
723 @param id Avp identifier (pair code + vendor-id).
725 int countChilds() const throw(anna::RuntimeException) { assertFormat("Grouped"); return countChilds(a_avps); }
728 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
729 a Diameter client, server, proxy, or translation agent and either the AVP or its value is unrecognized, the message MUST be rejected.
730 Diameter Relay and redirect agents MUST NOT reject messages with unrecognized AVPs.
732 Default implementation launch alarm and counter indicating the anomaly but don't launch exception (traces at warning level).
733 Relay and Redirect agents could reimplement this method to avoid oam management (another way is avoid alarm/counter registration on
734 these applications). Result-Code DIAMETER_AVP_UNSUPPORTED will be stored for possible answer message.
736 virtual void unknownAvpWithMandatoryBit() const throw(anna::RuntimeException);
739 friend class Message;