1 // ANNA - Anna is Not 'N' Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // https://bitbucket.org/testillano/anna
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 Google Inc. 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>
46 #include <anna/diameter/helpers/tme/codectypes/codectypes.hpp>
48 #include <anna/core/RuntimeException.hpp>
54 //------------------------------------------------------------------------------
55 //---------------------------------------------------------------------- #define
56 //------------------------------------------------------------------------------
75 namespace codectypes {
103 class DiameterIdentity;
116 typedef std::map < int /* key: insertion pos */, Avp* > avp_container;
117 typedef avp_container::iterator avp_iterator;
118 typedef avp_container::const_iterator const_avp_iterator;
120 // Cache avp-find system
121 typedef std::pair < AvpId, unsigned int /* position */ > find_key;
122 typedef std::map<find_key, Avp*> find_container;
123 typedef std::map<find_key, Avp*>::iterator find_iterator;
126 using namespace basetypes;
127 using namespace helpers::tme::codectypes;
130 * Diameter avp generic container
132 * RFC 3588 Diameter Based Protocol September 2003
135 * The fields in the AVP header MUST be sent in network byte order. The
136 * format of the header is:
139 * 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
140 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
142 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
143 * | AVP Flags | AVP Length |
144 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
145 * | Vendor-ID (opt) |
146 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
151 * AVP Flags: V (vendor-specific), M (mandatory), P (end to end encryption)
157 * The AVP Length field is three octets, and indicates the number of
158 * octets in this AVP including the AVP Code, AVP Length, AVP Flags,
159 * Vendor-ID field (if present) and the AVP data.
161 * Vendor-ID: IANA "SMI Network Management Private Enterprise Codes" [ASSIGNNO]
162 * http://www.iana.org/assignments/enterprise-numbers
167 AvpId a_id; // code and vendor-code
171 int a_insertionPositionForChilds; // used at grouped type
174 // --- Developer notes ---
175 // 'AVP Length' does not include posible data padding. Thanks to this, 'Data Length'
176 // is the difference between 'AVP Length' and sum of code, length, flags and
177 // optionally the vendor-ID (all of them are 32-bit boundary), that is to say:
178 // 8 or 12 (vendor-specific avps).
180 // Grouped avps 'AVP Length' includes own headers plus the total length of all
181 // underlying AVPs, including their headers and padding, then 'AVP Length' is
182 // always multiple of 4 (library will check this), and smae for 'Data Length'
183 // which is an 'whole avp Length with padding' itself.
186 OctetString *a_OctetString;
187 Integer32 *a_Integer32;
188 Integer64 *a_Integer64;
189 Unsigned32 *a_Unsigned32;
190 Unsigned64 *a_Unsigned64;
193 avp_container a_avps; // Grouped
196 UTF8String *a_UTF8String;
197 DiameterIdentity *a_DiameterIdentity;
198 DiameterURI *a_DiameterURI;
199 Enumerated *a_Enumerated;
200 IPFilterRule *a_IPFilterRule;
201 QoSFilterRule *a_QoSFilterRule;
204 // Derived formats ////////////////////////////////////////////
206 ISDNNumber *a_ISDNNumber;
207 ISDNAddress *a_ISDNAddress;
208 Unsigned16 *a_Unsigned16;
213 find_container a_finds; // fast access for grouped and message first-level avps
216 // 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
217 // 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
218 // instantiating the class. Friend functions are functions which are not in the class and you want to give them access to private members
221 // Common (also for Message class)
222 static avp_iterator avp_find(avp_container &avps, AvpId id, unsigned int position) throw();
223 static const_avp_iterator avp_find(const avp_container &avps, AvpId id, unsigned int position) throw() {
224 return (const_avp_iterator)avp_find((avp_container &)avps, id, position);
226 static Avp * addAvp(avp_container &avps, int &insertionPositionForChilds, AvpId id, Engine *engine) throw();
227 static bool removeAvp(avp_container &avps, find_container &finds, AvpId id, int ocurrence, Engine *engine) throw();
228 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();
229 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
230 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);
231 static int countAvp(const avp_container &avps, AvpId id) throw();
232 static const Avp* firstAvp(const avp_container &avps, AvpId id) throw();
233 static int countChilds(const avp_container &avps) throw();
234 static int addChild(avp_container &avps, int &insertionPositionForChilds, Avp *avp) throw() {
237 avps[insertionPositionForChilds++] = avp;
238 return insertionPositionForChilds;
240 static const anna::diameter::stack::Avp *getStackAvp(AvpId id, Engine *engine) throw();
241 const Avp* _getAvp(const char *name, int ocurrence, anna::Exception::Mode::_v emode) const throw(anna::RuntimeException);
242 const Avp* _getAvp(AvpId id, int ocurrence, anna::Exception::Mode::_v emode) const throw(anna::RuntimeException);
245 avp_iterator avp_begin() throw() { return a_avps.begin(); }
246 avp_iterator avp_end() throw() { return a_avps.end(); }
247 static Avp* avp(avp_iterator ii) throw() { return ii->second; }
248 const_avp_iterator avp_begin() const throw() { return a_avps.begin(); }
249 const_avp_iterator avp_end() const throw() { return a_avps.end(); }
250 static const Avp* avp(const_avp_iterator ii) throw() { return ii->second; }
253 void assertFormat(const std::string &name) const throw(anna::RuntimeException);
254 bool flagsOK() const throw(); // flags coherence regarding dictionary. Only must be called when AVP is identified at the dictionary.
255 int addChild(Avp *avp) throw(anna::RuntimeException) { assertFormat("Grouped"); return addChild(a_avps, a_insertionPositionForChilds, avp); }
256 bool hasChildren() throw() { return a_avps.size() != 0; }
258 static bool contain(const_avp_iterator begin, const_avp_iterator end, const Avp *parent) throw() { return true; }
262 Fix grouped content regarding dictionary avp positions.
263 Avp could remain invalid because of possible fixed/mandatory avps.
264 This is useful to give flexibility to the application during message construction before encoding or representing the data.
265 Is not recommended to fix a recently decoded message because possible validation problems will be hidden.
270 Validates an Avp regarding dictionary rules like enumerated range, flags coherence, mandatory and fixed types, cardinality qualifiers, etc.
272 @param parentDescription Parent description. Internally used for alarms and tracing
273 @param answer Answer could be modified with any validation problem during requests validation
275 @return Boolean indicating validation result
277 bool valid(const std::string & parentDescription, Message *answer) const throw(anna::RuntimeException);
280 Decodes buffer provided over class content. If an error ocurred, decoding will stop launching exception (fatal error) or a warning trace (perhaps the achieved
281 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
282 depending on validation depth (codec::Engine::ValidationDepth).
284 @param db Buffer data block processed
285 @param answer Answer built for request decoding/validation
287 void decode(const anna::DataBlock &db, Message *answer) throw(anna::RuntimeException);
290 /////////////////////////////////////////////
291 // Inherit format-specific virtual methods //
292 /////////////////////////////////////////////
295 * Initializes Avp class information.
296 * Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
297 * Diameter basic formats are managed at #initialize, which will invoke this method at the end.
299 virtual void initializeByFormat() throw();
302 * Gets avp data-part length.
303 * Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
304 * Diameter basic formats are managed at #initialize, which will invoke this method at the end.
306 * @param stackFormat Stack avp format in which data extraction is based.
308 * @return Avp data-part size.
310 virtual U24 getLengthByFormat(const anna::diameter::stack::Format *stackFormat) const throw();
313 Gets data or hexadecimal data depending on avp format, for xml creating
314 Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
315 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
317 \param isHex Hexadecimal/Natural data when apply.
318 \param stackFormat Stack avp format in which data extraction is based.
319 \return xml data representation
321 virtual std::string getXMLdataByFormat(bool & isHex, const anna::diameter::stack::Format *stackFormat) const throw();
324 Interpret xml data in order to dump over the class content.
325 Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
326 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
328 \param data Avp data attribute
329 \param hexData Avp hex-data attribute
330 \param stackFormat Stack avp format in which data extraction is based.
332 virtual void fromXMLByFormat(const anna::xml::Attribute* data, const anna::xml::Attribute* hexData, const anna::diameter::stack::Format *stackFormat) throw(anna::RuntimeException);
336 Encodes buffer with the class content.
337 Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
338 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
340 @param dataPart Data-part begin pointer
341 @param stackFormat Stack avp format in which data extraction is based.
343 virtual void codeByFormat(char* dataPart, const anna::diameter::stack::Format *stackFormat) const throw(anna::RuntimeException);
347 Decodes Avp data part.
348 Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
349 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
351 @param buffer Avp data part start pointer
352 @param size Avp data part size
353 @param stackFormat Stack avp format in which data extraction is based.
355 virtual void decodeDataPartByFormat(const char * buffer, int size, const anna::diameter::stack::Format *stackFormat) throw(anna::RuntimeException);
358 Reserves memory for data part depending on avp format for the identifier provided.
359 Default implementation supports all anna::diameter formats (including i.e. tme.db ones).
360 Diameter basic formats are managed at #initialize, which will invoke this method at the end.
362 @param stackFormat Stack avp format in which data extraction is based.
364 virtual void allocationByFormat(const anna::diameter::stack::Format *stackFormat) throw();
367 * Clears Avp data-part format containers.
369 virtual void clearByFormat() throw();
376 mutable Engine *a_engine;
378 /** Codec Engine getter: avoids have to create base engine when using its child */
379 virtual Engine * getEngine() const throw(anna::RuntimeException);
382 * Initializes Avp class information.
384 void initialize() throw();
388 * Gets avp total length based on internal data part and header configuration.
389 * Padding octets are not included, only header and data part length.
390 * The only format which always have total length equal to sum of all its parts is Grouped,
391 * because of the 4-multiple nature of its data part length.
393 U24 getLength() const throw();
396 Gets data or hexadecimal data depending on avp format, for xml creating
398 \param isHex Hexadecimal/Natural data when apply.
399 \param stackFormat Stack avp format in which data extraction is based.
400 \return xml data representation
402 std::string getXMLdata(bool & isHex, const anna::diameter::stack::Format *stackFormat) const throw();
405 Interpret xml data in order to dump over the class content.
407 \param avpNode Avp root node
409 void fromXML(const anna::xml::Node* avpNode) throw(anna::RuntimeException);
413 Encodes buffer with the class content.
415 * @param buffer Raw data to be encoded
416 * @param size Size of raw data to be encoded
418 void code(char* buffer, int &size) const throw(anna::RuntimeException);
422 Decodes Avp data part.
424 @param buffer Avp data part start pointer
425 @param size Avp data part size
426 @param answer Answer built for request decoding/validation
428 void decodeDataPart(const char * buffer, int size, Message *answer) throw(anna::RuntimeException);
434 * Default constructor
439 * Identified constructor
440 * @param id Avp identifier as pair (code,vendor-id).
446 static const int HeaderLengthVactive;
447 static const int HeaderLengthVinactive;
456 // (encry)P(tion) (end to end encryption)
457 // r(eserved) - these flag bits are reserved for future use, and
458 // MUST be set to zero, and ignored by the receiver.
459 static const U8 VBitMask;
460 static const U8 MBitMask;
461 static const U8 PBitMask;
472 * Clears and initializes Avp class information.
473 * Application should clear auxiliary avp objects before setting data in a new context.
475 void clear() throw(anna::RuntimeException);
479 Sets the avp identifier and clear the former content.
480 Internally reserves memory for data part depending on avp format for the identifier provided.
481 This must be called at first place because Avp class content is cleared when identifier is configured.
482 Generic AVP assignment have no sense and will be ignored.
484 @param id Avp identifier as pair (code,vendor-id).
486 void setId(AvpId id) throw(anna::RuntimeException);
489 Same as #setId but providing dictionary logical name for Avp searched
491 void setId(const char *name) throw(anna::RuntimeException);
494 Sets/unsets M bit activation.
495 Application should not have to use this because dictionary information is used in order to configure flags when Avp identifier is stored.
496 Anyway, could be useful when build unknown-type avps.
498 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
499 a Diameter client, server, proxy, or translation agent and either the AVP or its value is unrecognized, the message MUST be rejected.
500 Diameter Relay and redirect agents MUST NOT reject messages with unrecognized AVPs.
502 @param activate Activates/deactivates the bit. True by default.
504 void setMandatoryBit(bool activate = true) throw() { if(activate) a_flags |= MBitMask; else a_flags &= (~MBitMask); }
507 Sets/unsets P bit activation.
508 Application should not have to use this because dictionary information is used in order to configure flags when Avp identifier is stored.
509 Anyway, could be useful when build unknown-type avps.
511 @param activate Activates/deactivates the bit. True by default.
513 void setEncryptionBit(bool activate = true) throw() { if(activate) a_flags |= PBitMask; else a_flags &= (~PBitMask); }
517 Adds an avp child providing its identifier and reserve internal memory it.
518 An exception is launched is the Avp is not a grouped avp.
520 @param id Avp identifier as pair (code,vendor-id).
522 @return Pointer to the new created avp.
524 Avp * addAvp(AvpId id) throw(anna::RuntimeException) { assertFormat("Grouped"); return addAvp(a_avps, a_insertionPositionForChilds, id, getEngine()); }
528 Same as #addAvp but providing dictionary logical name for Avp searched
530 Avp * addAvp(const char *name) throw(anna::RuntimeException);
534 Adds an avp child providing a persistent pointer (must be maintained by application).
535 An exception is launched is the Avp is not a grouped avp.
537 @param avp Avp external pointer. If NULL provided, nothing is done and NULL returned.
539 @return Pointer to the added avp (again).
541 Avp * addAvp(Avp * avp) throw(anna::RuntimeException) { if(!avp) return NULL; addChild(avp); return avp; }
544 /** Access content for OctetString Avp in order to set data part */
545 OctetString * getOctetString() throw(anna::RuntimeException) { assertFormat("OctetString"); return a_OctetString; }
546 /** Access content for Integer32 Avp in order to set data part */
547 Integer32 * getInteger32() throw(anna::RuntimeException) { assertFormat("Integer32"); return a_Integer32; }
548 /** Access content for Integer64 Avp in order to set data part */
549 Integer64 * getInteger64() throw(anna::RuntimeException) { assertFormat("Integer64"); return a_Integer64; }
550 /** Access content for Unsigned32 Avp in order to set data part */
551 Unsigned32 * getUnsigned32() throw(anna::RuntimeException) { assertFormat("Unsigned32"); return a_Unsigned32; }
552 /** Access content for Unsigned64 Avp in order to set data part */
553 Unsigned64 * getUnsigned64() throw(anna::RuntimeException) { assertFormat("Unsigned64"); return a_Unsigned64; }
554 /** Access content for Float32 Avp in order to set data part */
555 Float32 * getFloat32() throw(anna::RuntimeException) { assertFormat("Float32"); return a_Float32; }
556 /** Access content for Float64 Avp in order to set data part */
557 Float64 * getFloat64() throw(anna::RuntimeException) { assertFormat("Float64"); return a_Float64; }
558 /** Access content for Address Avp in order to set data part */
559 Address * getAddress() throw(anna::RuntimeException) { assertFormat("Address"); return a_Address; }
560 /** Access content for Time Avp in order to set data part */
561 Time * getTime() throw(anna::RuntimeException) { assertFormat("Time"); return a_Time; }
562 /** Access content for UTF8String Avp in order to set data part */
563 UTF8String * getUTF8String() throw(anna::RuntimeException) { assertFormat("UTF8String"); return a_UTF8String; }
564 /** Access content for DiameterIdentity Avp in order to set data part */
565 DiameterIdentity * getDiameterIdentity() throw(anna::RuntimeException) { assertFormat("DiameterIdentity"); return a_DiameterIdentity; }
566 /** Access content for DiameterURI Avp in order to set data part */
567 DiameterURI * getDiameterURI() throw(anna::RuntimeException) { assertFormat("DiameterURI"); return a_DiameterURI; }
568 /** Access content for Enumerated Avp in order to set data part */
569 Enumerated * getEnumerated() throw(anna::RuntimeException) { assertFormat("Enumerated"); return a_Enumerated; }
570 /** Access content for IPFilterRule Avp in order to set data part */
571 IPFilterRule * getIPFilterRule() throw(anna::RuntimeException) { assertFormat("IPFilterRule"); return a_IPFilterRule; }
572 /** Access content for QoSFilterRule Avp in order to set data part */
573 QoSFilterRule * getQoSFilterRule() throw(anna::RuntimeException) { assertFormat("QoSFilterRule"); return a_QoSFilterRule; }
574 /** Access content for Unknown Avp in order to set data part */
575 Unknown * getUnknown() throw(anna::RuntimeException) { assertFormat("Unknown"); return a_Unknown; }
577 // Derived formats ////////////////////////////////////////////
579 /** Access content for ISDNNumber Avp in order to set data part */
580 ISDNNumber * getISDNNumber() throw(anna::RuntimeException) { assertFormat("ISDNNumber"); return a_ISDNNumber; }
581 /** Access content for ISDNAddress Avp in order to set data part */
582 ISDNAddress * getISDNAddress() throw(anna::RuntimeException) { assertFormat("ISDNAddress"); return a_ISDNAddress; }
583 /** Access content for Unsigned16 Avp in order to set data part */
584 Unsigned16 * getUnsigned16() throw(anna::RuntimeException) { assertFormat("Unsigned16"); return a_Unsigned16; }
588 Removes an Avp within grouped type (first level) and free resources.
590 @param id Avp identifier (pair code + vendor-id).
591 @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).
592 Negative values could be used to reverse access positions: i.e. -1 is the last ocurrence, -2 is the second to last (penultimate), etc.
594 @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).
596 bool removeAvp(AvpId id, int ocurrence = 1) throw(anna::RuntimeException) { assertFormat("Grouped"); return removeAvp(a_avps, (find_container&)a_finds, id, ocurrence, getEngine()); }
600 Same as #removeAvp but providing dictionary logical name for Avp searched
602 bool removeAvp(const char *name, int ocurrence = 1) throw(anna::RuntimeException);
607 Gets Avp identifier as pair (code, vendor-id).
609 const AvpId & getId() const throw() { return a_id; }
614 int getVendorId() const throw() { return a_id.second; }
617 Gets stack avp (dictionary avp reference).
619 const anna::diameter::stack::Avp *getStackAvp() const throw(anna::RuntimeException) { return getStackAvp(a_id, getEngine()); }
621 /** Returns V bit activation state */
622 bool vendorBit() const throw() { return ((a_flags & VBitMask) != 0x00); }
624 /** Returns M bit activation state */
625 bool mandatoryBit() const throw() { return ((a_flags & MBitMask) != 0x00); }
627 /** Returns P bit activation state */
628 bool encryptionBit() const throw() { return ((a_flags & PBitMask) != 0x00); }
631 /** Access content for OctetString Avp */
632 const OctetString * getOctetString() const throw(anna::RuntimeException) { assertFormat("OctetString"); return a_OctetString; }
633 /** Access content for Integer32 Avp */
634 const Integer32 * getInteger32() const throw(anna::RuntimeException) { assertFormat("Integer32"); return a_Integer32; }
635 /** Access content for Integer64 Avp */
636 const Integer64 * getInteger64() const throw(anna::RuntimeException) { assertFormat("Integer64"); return a_Integer64; }
637 /** Access content for Unsigned32 Avp */
638 const Unsigned32 * getUnsigned32() const throw(anna::RuntimeException) { assertFormat("Unsigned32"); return a_Unsigned32; }
639 /** Access content for Unsigned64 Avp */
640 const Unsigned64 * getUnsigned64() const throw(anna::RuntimeException) { assertFormat("Unsigned64"); return a_Unsigned64; }
641 /** Access content for Float32 Avp */
642 const Float32 * getFloat32() const throw(anna::RuntimeException) { assertFormat("Float32"); return a_Float32; }
643 /** Access content for Float64 Avp */
644 const Float64 * getFloat64() const throw(anna::RuntimeException) { assertFormat("Float64"); return a_Float64; }
647 Access content for Grouped Avp. Exception mode allows different combinations like cascade access:
651 message->getAvp(anna::diameter::helpers::base::AVP__Multiple_Services_Credit_Control, anna::Exception::Mode::Throw)
652 ->getAvp(anna::diameter::helpers::base::AVP__Rating_Group, anna::Exception::Mode::Throw);
654 catch(anna::RuntimeException) {;}
660 const Avp *mscc = message->getAvp(anna::diameter::helpers::base::AVP__Multiple_Services_Credit_Control);
662 if (mscc) rg = mscc->getAvp(anna::diameter::helpers::base::AVP__Rating_Group);
665 Replacing procedures becomes easy because an Avp can be searched and its pointer reconfigured by mean #setId and data part setters.
666 Deleting procedures must use #removeAvp.
667 Access is internally cached to speed up the search operations. This cache is reset after calling #fix or #removeAvp methods.
669 @param id Avp identifier (pair code + vendor-id).
670 @param ocurrence Order of appearance for the searched avp. Zero position is rejected, but negative values could be used to reverse
671 access positions: i.e. -1 is the last ocurrence, -2 is the second to last (penultimate), etc.
672 @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).
673 If avp format is not grouped, always exception will be launched and no matter what mode is provided. It would be a development
674 error and must be solved.
676 const Avp* getAvp(AvpId id, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) const throw(anna::RuntimeException) {
677 return _getAvp(id, ocurrence, emode);
680 Avp* getAvp(AvpId id, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException) {
681 return const_cast<Avp*>(_getAvp(id, ocurrence, emode));
685 Same as #getAvp but providing dictionary logical name for Avp searched
687 const Avp* getAvp(const char *name, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) const throw(anna::RuntimeException) {
688 return _getAvp(name, ocurrence, emode);
691 Avp* getAvp(const char *name, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException) {
692 return const_cast<Avp*>(_getAvp(name, ocurrence, emode));
697 /** Access content for Address Avp */
698 const Address * getAddress() const throw(anna::RuntimeException) { assertFormat("Address"); return a_Address; }
699 /** Access content for Time Avp */
700 const Time * getTime() const throw(anna::RuntimeException) { assertFormat("Time"); return a_Time; }
701 /** Access content for UTF8String Avp */
702 const UTF8String * getUTF8String() const throw(anna::RuntimeException) { assertFormat("UTF8String"); return a_UTF8String; }
703 /** Access content for DiameterIdentity Avp */
704 const DiameterIdentity * getDiameterIdentity() const throw(anna::RuntimeException) { assertFormat("DiameterIdentity"); return a_DiameterIdentity; }
705 /** Access content for DiameterURI Avp */
706 const DiameterURI * getDiameterURI() const throw(anna::RuntimeException) { assertFormat("DiameterURI"); return a_DiameterURI; }
707 /** Access content for Enumerated Avp */
708 const Enumerated * getEnumerated() const throw(anna::RuntimeException) { assertFormat("Enumerated"); return a_Enumerated; }
709 /** Access content for IPFilterRule Avp */
710 const IPFilterRule * getIPFilterRule() const throw(anna::RuntimeException) { assertFormat("IPFilterRule"); return a_IPFilterRule; }
711 /** Access content for QoSFilterRule Avp */
712 const QoSFilterRule * getQoSFilterRule() const throw(anna::RuntimeException) { assertFormat("QoSFilterRule"); return a_QoSFilterRule; }
713 /** Access content for Unknown Avp */
714 const Unknown * getUnknown() const throw(anna::RuntimeException) { assertFormat("Unknown"); return a_Unknown; }
717 // Derived formats ////////////////////////////////////////////
719 /** Access content for ISDNNumber Avp */
720 const ISDNNumber * getISDNNumber() const throw(anna::RuntimeException) { assertFormat("ISDNNumber"); return a_ISDNNumber; }
721 /** Access content for ISDNAddress Avp */
722 const ISDNAddress * getISDNAddress() const throw(anna::RuntimeException) { assertFormat("ISDNAddress"); return a_ISDNAddress; }
723 /** Access content for Unsigned16 Avp */
724 const Unsigned16 * getUnsigned16() const throw(anna::RuntimeException) { assertFormat("Unsigned16"); return a_Unsigned16; }
730 Class xml representation
731 \param parent Parent XML node on which hold this instance information.
732 \return XML document with relevant information for this instance.
734 anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
737 Class xml string representation
738 \return XML string representation with relevant information for this instance.
740 std::string asXMLString() const throw();
743 Counts the number of ocurrences of Avps (first level) with the identifier provided
745 @param id Avp identifier (pair code + vendor-id).
747 int countAvp(AvpId id) const throw(anna::RuntimeException) { assertFormat("Grouped"); return countAvp(a_avps, id); }
750 Same as #countAvp but providing dictionary logical name for Avp searched
752 int countAvp(const char *name) const throw(anna::RuntimeException);
755 Counts the number of children within a grouped avp
757 @param id Avp identifier (pair code + vendor-id).
759 int countChilds() const throw(anna::RuntimeException) { assertFormat("Grouped"); return countChilds(a_avps); }
762 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
763 a Diameter client, server, proxy, or translation agent and either the AVP or its value is unrecognized, the message MUST be rejected.
764 Diameter Relay and redirect agents MUST NOT reject messages with unrecognized AVPs.
766 Default implementation launch alarm and counter indicating the anomaly but don't launch exception (traces at warning level).
767 Realy and Redirect agents could reimplement this method to avoid oam management (another way is avoid alarm/counter registration on
768 these applications). Result-Code DIAMETER_AVP_UNSUPPORTED will be stored for possible answer message.
770 @param answer Answer built for request decoding/validation
772 virtual void unknownAvpWithMandatoryBit(Message *answer) const throw(anna::RuntimeException);
775 friend class Message;