Fix local server for multiple applications
[anna.git] / diameter / stack / Command.cpp
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 // Local
10 #include <anna/diameter/stack/Command.hpp>
11 #include <anna/diameter/stack/Avp.hpp>
12 #include <anna/diameter/functions.hpp>
13 #include <anna/diameter/stack/Dictionary.hpp>
14
15 #include <anna/core/functions.hpp>
16 #include <anna/xml/xml.hpp>
17
18 //using namespace diameter::stack;
19
20
21 //------------------------------------------------------------------------------
22 //-------------------------------------------------------- Command::addAvpRule()
23 //------------------------------------------------------------------------------
24 void anna::diameter::stack::Command::addAvpRule(const AvpRule & avpRule) throw(anna::RuntimeException) {
25   if(avpRule.isFixed()) {
26     if(!a_allowFixedRule) {
27       std::string s_ex = anna::functions::asString("Incorrect position for fixed avp rule '<%s>' within command '%s'", avpRule.getAvpName().c_str(), getName().c_str());
28       s_ex += ". Fixed avp rules must be located at the beginning";
29       throw anna::RuntimeException(s_ex, ANNA_FILE_LOCATION);
30     }
31   } else a_allowFixedRule = false;
32
33   //a_avprules[(avpRule.getAvp())->getId()] = avpRule;
34
35   // Restriction for redefinition (at this same level) of two rules for the same avp:
36   if(isChild(avpRule.getId())) {
37     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());
38     throw anna::RuntimeException(s_ex, ANNA_FILE_LOCATION);
39   }
40
41   a_avprules[a_avprulePosition++] = avpRule;
42 }
43
44
45 //------------------------------------------------------------------------------
46 //----------------------------------------------------------- Command::isChild()
47 //------------------------------------------------------------------------------
48 bool anna::diameter::stack::Command::isChild(const AvpId & avpId) const throw() {
49   for(const_avprule_iterator it = avprule_begin(); it != avprule_end(); it++)
50     if(avpId == ((*it).second.getId()))
51       return true;
52
53   return false;
54 }
55
56
57 //------------------------------------------------------------------------------
58 //---------------------------------------------------------- Command::asString()
59 //------------------------------------------------------------------------------
60 std::string anna::diameter::stack::Command::asString(void) const throw() {
61   std::string trace;
62   //trace = "Command '";
63   trace = "'";
64   trace += a_name;
65   trace += "' ";
66   trace += anna::diameter::functions::commandIdAsPairString(a_id);
67   trace += "\n";
68
69   if(isEmpty()) {
70     trace += DICTIONARY_AVPRULE_TAB;
71     trace += "No Avp rules defined\n";
72   } else {
73     for(const_avprule_iterator it = avprule_begin(); it != avprule_end(); it++) {
74       // Align qualifier
75       std::string qual = (*it).second.getQual();
76       int NumberOfSpaces = strlen(DICTIONARY_AVPRULE_TAB) - qual.size();
77
78       for(int k = 0; k < NumberOfSpaces; k++) trace += " ";
79
80       trace += (*it).second.asString();
81       trace += "\n";
82     }
83   }
84
85   return (trace);
86 }
87
88
89 //------------------------------------------------------------------------------
90 //------------------------------------------------------------- Command::asXML()
91 //------------------------------------------------------------------------------
92 anna::xml::Node* anna::diameter::stack::Command::asXML(anna::xml::Node* parent) const throw() {
93 //   <!ELEMENT command (avprule*)>
94 //   <!ATTLIST command name CDATA #REQUIRED code CDATA #REQUIRED type (Request | Answer) #REQUIRED>
95   anna::xml::Node* result = parent->createChild("command");
96   result->createAttribute("name", a_name);
97   result->createAttribute("code", anna::functions::asString(a_id.first));
98   result->createAttribute("type", anna::functions::asString(a_id.second ? "Request" : "Answer"));
99
100   for(const_avprule_iterator it = avprule_begin(); it != avprule_end(); it++)
101     (*it).second.asXML(result);
102
103   return result;
104 }
105