1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
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 //
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>
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>
26 using namespace anna::diameter::codec;
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),
39 a_fixMode(FixMode::BeforeEncoding) {
40 anna::diameter::sccs::activate();
41 anna::xml::functions::initialize();
45 //------------------------------------------------------------------------------
46 //------------------------------------------------------ EngineImpl::createAvp()
47 //------------------------------------------------------------------------------
48 Avp* EngineImpl::createAvp(const AvpId *id) throw(anna::RuntimeException) {
50 anna::Guard guard(this, "diameter::codec::EngineImpl::createAvp");
52 if((result = allocateAvp()) == NULL)
53 throw anna::RuntimeException("diameter::codec::EngineImpl::allocateAvp returns NULL", ANNA_FILE_LOCATION);
56 result->setEngine((Engine*)this);
58 //result->clear(); better clear this at releaseAvp(), see class-help implementation example
59 if(id) result->setId(*id);
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");
72 if((result = allocateMessage()) == NULL)
73 throw anna::RuntimeException("diameter::codec::EngineImpl::allocateMessage returns NULL", ANNA_FILE_LOCATION);
76 result->setEngine((Engine*)this);
78 //result->clear(); better clear this at releaseMessage(), see class-help implementation example
79 if(id) result->setId(*id);
85 //------------------------------------------------------------------------------
86 //-------------------------------------------------- EngineImpl::createMessage()
87 //------------------------------------------------------------------------------
88 Message *EngineImpl::createMessage(const std::string & xmlPathFile) throw(anna::RuntimeException) {
89 Message *result = createMessage();
90 result->loadXML(xmlPathFile);
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>";
113 //------------------------------------------------------------------------------
114 //---------------------------------------------------------- EngineImpl::asXML()
115 //------------------------------------------------------------------------------
116 anna::xml::Node* EngineImpl::asXML(anna::xml::Node* parent) const
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 anna::xml::Node* dictionary = result->createChild("EngineImpl.ActivatedDictionary");
127 if(a_dictionary) a_dictionary->asXML(result);
132 //------------------------------------------------------------------------------
133 //--------------------------------------------------------- EngineImpl::asText()
134 //------------------------------------------------------------------------------
135 const char* EngineImpl::asText(const ValidationDepth::_v vd)
137 static const char* text [] = { "Complete", "FirstError" };
141 //------------------------------------------------------------------------------
142 //--------------------------------------------------------- EngineImpl::asText()
143 //------------------------------------------------------------------------------
144 const char* EngineImpl::asText(const ValidationMode::_v vm)
146 static const char* text [] = { "BeforeEncoding", "AfterDecoding", "Always", "Never" };
150 //------------------------------------------------------------------------------
151 //--------------------------------------------------------- EngineImpl::asText()
152 //------------------------------------------------------------------------------
153 const char* EngineImpl::asText(const FixMode::_v fm)
155 static const char* text [] = { "BeforeEncoding", "AfterDecoding", "Always", "Never" };
159 //------------------------------------------------------------------------------
160 //---------------------------------------------- EngineImpl::validationAnomaly()
161 //------------------------------------------------------------------------------
162 void EngineImpl::validationAnomaly(const std::string & description) const throw(anna::RuntimeException) {
163 std::string msg = "Validation error: ";
165 if(a_validationDepth == ValidationDepth::FirstError)
166 throw anna::RuntimeException(msg + description, ANNA_FILE_LOCATION);
168 LOGWARNING(anna::Logger::warning(msg + description, ANNA_FILE_LOCATION));
172 //------------------------------------------------------------------------------
173 //--------------------------------------------------- EngineImpl::avpIdForName()
174 //------------------------------------------------------------------------------
175 anna::diameter::AvpId EngineImpl::avpIdForName(const char * name) throw(anna::RuntimeException) {
177 throw anna::RuntimeException("Provided NULL Avp Logical Name", ANNA_FILE_LOCATION);
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);
185 const stack::Avp * stackAvp = a_dictionary->getAvp(name);
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);
193 return (stackAvp->getId());
197 //------------------------------------------------------------------------------
198 //----------------------------------------------- EngineImpl::commandIdForName()
199 //------------------------------------------------------------------------------
200 anna::diameter::CommandId EngineImpl::commandIdForName(const char * name) throw(anna::RuntimeException) {
202 throw anna::RuntimeException("Provided NULL Command Logical Name", ANNA_FILE_LOCATION);
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);
210 const stack::Command * stackCommand = a_dictionary->getCommand(name);
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);
218 return (stackCommand->getId());