ANNA Suite  2020b
Multipurpose development suite for Telco applications
Avp.hpp
Go to the documentation of this file.
1 // ANNA - Anna is Not Nothingness Anymore //
2 // //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
4 // //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7 
8 
9 #ifndef anna_diameter_codec_Avp_hpp
10 #define anna_diameter_codec_Avp_hpp
11 
12 
13 // Local
14 #include <anna/config/defines.hpp>
19 
21 
22 // STL
23 #include <string>
24 #include <map>
25 
26 //------------------------------------------------------------------------------
27 //---------------------------------------------------------------------- #define
28 //------------------------------------------------------------------------------
29 
30 namespace anna {
31 
32 class DataBlock;
33 
34 namespace xml {
35 class Node;
36 class Attribute;
37 }
38 }
39 
40 namespace anna {
41 
42 namespace diameter {
43 
44 
45 namespace stack {
46 class Dictionary;
47 class Format;
48 class Avp;
49 }
50 
51 namespace codec {
52 
53 namespace basetypes {
54 class OctetString;
55 class Integer32;
56 class Integer64;
57 class Unsigned32;
58 class Unsigned64;
59 class Float32;
60 class Float64;
61 class Address;
62 class Time;
63 class UTF8String;
64 class DiameterIdentity;
65 class DiameterURI;
66 class Enumerated;
67 class IPFilterRule;
68 class QoSFilterRule;
69 class Unknown;
70 }
71 
72 class Avp;
73 class Message;
74 class Engine;
75 
76 
77 typedef std::map < int /* key: insertion pos */, Avp* > avp_container;
78 typedef avp_container::iterator avp_iterator;
79 typedef avp_container::const_iterator const_avp_iterator;
80 
81 // Cache avp-find system
82 typedef std::pair < AvpId, unsigned int /* position */ > find_key;
83 typedef std::map<find_key, Avp*> find_container;
84 typedef std::map<find_key, Avp*>::iterator find_iterator;
85 
86 
87 using namespace basetypes;
88 
125 class Avp {
126 
127  AvpId a_id; // code and vendor-code
128  U8 a_flags;
129 
130  // auxiliary
131  int a_insertionPositionForChilds; // used at grouped type
132 
133 
134  // --- Developer notes ---
135  // 'AVP Length' does not include posible data padding. Thanks to this, 'Data Length'
136  // is the difference between 'AVP Length' and sum of code, length, flags and
137  // optionally the vendor-ID (all of them are 32-bit boundary), that is to say:
138  // 8 or 12 (vendor-specific avps).
139  //
140  // Grouped avps 'AVP Length' includes own headers plus the total length of all
141  // underlying AVPs, including their headers and padding, then 'AVP Length' is
142  // always multiple of 4 (library will check this), and smae for 'Data Length'
143  // which is an 'whole avp Length with padding' itself.
144 
145  // Data containers
146  OctetString *a_OctetString;
147  Integer32 *a_Integer32;
148  Integer64 *a_Integer64;
149  Unsigned32 *a_Unsigned32;
150  Unsigned64 *a_Unsigned64;
151  Float32 *a_Float32;
152  Float64 *a_Float64;
153  avp_container a_avps; // Grouped
154  Address *a_Address;
155  Time *a_Time;
156  UTF8String *a_UTF8String;
157  DiameterIdentity *a_DiameterIdentity;
158  DiameterURI *a_DiameterURI;
159  Enumerated *a_Enumerated;
160  IPFilterRule *a_IPFilterRule;
161  QoSFilterRule *a_QoSFilterRule;
162  Unknown *a_Unknown;
163 
164  // Grouped helpers
165  find_container a_finds; // fast access for grouped and message first-level avps
166 
167 
168  // Static functions are used when you want a function that is the same for every instance of a class. Such functions do not have access
169  // to "this" pointer and thus cannot access any non static fields. They are used often when you want a function that can be used without
170  // instantiating the class. Friend functions are functions which are not in the class and you want to give them access to private members
171  // of your class.
172 
173  // Common (also for Message class)
174  static avp_iterator avp_find(avp_container &avps, AvpId id, unsigned int position) ;
175  static const_avp_iterator avp_find(const avp_container &avps, AvpId id, unsigned int position) {
176  return (const_avp_iterator)avp_find((avp_container &)avps, id, position);
177  }
178  static Avp * addAvp(avp_container &avps, int &insertionPositionForChilds, AvpId id, Engine *engine) ;
179  static bool removeAvp(avp_container &avps, find_container &finds, AvpId id, int ocurrence, Engine *engine) ;
180  static void fix(avp_container &avps, find_container &finds, int &insertionPositionForChilds, anna::diameter::stack::const_avprule_iterator ruleBegin, anna::diameter::stack::const_avprule_iterator ruleEnd) ;
181  static bool validLevel(const avp_container &avps, anna::diameter::stack::const_avprule_iterator ruleBegin, anna::diameter::stack::const_avprule_iterator ruleEnd, Engine * engine, const anna::diameter::codec::parent_t & parent, Message *answer) noexcept(false); // validates mandatory/fixed and cardinality
182  static const Avp* getAvp(const avp_container &avps, find_container &finds, AvpId id, int ocurrence, Engine *engine, anna::Exception::Mode::_v emode) noexcept(false);
183  static int countAvp(const avp_container &avps, AvpId id) ;
184  static const Avp* firstAvp(const avp_container &avps, AvpId id) ;
185  static int countChilds(const avp_container &avps) ;
186  static int addChild(avp_container &avps, int &insertionPositionForChilds, Avp *avp) {
187  if(!avp) return -1;
188 
189  avps[insertionPositionForChilds++] = avp;
190  return insertionPositionForChilds;
191  }
192  static const anna::diameter::stack::Avp *getStackAvp(AvpId id, Engine *engine) ;
193  const Avp* _getAvp(const char *name, int ocurrence, anna::Exception::Mode::_v emode) const noexcept(false);
194  const Avp* _getAvp(AvpId id, int ocurrence, anna::Exception::Mode::_v emode) const noexcept(false);
195 
196  // Own
197  avp_iterator avp_begin() { return a_avps.begin(); }
198  avp_iterator avp_end() { return a_avps.end(); }
199  static Avp* avp(avp_iterator ii) { return ii->second; }
200  const_avp_iterator avp_begin() const { return a_avps.begin(); }
201  const_avp_iterator avp_end() const { return a_avps.end(); }
202  static const Avp* avp(const_avp_iterator ii) { return ii->second; }
203 
204  // Internal
205  bool flagsOK() const ; // flags coherence regarding dictionary. Only must be called when AVP is identified at the dictionary.
206  int addChild(Avp *avp) noexcept(false) { assertFormat("Grouped"); return addChild(a_avps, a_insertionPositionForChilds, avp); }
207  bool hasChildren() { return a_avps.size() != 0; }
208 
209  static bool contain(const_avp_iterator begin, const_avp_iterator end, const Avp *parent) { return true; }
210 
211 
218  void fix() ;
219 
228  bool valid(const anna::diameter::codec::parent_t & parent, Message *answer) const noexcept(false);
229 
239  void decode(const anna::DataBlock &db, const anna::diameter::codec::parent_t & parent, Message *answer) noexcept(false);
240 
241 
243  // Inherit format-specific virtual methods //
245 
251  virtual void initializeByFormat() {};
252 
262  virtual U24 getLengthByFormat(const anna::diameter::stack::Format *stackFormat) const { return 0; };
263 
273  virtual std::string getXMLdataByFormat(bool & isHex, const anna::diameter::stack::Format *stackFormat) const { return ""; };
274 
284  virtual void fromXMLByFormat(const anna::xml::Attribute* data, const anna::xml::Attribute* hexData, const anna::diameter::stack::Format *stackFormat) noexcept(false) {};
285 
286 
295  virtual void codeByFormat(char* dataPart, const anna::diameter::stack::Format *stackFormat) const noexcept(false) {};
296 
297 
307  virtual void decodeDataPartByFormat(const char * buffer, int size, const anna::diameter::stack::Format *stackFormat) noexcept(false) {};
308 
316  virtual void allocationByFormat(const anna::diameter::stack::Format *stackFormat) {};
317 
321  virtual void clearByFormat() {};
322 
323 
324 
325 protected:
326 
328  mutable Engine *a_engine;
329 
331  virtual Engine * getEngine() const noexcept(false);
332 
336  void initialize() ;
337 
341  void assertFormat(const std::string &name) const noexcept(false);
342 
349  U24 getLength() const ;
350 
358  std::string getXMLdata(bool & isHex, const anna::diameter::stack::Format *stackFormat) const ;
359 
360 
369  void decodeDataPart(const char * buffer, int size, const anna::diameter::codec::parent_t & parent, Message *answer) noexcept(false);
370 
371 
372 public:
373 
378  Avp(Engine *engine = NULL);
379 
385  Avp(AvpId id, Engine *engine = NULL);
386 
387 
404  void setEngine(Engine *engine) ;
405 
406 
407  // Length references
408  static const int HeaderLengthVactive;
409  static const int HeaderLengthVinactive;
410 
411  // AVP Flags
412  // +-+-+-+-+-+-+-+-+
413  // |V M P r r r r r|
414  // +-+-+-+-+-+-+-+-+
415  //
416  // V(endor-specific)
417  // M(andatory)
418  // (encry)P(tion) (end to end encryption)
419  // r(eserved) - these flag bits are reserved for future use, and
420  // MUST be set to zero, and ignored by the receiver.
421  static const U8 VBitMask;
422  static const U8 MBitMask;
423  static const U8 PBitMask;
424 
428  virtual ~Avp();
429 
430 
431  // setters
432 
437  void clear() noexcept(false);
438 
439 
448  void setId(AvpId id) noexcept(false);
449 
453  void setId(const char *name) noexcept(false);
454 
466  void setMandatoryBit(bool activate = true) { if(activate) a_flags |= MBitMask; else a_flags &= (~MBitMask); }
467 
475  void setEncryptionBit(bool activate = true) { if(activate) a_flags |= PBitMask; else a_flags &= (~PBitMask); }
476 
477 
486  Avp * addAvp(AvpId id) noexcept(false) { assertFormat("Grouped"); return addAvp(a_avps, a_insertionPositionForChilds, id, getEngine()); }
487 
488 
492  Avp * addAvp(const char *name) noexcept(false);
493 
505  Avp * addAvp(Avp * avp) noexcept(false);
506 
507 
508  // Data part access
510  OctetString * getOctetString() noexcept(false) { assertFormat("OctetString"); return a_OctetString; }
512  Integer32 * getInteger32() noexcept(false) { assertFormat("Integer32"); return a_Integer32; }
514  Integer64 * getInteger64() noexcept(false) { assertFormat("Integer64"); return a_Integer64; }
516  Unsigned32 * getUnsigned32() noexcept(false) { assertFormat("Unsigned32"); return a_Unsigned32; }
518  Unsigned64 * getUnsigned64() noexcept(false) { assertFormat("Unsigned64"); return a_Unsigned64; }
520  Float32 * getFloat32() noexcept(false) { assertFormat("Float32"); return a_Float32; }
522  Float64 * getFloat64() noexcept(false) { assertFormat("Float64"); return a_Float64; }
524  Address * getAddress() noexcept(false) { assertFormat("Address"); return a_Address; }
526  Time * getTime() noexcept(false) { assertFormat("Time"); return a_Time; }
528  UTF8String * getUTF8String() noexcept(false) { assertFormat("UTF8String"); return a_UTF8String; }
530  DiameterIdentity * getDiameterIdentity() noexcept(false) { assertFormat("DiameterIdentity"); return a_DiameterIdentity; }
532  DiameterURI * getDiameterURI() noexcept(false) { assertFormat("DiameterURI"); return a_DiameterURI; }
534  Enumerated * getEnumerated() noexcept(false) { assertFormat("Enumerated"); return a_Enumerated; }
536  IPFilterRule * getIPFilterRule() noexcept(false) { assertFormat("IPFilterRule"); return a_IPFilterRule; }
538  QoSFilterRule * getQoSFilterRule() noexcept(false) { assertFormat("QoSFilterRule"); return a_QoSFilterRule; }
540  Unknown * getUnknown() noexcept(false) { assertFormat("Unknown"); return a_Unknown; }
541 
542 
552  bool removeAvp(AvpId id, int ocurrence = 1) noexcept(false) { assertFormat("Grouped"); return removeAvp(a_avps, (find_container&)a_finds, id, ocurrence, getEngine()); }
553 
554 
558  bool removeAvp(const char *name, int ocurrence = 1) noexcept(false);
559 
560  // getters
561 
565  const AvpId & getId() const { return a_id; }
566 
570  int getVendorId() const { return a_id.second; }
571 
575  const anna::diameter::stack::Avp *getStackAvp() const noexcept(false) { return getStackAvp(a_id, getEngine()); }
576 
578  bool vendorBit() const { return ((a_flags & VBitMask) != 0x00); }
579 
581  bool mandatoryBit() const { return ((a_flags & MBitMask) != 0x00); }
582 
584  bool encryptionBit() const { return ((a_flags & PBitMask) != 0x00); }
585 
586  // Data part access
588  const OctetString * getOctetString() const noexcept(false) { assertFormat("OctetString"); return a_OctetString; }
590  const Integer32 * getInteger32() const noexcept(false) { assertFormat("Integer32"); return a_Integer32; }
592  const Integer64 * getInteger64() const noexcept(false) { assertFormat("Integer64"); return a_Integer64; }
594  const Unsigned32 * getUnsigned32() const noexcept(false) { assertFormat("Unsigned32"); return a_Unsigned32; }
596  const Unsigned64 * getUnsigned64() const noexcept(false) { assertFormat("Unsigned64"); return a_Unsigned64; }
598  const Float32 * getFloat32() const noexcept(false) { assertFormat("Float32"); return a_Float32; }
600  const Float64 * getFloat64() const noexcept(false) { assertFormat("Float64"); return a_Float64; }
601 
632  const Avp* getAvp(AvpId id, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) const noexcept(false) {
633  return _getAvp(id, ocurrence, emode);
634  }
635 
636  Avp* getAvp(AvpId id, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) noexcept(false) {
637  return const_cast<Avp*>(_getAvp(id, ocurrence, emode));
638  }
639 
643  const Avp* getAvp(const char *name, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) const noexcept(false) {
644  return _getAvp(name, ocurrence, emode);
645  }
646 
647  Avp* getAvp(const char *name, int ocurrence = 1, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) noexcept(false) {
648  return const_cast<Avp*>(_getAvp(name, ocurrence, emode));
649  }
650 
651 
652 
654  const Address * getAddress() const noexcept(false) { assertFormat("Address"); return a_Address; }
656  const Time * getTime() const noexcept(false) { assertFormat("Time"); return a_Time; }
658  const UTF8String * getUTF8String() const noexcept(false) { assertFormat("UTF8String"); return a_UTF8String; }
660  const DiameterIdentity * getDiameterIdentity() const noexcept(false) { assertFormat("DiameterIdentity"); return a_DiameterIdentity; }
662  const DiameterURI * getDiameterURI() const noexcept(false) { assertFormat("DiameterURI"); return a_DiameterURI; }
664  const Enumerated * getEnumerated() const noexcept(false) { assertFormat("Enumerated"); return a_Enumerated; }
666  const IPFilterRule * getIPFilterRule() const noexcept(false) { assertFormat("IPFilterRule"); return a_IPFilterRule; }
668  const QoSFilterRule * getQoSFilterRule() const noexcept(false) { assertFormat("QoSFilterRule"); return a_QoSFilterRule; }
670  const Unknown * getUnknown() const noexcept(false) { assertFormat("Unknown"); return a_Unknown; }
671 
672 
682  void decode(const anna::DataBlock &db) noexcept(false);
683 
684 
690  void fromXML(const anna::xml::Node* avpNode) noexcept(false);
691 
692 
701  void code(char* buffer, int &size) const noexcept(false);
702 
703 
704  // Helpers
705 
711  anna::xml::Node* asXML(anna::xml::Node* parent) const ;
712 
720  std::string asXMLString(bool normalize = false) const ;
721 
730  friend bool operator == (const Avp & a1, const Avp & a2) { return (a1.asXMLString() == a2.asXMLString()); }
731 
740  bool isLike(const std::string &pattern) const ;
741 
747  int countAvp(AvpId id) const noexcept(false) { assertFormat("Grouped"); return countAvp(a_avps, id); }
748 
752  int countAvp(const char *name) const noexcept(false);
753 
759  int countChilds() const noexcept(false) { assertFormat("Grouped"); return countChilds(a_avps); }
760 
770  virtual void unknownAvpWithMandatoryBit() const noexcept(false);
771 
772 
773  friend class Message;
774  friend class Engine;
775 };
776 
777 }
778 }
779 }
780 
781 
782 #endif
Definition: Exception.hpp:26
const Address * getAddress() const noexcept(false)
Definition: Avp.hpp:654
static const int HeaderLengthVactive
Definition: Avp.hpp:408
Engine * a_engine
Definition: Avp.hpp:321
static const U8 VBitMask
Definition: Avp.hpp:421
std::pair< AvpId, unsigned int > find_key
Definition: Avp.hpp:82
avp_container::const_iterator const_avp_iterator
Definition: Avp.hpp:79
Definition: Engine.hpp:42
Time * getTime() noexcept(false)
Definition: Avp.hpp:526
OctetString * getOctetString() noexcept(false)
Definition: Avp.hpp:510
_v
Definition: Exception.hpp:26
int countAvp(AvpId id) const noexcept(false)
Definition: Avp.hpp:747
Integer32 * getInteger32() noexcept(false)
Definition: Avp.hpp:512
const Integer32 * getInteger32() const noexcept(false)
Definition: Avp.hpp:590
static const U8 MBitMask
Definition: Avp.hpp:422
Definition: IPFilterRule.hpp:30
Float32 * getFloat32() noexcept(false)
Definition: Avp.hpp:520
const UTF8String * getUTF8String() const noexcept(false)
Definition: Avp.hpp:658
const OctetString * getOctetString() const noexcept(false)
Definition: Avp.hpp:588
const Avp * getAvp(AvpId id, int ocurrence=1, anna::Exception::Mode::_v emode=anna::Exception::Mode::Throw) const noexcept(false)
Definition: Avp.hpp:632
QoSFilterRule * getQoSFilterRule() noexcept(false)
Definition: Avp.hpp:538
Enumerated * getEnumerated() noexcept(false)
Definition: Avp.hpp:534
Definition: Node.hpp:56
Avp * getAvp(AvpId id, int ocurrence=1, anna::Exception::Mode::_v emode=anna::Exception::Mode::Throw) noexcept(false)
Definition: Avp.hpp:636
std::map< find_key, Avp * >::iterator find_iterator
Definition: Avp.hpp:84
bool mandatoryBit() const
Definition: Avp.hpp:581
static const U8 PBitMask
Definition: Avp.hpp:423
const Integer64 * getInteger64() const noexcept(false)
Definition: Avp.hpp:592
const DiameterURI * getDiameterURI() const noexcept(false)
Definition: Avp.hpp:662
const IPFilterRule * getIPFilterRule() const noexcept(false)
Definition: Avp.hpp:666
std::pair< S32, S32 > AvpId
Definition: defines.hpp:31
const Float64 * getFloat64() const noexcept(false)
Definition: Avp.hpp:600
const Enumerated * getEnumerated() const noexcept(false)
Definition: Avp.hpp:664
std::string asXMLString(bool normalize=false) const
const DiameterIdentity * getDiameterIdentity() const noexcept(false)
Definition: Avp.hpp:660
Definition: Avp.hpp:125
Unsigned32 * getUnsigned32() noexcept(false)
Definition: Avp.hpp:516
Definition: OctetString.hpp:30
Definition: Attribute.hpp:35
DiameterURI * getDiameterURI() noexcept(false)
Definition: Avp.hpp:532
const anna::diameter::stack::Avp * getStackAvp() const noexcept(false)
Definition: Avp.hpp:575
Definition: Message.hpp:74
int getVendorId() const
Definition: Avp.hpp:570
Avp * getAvp(const char *name, int ocurrence=1, anna::Exception::Mode::_v emode=anna::Exception::Mode::Throw) noexcept(false)
Definition: Avp.hpp:647
U32 U24
Definition: defines.hpp:96
Definition: DiameterURI.hpp:30
Definition: QoSFilterRule.hpp:30
unsigned char U8
Definition: defines.hpp:62
Definition: Dictionary.hpp:50
Integer64 * getInteger64() noexcept(false)
Definition: Avp.hpp:514
static const int HeaderLengthVinactive
Definition: Avp.hpp:409
void setEncryptionBit(bool activate=true)
Definition: Avp.hpp:475
const Unsigned64 * getUnsigned64() const noexcept(false)
Definition: Avp.hpp:596
avprule_container::const_iterator const_avprule_iterator
Definition: Avp.hpp:46
Definition: DiameterIdentity.hpp:30
Definition: app.hpp:12
Unsigned64 * getUnsigned64() noexcept(false)
Definition: Avp.hpp:518
bool removeAvp(AvpId id, int ocurrence=1) noexcept(false)
Definition: Avp.hpp:552
Definition: Avp.hpp:58
const Time * getTime() const noexcept(false)
Definition: Avp.hpp:656
const Float32 * getFloat32() const noexcept(false)
Definition: Avp.hpp:598
bool vendorBit() const
Definition: Avp.hpp:578
Address * getAddress() noexcept(false)
Definition: Avp.hpp:524
IPFilterRule * getIPFilterRule() noexcept(false)
Definition: Avp.hpp:536
const Unsigned32 * getUnsigned32() const noexcept(false)
Definition: Avp.hpp:594
UTF8String * getUTF8String() noexcept(false)
Definition: Avp.hpp:528
Definition: Format.hpp:45
DiameterIdentity * getDiameterIdentity() noexcept(false)
Definition: Avp.hpp:530
const Avp * getAvp(const char *name, int ocurrence=1, anna::Exception::Mode::_v emode=anna::Exception::Mode::Throw) const noexcept(false)
Definition: Avp.hpp:643
const AvpId & getId() const
Definition: Avp.hpp:565
bool encryptionBit() const
Definition: Avp.hpp:584
Float64 * getFloat64() noexcept(false)
Definition: Avp.hpp:522
std::map< find_key, Avp * > find_container
Definition: Avp.hpp:83
const QoSFilterRule * getQoSFilterRule() const noexcept(false)
Definition: Avp.hpp:668
Avp * addAvp(AvpId id) noexcept(false)
Definition: Avp.hpp:486
avp_container::iterator avp_iterator
Definition: Avp.hpp:78
const Unknown * getUnknown() const noexcept(false)
Definition: Avp.hpp:670
Definition: DataBlock.hpp:24
Definition: functions.hpp:118
Unknown * getUnknown() noexcept(false)
Definition: Avp.hpp:540
int countChilds() const noexcept(false)
Definition: Avp.hpp:759
std::map< int, Avp *> avp_container
Definition: Avp.hpp:74