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
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>
43 #include <anna/core/functions.hpp>
44 #include <anna/xml/xml.hpp>
46 //using namespace diameter::stack;
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);
59 } else a_allowFixedRule = false;
61 //a_avprules[(avpRule.getAvp())->getId()] = avpRule;
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);
69 a_avprules[a_avprulePosition++] = avpRule;
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()))
85 //------------------------------------------------------------------------------
86 //---------------------------------------------------------- Command::asString()
87 //------------------------------------------------------------------------------
88 std::string anna::diameter::stack::Command::asString(void) const throw() {
90 //trace = "Command '";
94 trace += anna::diameter::functions::commandIdAsPairString(a_id);
98 trace += DICTIONARY_AVPRULE_TAB;
99 trace += "No Avp rules defined\n";
101 for(const_avprule_iterator it = avprule_begin(); it != avprule_end(); it++) {
103 std::string qual = (*it).second.getQual();
104 int NumberOfSpaces = strlen(DICTIONARY_AVPRULE_TAB) - qual.size();
106 for(int k = 0; k < NumberOfSpaces; k++) trace += " ";
108 trace += (*it).second.asString();
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"));
128 for(const_avprule_iterator it = avprule_begin(); it != avprule_end(); it++)
129 (*it).second.asXML(result);