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();
390 Decodes Avp data part.
392 @param buffer Avp data part start pointer
393 @param size Avp data part size
394 @param parent Parent description. Internally used for alarms, tracing and Failed-AVP construction
395 @param answer Answer built for request decoding/validation
397 void decodeDataPart(const char * buffer, int size, const anna::diameter::codec::parent_t & parent, Message *answer) throw(anna::RuntimeException);
403 * Default constructor
408 * Identified constructor
409 * @param id Avp identifier as pair (code,vendor-id).
415 static const int HeaderLengthVactive;
416 static const int HeaderLengthVinactive;
425 // (encry)P(tion) (end to end encryption)
426 // r(eserved) - these flag bits are reserved for future use, and
427 // MUST be set to zero, and ignored by the receiver.
428 static const U8 VBitMask;
429 static const U8 MBitMask;
430 static const U8 PBitMask;
441 * Clears and initializes Avp class information.
442 * Application should clear auxiliary avp objects before setting data in a new context.
444 void clear() throw(anna::RuntimeException);
448 Sets the avp identifier and clear the former content.
449 Internally reserves memory for data part depending on avp format for the identifier provided.
450 This must be called at first place because Avp class content is cleared when identifier is configured.
451 Generic AVP assignment have no sense and will be ignored.
453 @param id Avp identifier as pair (code,vendor-id).
455 void setId(AvpId id) throw(anna::RuntimeException);
458 Same as #setId but providing dictionary logical name for Avp searched
460 void setId(const char *name) throw(anna::RuntimeException);
463 Sets/unsets M bit activation.
464 Application should not have to use this because dictionary information is used in order to configure flags when Avp identifier is stored.
465 Anyway, could be useful when build unknown-type avps.
467 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
468 a Diameter client, server, proxy, or translation agent and either the AVP or its value is unrecognized, the message MUST be rejected.
469 Diameter Relay and redirect agents MUST NOT reject messages with unrecognized AVPs.
471 @param activate Activates/deactivates the bit. True by default.
473 void setMandatoryBit(bool activate = true) throw() { if(activate) a_flags |= MBitMask; else a_flags &= (~MBitMask); }
476 Sets/unsets P 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 @param activate Activates/deactivates the bit. True by default.
482 void setEncryptionBit(bool activate = true) throw() { if(activate) a_flags |= PBitMask; else a_flags &= (~PBitMask); }
486 Adds an avp child providing its identifier and reserve internal memory it.
487 An exception is launched is the Avp is not a grouped avp.
489 @param id Avp identifier as pair (code,vendor-id).
491 @return Pointer to the new created avp.
493 Avp * addAvp(AvpId id) throw(anna::RuntimeException) { assertFormat("Grouped"); return addAvp(a_avps, a_insertionPositionForChilds, id, getEngine()); }
497 Same as #addAvp but providing dictionary logical name for Avp searched
499 Avp * addAvp(const char *name) throw(anna::RuntimeException);
503 Adds an avp child providing a persistent pointer (must be maintained by application).
504 An exception is launched is the Avp is not a grouped avp.
506 @param avp Avp external pointer. If NULL provided, nothing is done and NULL returned.
508 @return Pointer to the added avp (again).
510 Avp * addAvp(Avp * avp) throw(anna::RuntimeException) { if(!avp) return NULL; addChild(avp); return avp; }
513 /** Access content for OctetString Avp in order to set data part */
514 OctetString * getOctetString() throw(anna::RuntimeException) { assertFormat("OctetString"); return a_OctetString; }
515 /** Access content for Integer32 Avp in order to set data part */
516 Integer32 * getInteger32() throw(anna::RuntimeException) { assertFormat("Integer32"); return a_Integer32; }
517 /** Access content for Integer64 Avp in order to set data part */
518 Integer64 * getInteger64() throw(anna::RuntimeException) { assertFormat("Integer64"); return a_Integer64; }
519 /** Access content for Unsigned32 Avp in order to set data part */
520 Unsigned32 * getUnsigned32() throw(anna::RuntimeException) { assertFormat("Unsigned32"); return a_Unsigned32; }
521 /** Access content for Unsigned64 Avp in order to set data part */
522 Unsigned64 * getUnsigned64() throw(anna::RuntimeException) { assertFormat("Unsigned64"); return a_Unsigned64; }
523 /** Access content for Float32 Avp in order to set data part */
524 Float32 * getFloat32() throw(anna::RuntimeException) { assertFormat("Float32"); return a_Float32; }
525 /** Access content for Float64 Avp in order to set data part */
526 Float64 * getFloat64() throw(anna::RuntimeException) { assertFormat("Float64"); return a_Float64; }
527 /** Access content for Address Avp in order to set data part */
528 Address * getAddress() throw(anna::RuntimeException) { assertFormat("Address"); return a_Address; }
529 /** Access content for Time Avp in order to set data part */
530 Time * getTime() throw(anna::RuntimeException) { assertFormat("Time"); return a_Time; }
531 /** Access content for UTF8String Avp in order to set data part */
532 UTF8String * getUTF8String() throw(anna::RuntimeException) { assertFormat("UTF8String"); return a_UTF8String; }
533 /** Access content for DiameterIdentity Avp in order to set data part */
534 DiameterIdentity * getDiameterIdentity() throw(anna::RuntimeException) { assertFormat("DiameterIdentity"); return a_DiameterIdentity; }
535 /** Access content for DiameterURI Avp in order to set data part */
536 DiameterURI * getDiameterURI() throw(anna::RuntimeException) { assertFormat("DiameterURI"); return a_DiameterURI; }
537 /** Access content for Enumerated Avp in order to set data part */
538 Enumerated * getEnumerated() throw(anna::RuntimeException) { assertFormat("Enumerated"); return a_Enumerated; }
539 /** Access content for IPFilterRule Avp in order to set data part */
540 IPFilterRule * getIPFilterRule() throw(anna::RuntimeException) { assertFormat("IPFilterRule"); return a_IPFilterRule; }
541 /** Access content for QoSFilterRule Avp in order to set data part */
542 QoSFilterRule * getQoSFilterRule() throw(anna::RuntimeException) { assertFormat("QoSFilterRule"); return a_QoSFilterRule; }
543 /** Access content for Unknown Avp in order to set data part */
544 Unknown * getUnknown() throw(anna::RuntimeException) { assertFormat("Unknown"); return a_Unknown; }
548 Removes an Avp within grouped type (first level) and free resources.
550 @param id Avp identifier (pair code + vendor-id).
551 @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).
552 Negative values could be used to reverse access positions: i.e. -1 is the last ocurrence, -2 is the second to last (penultimate), etc.
554 @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).
556 bool removeAvp(AvpId id, int ocurrence = 1) throw(anna::RuntimeException) { assertFormat("Grouped"); return removeAvp(a_avps, (find_container&)a_finds, id, ocurrence, getEngine()); }
560 Same as #removeAvp but providing dictionary logical name for Avp searched
562 bool removeAvp(const char *name, int ocurrence = 1) throw(anna::RuntimeException);
567 Gets Avp identifier as pair (code, vendor-id).
569 const AvpId & getId() const throw() { return a_id; }
574 int getVendorId() const throw() { return a_id.second; }
577 Gets stack avp (dictionary avp reference).
579 const anna::diameter::stack::Avp *getStackAvp() const throw(anna::RuntimeException) { return getStackAvp(a_id, getEngine()); }
581 /** Returns V bit activation state */
582 bool vendorBit() const throw() { return ((a_flags & VBitMask) != 0x00); }
584 /** Returns M bit activation state */
585 bool mandatoryBit() const throw() { return ((a_flags & MBitMask) != 0x00); }
587 /** Returns P bit activation state */
588 bool encryptionBit() const throw() { return ((a_flags & PBitMask) != 0x00); }
591 /** Access content for OctetString Avp */
592 const OctetString * getOctetString() const throw(anna::RuntimeException) { assertFormat("OctetString"); return a_OctetString; }
593 /** Access content for Integer32 Avp */
594 const Integer32 * getInteger32() const throw(anna::RuntimeException) { assertFormat("Integer32"); return a_Integer32; }
595 /** Access content for Integer64 Avp */
596 const Integer64 * getInteger64() const throw(anna::RuntimeException) { assertFormat("Integer64"); return a_Integer64; }
597 /** Access content for Unsigned32 Avp */
598 const Unsigned32 * getUnsigned32() const throw(anna::RuntimeException) { assertFormat("Unsigned32"); return a_Unsigned32; }
599 /** Access content for Unsigned64 Avp */
600 const Unsigned64 * getUnsigned64() const throw(anna::RuntimeException) { assertFormat("Unsigned64"); return a_Unsigned64; }
601 /** Access content for Float32 Avp */
602 const Float32 * getFloat32() const throw(anna::RuntimeException) { assertFormat("Float32"); return a_Float32; }
603 /** Access content for Float64 Avp */
604 const Float64 * getFloat64() const throw(anna::RuntimeException) { assertFormat("Float64"); return a_Float64; }
607 Access content for Grouped Avp. Exception mode allows different combinations like cascade access:
611 message->getAvp(anna::diameter::helpers::base::AVP__Multiple_Services_Credit_Control, anna::Exception::Mode::Throw)
612 ->getAvp(anna::diameter::helpers::base::AVP__Rating_Group, anna::Exception::Mode::Throw);
614 catch(anna::RuntimeException) {;}
620 const Avp *mscc = message->getAvp(anna::diameter::helpers::base::AVP__Multiple_Services_Credit_Control);
622 if (mscc) rg = mscc->getAvp(anna::diameter::helpers::base::AVP__Rating_Group);
625 Replacing procedures becomes easy because an Avp can be searched and its pointer reconfigured by mean #setId and data part setters.
626 Deleting procedures must use #removeAvp.
627 Access is internally cached to speed up the search operations. This cache is reset after calling #fix or #removeAvp methods.
629 @param id Avp identifier (pair code + vendor-id).
630 @param ocurrence Order of appearance for the searched avp. Zero position is rejected, but negative values could be used to reverse
631 access positions: i.e. -1 is the last ocurrence, -2 is the second to last (penultimate), etc.
632 @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).
633 If avp format is not grouped, always exception will be launched and no matter what mode is provided. It would be a development
634 error and must be solved.
636 const Avp* getAvp(AvpId id, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) const throw(anna::RuntimeException) {
637 return _getAvp(id, ocurrence, emode);
640 Avp* getAvp(AvpId id, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException) {
641 return const_cast<Avp*>(_getAvp(id, ocurrence, emode));
645 Same as #getAvp but providing dictionary logical name for Avp searched
647 const Avp* getAvp(const char *name, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) const throw(anna::RuntimeException) {
648 return _getAvp(name, ocurrence, emode);
651 Avp* getAvp(const char *name, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException) {
652 return const_cast<Avp*>(_getAvp(name, ocurrence, emode));
657 /** Access content for Address Avp */
658 const Address * getAddress() const throw(anna::RuntimeException) { assertFormat("Address"); return a_Address; }
659 /** Access content for Time Avp */
660 const Time * getTime() const throw(anna::RuntimeException) { assertFormat("Time"); return a_Time; }
661 /** Access content for UTF8String Avp */
662 const UTF8String * getUTF8String() const throw(anna::RuntimeException) { assertFormat("UTF8String"); return a_UTF8String; }
663 /** Access content for DiameterIdentity Avp */
664 const DiameterIdentity * getDiameterIdentity() const throw(anna::RuntimeException) { assertFormat("DiameterIdentity"); return a_DiameterIdentity; }
665 /** Access content for DiameterURI Avp */
666 const DiameterURI * getDiameterURI() const throw(anna::RuntimeException) { assertFormat("DiameterURI"); return a_DiameterURI; }
667 /** Access content for Enumerated Avp */
668 const Enumerated * getEnumerated() const throw(anna::RuntimeException) { assertFormat("Enumerated"); return a_Enumerated; }
669 /** Access content for IPFilterRule Avp */
670 const IPFilterRule * getIPFilterRule() const throw(anna::RuntimeException) { assertFormat("IPFilterRule"); return a_IPFilterRule; }
671 /** Access content for QoSFilterRule Avp */
672 const QoSFilterRule * getQoSFilterRule() const throw(anna::RuntimeException) { assertFormat("QoSFilterRule"); return a_QoSFilterRule; }
673 /** Access content for Unknown Avp */
674 const Unknown * getUnknown() const throw(anna::RuntimeException) { assertFormat("Unknown"); return a_Unknown; }
678 Decodes buffer provided over class content. If an error ocurred, decoding will stop launching exception (fatal error) or a warning trace (perhaps the achieved
679 avp is valid against all odds then validation will go on). In case that validation is enabled (codec::Engine::ValidationMode) an exception will be launched
680 depending on validation depth (codec::Engine::ValidationDepth).
682 Useful as serialization procedure with #code
684 @param db Buffer data block processed
686 void decode(const anna::DataBlock &db) throw(anna::RuntimeException);
690 Interpret xml data in order to dump over the class content.
692 \param avpNode Avp root node
694 void fromXML(const anna::xml::Node* avpNode) throw(anna::RuntimeException);
698 Encodes buffer with the class content. This method is internally used to encode diameter messages, but is declared as public, to allow
699 its use as serialization procedure. Then, it's assumed that this Avp is valid (validation shall be applied as part of a whole diameter
700 message but nothing will be verified now).
702 * @param buffer Raw data to be encoded (shall be externally allocated)
703 * @param size Size of raw data to be encoded
705 void code(char* buffer, int &size) const throw(anna::RuntimeException);
711 Class xml representation
712 \param parent Parent XML node on which hold this instance information.
713 \return XML document with relevant information for this instance.
715 anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
718 Class xml string representation
719 \return XML string representation with relevant information for this instance.
721 std::string asXMLString() const throw();
724 Comparison operator by mean serialization
726 @param a1 Instance 1 for Avp class
727 @param a2 Instance 2 for Avp class
729 @return Comparison result
731 friend bool operator == (const Avp & a1, const Avp & a2) throw() { return (a1.asXMLString() == a2.asXMLString()); }
734 Match a regular expression (string pattern) regarding xml string serialization for this avp.
735 This works same as #Message::isLike
737 @param pattern Pattern to match
739 \return Returns the match result
741 bool isLike(const std::string &pattern) const throw();
744 Counts the number of ocurrences of Avps (first level) with the identifier provided
746 @param id Avp identifier (pair code + vendor-id).
748 int countAvp(AvpId id) const throw(anna::RuntimeException) { assertFormat("Grouped"); return countAvp(a_avps, id); }
751 Same as #countAvp but providing dictionary logical name for Avp searched
753 int countAvp(const char *name) const throw(anna::RuntimeException);
756 Counts the number of children within a grouped avp
758 @param id Avp identifier (pair code + vendor-id).
760 int countChilds() const throw(anna::RuntimeException) { assertFormat("Grouped"); return countChilds(a_avps); }
763 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
764 a Diameter client, server, proxy, or translation agent and either the AVP or its value is unrecognized, the message MUST be rejected.
765 Diameter Relay and redirect agents MUST NOT reject messages with unrecognized AVPs.
767 Default implementation launch alarm and counter indicating the anomaly but don't launch exception (traces at warning level).
768 Relay and Redirect agents could reimplement this method to avoid oam management (another way is avoid alarm/counter registration on
769 these applications). Result-Code DIAMETER_AVP_UNSUPPORTED will be stored for possible answer message.
771 virtual void unknownAvpWithMandatoryBit() const throw(anna::RuntimeException);
774 friend class Message;