Add nlohmann/json parser
[anna.git] / source / diameter / codec / EngineImpl.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/codec/EngineImpl.hpp>
11 #include <anna/diameter/codec/Message.hpp>
12 #include <anna/diameter/codec/Avp.hpp>
13 #include <anna/diameter/stack/Engine.hpp>
14 #include <anna/diameter/stack/Dictionary.hpp>
15 #include <anna/diameter/stack/Command.hpp>
16 #include <anna/diameter/internal/sccs.hpp>
17 #include <anna/diameter/defines.hpp>
18
19 #include <anna/xml/xml.hpp>
20 #include <anna/core/tracing/Logger.hpp>
21 #include <anna/core/tracing/TraceMethod.hpp>
22 #include <anna/core/functions.hpp>
23 #include <anna/core/mt/Guard.hpp>
24
25
26 using namespace anna::diameter::codec;
27
28
29 //------------------------------------------------------------------------------
30 //----------------------------------------------------- EngineImpl::EngineImpl()
31 //------------------------------------------------------------------------------
32 EngineImpl::EngineImpl(const char* className, const stack::Dictionary * dictionary) :
33   anna::Component(className),
34   a_dictionary(dictionary),
35   a_validationDepth(ValidationDepth::FirstError),
36   a_validationMode(ValidationMode::AfterDecoding),
37   a_singleFailedAVP(true),
38   a_ignoreFlags(false),
39   a_fixMode(FixMode::BeforeEncoding) {
40   anna::diameter::sccs::activate();
41   anna::xml::functions::initialize();
42 }
43
44
45 //------------------------------------------------------------------------------
46 //------------------------------------------------------ EngineImpl::createAvp()
47 //------------------------------------------------------------------------------
48 Avp* EngineImpl::createAvp(const AvpId *id) throw(anna::RuntimeException) {
49   Avp *result(NULL);
50   anna::Guard guard(this, "diameter::codec::EngineImpl::createAvp");
51
52   if((result = allocateAvp()) == NULL)
53     throw anna::RuntimeException("diameter::codec::EngineImpl::allocateAvp returns NULL", ANNA_FILE_LOCATION);
54
55   // Sets engine
56   result->setEngine((Engine*)this);
57
58   //result->clear(); better clear this at releaseAvp(), see class-help implementation example
59   if(id) result->setId(*id);
60
61   return result;
62 }
63
64
65 //------------------------------------------------------------------------------
66 //-------------------------------------------------- EngineImpl::createMessage()
67 //------------------------------------------------------------------------------
68 Message* EngineImpl::createMessage(const CommandId *id) throw(anna::RuntimeException) {
69   Message *result(NULL);
70   anna::Guard guard(this, "diameter::codec::EngineImpl::createMessage");
71
72   if((result = allocateMessage()) == NULL)
73     throw anna::RuntimeException("diameter::codec::EngineImpl::allocateMessage returns NULL", ANNA_FILE_LOCATION);
74
75   // Sets engine
76   result->setEngine((Engine*)this);
77
78   //result->clear(); better clear this at releaseMessage(), see class-help implementation example
79   if(id) result->setId(*id);
80
81   return result;
82 }
83
84
85 //------------------------------------------------------------------------------
86 //-------------------------------------------------- EngineImpl::createMessage()
87 //------------------------------------------------------------------------------
88 Message *EngineImpl::createMessage(const std::string & xmlPathFile) throw(anna::RuntimeException) {
89   Message *result = createMessage();
90   result->loadXMLFile(xmlPathFile);
91   return result;
92 }
93
94
95
96 std::string EngineImpl::asString(void) const throw() {
97   std::string result = anna::Component::asString();
98   result += "\nValidationDepth: ";
99   result += asText(a_validationDepth);
100   result += "\nValidationMode: ";
101   result += asText(a_validationMode);
102   result += "\nSingle Failed-AVP: ";
103   result += a_singleFailedAVP ? "yes" : "no";
104   result += "\nIgnore flags: ";
105   result += a_ignoreFlags ? "yes" : "no";
106   result += "\nFixMode: ";
107   result += asText(a_fixMode);
108   result += "\nActivated Dictionary: ";
109   result += a_dictionary ? (a_dictionary->getName()) : "<null>";
110   return result;
111 }
112
113 //------------------------------------------------------------------------------
114 //---------------------------------------------------------- EngineImpl::asXML()
115 //------------------------------------------------------------------------------
116 anna::xml::Node* EngineImpl::asXML(anna::xml::Node* parent) const
117 throw() {
118   parent = anna::Component::asXML(parent);
119   anna::xml::Node* result = parent->createChild("diameter.codec.EngineImpl");
120   result->createAttribute("ValidationDepth", asText(a_validationDepth));
121   result->createAttribute("ValidationMode", asText(a_validationMode));
122   result->createAttribute("SingleFailedAVP", a_singleFailedAVP ? "yes" : "no");
123   result->createAttribute("IgnoreFlags", a_ignoreFlags ? "yes" : "no");
124   result->createAttribute("FixMode", asText(a_fixMode));
125   result->createChild("EngineImpl.ActivatedDictionary");
126
127   if(a_dictionary) a_dictionary->asXML(result);
128
129   return result;
130 }
131
132 //------------------------------------------------------------------------------
133 //--------------------------------------------------------- EngineImpl::asText()
134 //------------------------------------------------------------------------------
135 const char* EngineImpl::asText(const ValidationDepth::_v vd)
136 throw() {
137   static const char* text [] = { "Complete", "FirstError" };
138   return text [vd];
139 }
140
141 //------------------------------------------------------------------------------
142 //--------------------------------------------------------- EngineImpl::asText()
143 //------------------------------------------------------------------------------
144 const char* EngineImpl::asText(const ValidationMode::_v vm)
145 throw() {
146   static const char* text [] = { "BeforeEncoding", "AfterDecoding", "Always", "Never" };
147   return text [vm];
148 }
149
150 //------------------------------------------------------------------------------
151 //--------------------------------------------------------- EngineImpl::asText()
152 //------------------------------------------------------------------------------
153 const char* EngineImpl::asText(const FixMode::_v fm)
154 throw() {
155   static const char* text [] = { "BeforeEncoding", "AfterDecoding", "Always", "Never" };
156   return text [fm];
157 }
158
159 //------------------------------------------------------------------------------
160 //---------------------------------------------- EngineImpl::validationAnomaly()
161 //------------------------------------------------------------------------------
162 void EngineImpl::validationAnomaly(const std::string & description) const throw(anna::RuntimeException) {
163   std::string msg = "Validation error: ";
164
165   if(a_validationDepth == ValidationDepth::FirstError)
166     throw anna::RuntimeException(msg + description, ANNA_FILE_LOCATION);
167
168   LOGWARNING(anna::Logger::warning(msg + description, ANNA_FILE_LOCATION));
169 }
170
171
172 //------------------------------------------------------------------------------
173 //--------------------------------------------------- EngineImpl::avpIdForName()
174 //------------------------------------------------------------------------------
175 anna::diameter::AvpId EngineImpl::avpIdForName(const char * name) throw(anna::RuntimeException) {
176   if(!name)
177     throw anna::RuntimeException("Provided NULL Avp Logical Name", ANNA_FILE_LOCATION);
178
179   if(!a_dictionary) {
180     std::string msg = "Cannot find identifier '"; msg += name;
181     msg += "' for the avp: no dictionary available";
182     throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
183   }
184
185   const stack::Avp * stackAvp = a_dictionary->getAvp(name);
186
187   if(!stackAvp) {
188     std::string msg = "Cannot find identifier '"; msg += name;
189     msg += "' for the avp at the available dictionary";
190     throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
191   }
192
193   return (stackAvp->getId());
194 }
195
196
197 //------------------------------------------------------------------------------
198 //----------------------------------------------- EngineImpl::commandIdForName()
199 //------------------------------------------------------------------------------
200 anna::diameter::CommandId EngineImpl::commandIdForName(const char * name) throw(anna::RuntimeException) {
201   if(!name)
202     throw anna::RuntimeException("Provided NULL Command Logical Name", ANNA_FILE_LOCATION);
203
204   if(!a_dictionary) {
205     std::string msg = "Cannot find identifier '"; msg += name;
206     msg += "' for the command: no dictionary available";
207     throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
208   }
209
210   const stack::Command * stackCommand = a_dictionary->getCommand(name);
211
212   if(!stackCommand) {
213     std::string msg = "Cannot find identifier '"; msg += name;
214     msg += "' for the command at the available dictionary";
215     throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
216   }
217
218   return (stackCommand->getId());
219 }
220