First commit
[anna.git] / include / anna / diameter / stack / Avp.hpp
1 // ANNA - Anna is Not 'N' Anymore
2 //
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
4 //
5 // https://bitbucket.org/testillano/anna
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 //
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
16 // distribution.
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.
20 //
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.
32 //
33 // Authors: eduardo.ramos.testillano@gmail.com
34 //          cisco.tierra@gmail.com
35
36
37 #ifndef anna_diameter_stack_Avp_hpp
38 #define anna_diameter_stack_Avp_hpp
39
40
41 // Local
42 #include <anna/diameter/defines.hpp>
43 #include <anna/diameter/stack/AvpRule.hpp>
44 #include <anna/core/util/MultiRangeExpression.hpp>
45
46 #include <anna/core/RuntimeException.hpp>
47 #include <anna/config/defines.hpp>
48
49 // STL
50 #include <string>
51 #include <map>
52
53
54
55 namespace anna {
56 namespace xml {
57 class Node;
58 }
59 }
60
61
62
63
64 namespace anna {
65
66 namespace diameter {
67
68 namespace stack {
69
70
71 //typedef std::map<AvpId, AvpRule> avprule_container;
72 typedef std::map < int /*position*/, AvpRule > avprule_container;
73 typedef avprule_container::iterator avprule_iterator;
74 typedef avprule_container::const_iterator const_avprule_iterator;
75
76
77 class Format;
78 class Dictionary;
79
80 //------------------------------------------------------------------------------
81 //-------------------------------------------------------------------- class Avp
82 //------------------------------------------------------------------------------
83 /**
84 * Avp Reference information
85 */
86 class Avp {
87
88 public:
89
90   struct lessLabel {
91     bool operator()(const std::string &d1, const std::string &d2) const {
92       return (atoi(d1.c_str()) < atoi(d2.c_str()));
93     }
94   };
95   typedef std::map < std::string /* data */, std::string /* alias */, lessLabel > label_container;
96   typedef label_container::iterator label_iterator;
97   typedef label_container::const_iterator const_label_iterator;
98
99
100
101   struct FlagRule {
102     enum _v {
103       None = -1, // Initialized
104       must,
105       may,
106       shouldnot,
107       mustnot
108     };
109
110     anna_declare_enum(FlagRule);
111
112     /**
113     * FlagRule description
114     * @param v FlagRule type
115     * @return FlagRule description
116     */
117     static const char* asText(const FlagRule::_v v) throw(anna::RuntimeException) {
118       return asCString(v);
119     }
120   };
121
122
123 private:
124
125   const Dictionary *a_dictionary;
126   AvpId a_id;
127   std::string a_name;
128   std::string a_formatName;
129   std::string a_vendorName;
130
131   // Flag Rules:
132   FlagRule::_v a_vBit, a_mBit, a_pBit;
133   bool a_mayEncrypt;
134
135   MultiRangeExpression a_enums;
136   label_container a_labels;
137
138   // Grouped:
139   avprule_container a_avprules;
140   bool a_allowFixedRule;
141   int a_avprulePosition;
142
143   void _initializeEnumsLabelsAndRules() throw() {
144     a_enums.setLiteral("");
145     a_labels.clear();
146     a_avprules.clear();
147     a_allowFixedRule = true;
148     a_avprulePosition = 0;
149   }
150
151   void _initialize(const Dictionary *d) throw() {
152     a_dictionary = d;
153     a_name = "";
154     a_formatName = "";
155     a_vendorName = "";
156     a_vBit = FlagRule::mustnot;
157     a_mBit = FlagRule::must;
158     a_pBit = FlagRule::may;
159     a_mayEncrypt = true;
160     _initializeEnumsLabelsAndRules();
161   }
162
163 public:
164
165   Avp(const Dictionary *d = NULL) { _initialize(d); }
166   ~Avp();
167
168
169   // get
170   const AvpId & getId(void) const throw() { return a_id; }
171   const std::string & getName(void) const throw() { return a_name; }
172   const std::string & getFormatName(void) const throw() { return a_formatName; }
173
174   const FlagRule::_v & getVbit(void) const throw() { return a_vBit; }
175   const FlagRule::_v & getMbit(void) const throw() { return a_mBit; }
176   const FlagRule::_v & getPbit(void) const throw() { return a_pBit; }
177   bool mayEncrypt(void) const throw() { return a_mayEncrypt; }
178
179   const char * getEnums(void) const throw() { return a_enums.getLiteral(); }
180   const char * getAlias(const std::string data) const throw() {
181     std::map<std::string, std::string>::const_iterator it = a_labels.find(data);
182     return ((it != a_labels.end()) ? ((*it).second.c_str()) : NULL);
183   }
184
185   // containers
186   const_avprule_iterator avprule_begin() const throw() { return a_avprules.begin(); }
187   const_avprule_iterator avprule_end() const throw() { return a_avprules.end(); }
188   int avprule_size() const throw() { return a_avprules.size(); }
189
190   const_label_iterator label_begin() const throw() { return a_labels.begin(); }
191   const_label_iterator label_end() const throw() { return a_labels.end(); }
192   int label_size() const throw() { return a_labels.size(); }
193
194
195   // helpers
196   bool allowEnum(int value) const throw() { return a_enums.contain(value); }
197   bool hasAliases(void) const throw() { return (a_labels.size() != 0); }
198   bool isChild(const AvpId & avp) const throw();
199   std::string getFlagsDescription(void) const throw();
200   std::string getFlagRulesDescription(void) const throw();
201   const Format * getFormat() const throw();
202
203   std::string asString(void) const throw();
204   anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
205
206   // operators
207
208   // set
209   void setCode(const S32 & c) throw(anna::RuntimeException) {
210     if(c < 0) throw anna::RuntimeException("Negative avp-code not allowed", ANNA_FILE_LOCATION);
211
212     a_id.first = c;
213   }
214
215   void setVendorId(const S32 & v) throw(anna::RuntimeException) {
216     if(v < 0) throw anna::RuntimeException("Negative vendor-id not allowed", ANNA_FILE_LOCATION);
217
218     a_id.second = v;
219   }
220
221   void setName(const std::string & n) throw(anna::RuntimeException) {
222     if(n == "") throw anna::RuntimeException("Empty avp-name string not allowed", ANNA_FILE_LOCATION);
223
224     a_name = n;
225   }
226
227   void initialize(const Dictionary *d = NULL) throw() { _initialize(d); }
228   void setVendorName(const std::string & vn) throw() { a_vendorName = vn; }
229   void setFormatName(const std::string & fn) throw() { a_formatName = fn; }
230   void setVbit(const FlagRule::_v &v) throw() { a_vBit = v; }
231   void setMbit(const FlagRule::_v &m) throw() { a_mBit = m; }
232   void setPbit(const FlagRule::_v &p) throw() { a_pBit = p; }
233   void setMayEncrypt(bool me) throw() { a_mayEncrypt = me; }
234
235   void setEnums(const char * e) throw() { a_enums.setLiteral(e); }
236
237   // After format configuration:
238   void addLabel(const std::string & data,  const std::string & alias) throw(anna::RuntimeException);
239   void addAvpRule(const AvpRule & avpRule) throw(anna::RuntimeException);
240 };
241
242
243 }
244 }
245 }
246
247
248 #endif