Updated license
[anna.git] / source / diameter / stack / Command.cpp
1 // ANNA - Anna is Not Nothingness 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 // Local
38 #include <anna/diameter/stack/Command.hpp>
39 #include <anna/diameter/stack/Avp.hpp>
40 #include <anna/diameter/functions.hpp>
41 #include <anna/diameter/stack/Dictionary.hpp>
42
43 #include <anna/core/functions.hpp>
44 #include <anna/xml/xml.hpp>
45
46 //using namespace diameter::stack;
47
48
49 //------------------------------------------------------------------------------
50 //-------------------------------------------------------- Command::addAvpRule()
51 //------------------------------------------------------------------------------
52 void anna::diameter::stack::Command::addAvpRule(const AvpRule & avpRule) throw(anna::RuntimeException) {
53   if(avpRule.isFixed()) {
54     if(!a_allowFixedRule) {
55       std::string s_ex = anna::functions::asString("Incorrect position for fixed avp rule '<%s>' within command '%s'", avpRule.getAvpName().c_str(), getName().c_str());
56       s_ex += ". Fixed avp rules must be located at the beginning";
57       throw anna::RuntimeException(s_ex, ANNA_FILE_LOCATION);
58     }
59   } else a_allowFixedRule = false;
60
61   //a_avprules[(avpRule.getAvp())->getId()] = avpRule;
62
63   // Restriction for redefinition (at this same level) of two rules for the same avp:
64   if(isChild(avpRule.getId())) {
65     std::string s_ex = anna::functions::asString("Cannot add two rules for avp '%s', at the same level within command '%s'", avpRule.getAvpName().c_str(), getName().c_str());
66     throw anna::RuntimeException(s_ex, ANNA_FILE_LOCATION);
67   }
68
69   a_avprules[a_avprulePosition++] = avpRule;
70 }
71
72
73 //------------------------------------------------------------------------------
74 //----------------------------------------------------------- Command::isChild()
75 //------------------------------------------------------------------------------
76 bool anna::diameter::stack::Command::isChild(const AvpId & avpId) const throw() {
77   for(const_avprule_iterator it = avprule_begin(); it != avprule_end(); it++)
78     if(avpId == ((*it).second.getId()))
79       return true;
80
81   return false;
82 }
83
84
85 //------------------------------------------------------------------------------
86 //---------------------------------------------------------- Command::asString()
87 //------------------------------------------------------------------------------
88 std::string anna::diameter::stack::Command::asString(void) const throw() {
89   std::string trace;
90   //trace = "Command '";
91   trace = "'";
92   trace += a_name;
93   trace += "' ";
94   trace += anna::diameter::functions::commandIdAsPairString(a_id);
95   trace += "\n";
96
97   if(isEmpty()) {
98     trace += DICTIONARY_AVPRULE_TAB;
99     trace += "No Avp rules defined\n";
100   } else {
101     for(const_avprule_iterator it = avprule_begin(); it != avprule_end(); it++) {
102       // Align qualifier
103       std::string qual = (*it).second.getQual();
104       int NumberOfSpaces = strlen(DICTIONARY_AVPRULE_TAB) - qual.size();
105
106       for(register int k = 0; k < NumberOfSpaces; k++) trace += " ";
107
108       trace += (*it).second.asString();
109       trace += "\n";
110     }
111   }
112
113   return (trace);
114 }
115
116
117 //------------------------------------------------------------------------------
118 //------------------------------------------------------------- Command::asXML()
119 //------------------------------------------------------------------------------
120 anna::xml::Node* anna::diameter::stack::Command::asXML(anna::xml::Node* parent) const throw() {
121 //   <!ELEMENT command (avprule*)>
122 //   <!ATTLIST command name CDATA #REQUIRED code CDATA #REQUIRED type (Request | Answer) #REQUIRED>
123   anna::xml::Node* result = parent->createChild("command");
124   result->createAttribute("name", a_name);
125   result->createAttribute("code", anna::functions::asString(a_id.first));
126   result->createAttribute("type", anna::functions::asString(a_id.second ? "Request" : "Answer"));
127
128   for(const_avprule_iterator it = avprule_begin(); it != avprule_end(); it++)
129     (*it).second.asXML(result);
130
131   return result;
132 }
133