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/core/core.hpp>
11 #include <anna/diameter/functions.hpp>
12 #include <anna/time/functions.hpp>
13 #include <anna/diameter.comm/Response.hpp>
16 #include "MyDiameterEntity.hpp"
17 #include "Launcher.hpp"
20 void MyDiameterEntity::eventRequestRetransmission(const anna::diameter::comm::ClientSession* clientSession, anna::diameter::comm::Message *request) throw() {
22 LOGMETHOD(anna::TraceMethod tm("launcher::MyDiameterEntity", "eventRequestRetransmission", ANNA_FILE_LOCATION));
25 Entity::eventRequestRetransmission(clientSession, request); // warning trace
28 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
29 CommandLine& cl(anna::CommandLine::instantiate());
31 anna::diameter::CommandId cid = anna::diameter::codec::functions::getCommandId(request->getBody());
34 std::string msg = "Request retransmitted: ";
35 msg += anna::diameter::functions::commandIdAsPairString(cid);
36 msg += " | DiameterServer: ";
37 msg += anna::functions::socketLiteralAsString(clientSession->getAddress(), clientSession->getPort());
38 msg += " | EventTime: ";
39 msg += anna::time::functions::currentTimeAsString();
40 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
43 // Write retransmission
44 if(my_app.logEnabled()) my_app.writeLogFile(request->getBody(), "retry", clientSession->asString(), a_codecEngine);
48 void MyDiameterEntity::eventRequest(anna::diameter::comm::ClientSession *clientSession, const anna::DataBlock &message)
49 throw(anna::RuntimeException) {
50 LOGMETHOD(anna::TraceMethod tm("launcher::MyDiameterEntity", "eventRequest", ANNA_FILE_LOCATION));
52 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
53 CommandLine& cl(anna::CommandLine::instantiate());
55 anna::diameter::CommandId cid = anna::diameter::codec::functions::getCommandId(message);
58 std::string msg = "Request received: ";
59 msg += anna::diameter::functions::commandIdAsPairString(cid);
60 msg += " | DiameterServer: ";
61 msg += anna::functions::socketLiteralAsString(clientSession->getAddress(), clientSession->getPort());
62 msg += " | EventTime: ";
63 msg += anna::time::functions::currentTimeAsString();
64 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
68 if(my_app.logEnabled()) my_app.writeLogFile(message, "recvfe", clientSession->asString(), a_codecEngine);
70 // Lookup reacting answers list:
72 anna::diameter::codec::Message *answer_message = a_reactingAnswers.getMessage(code);
75 my_app.getCommunicator()->prepareAnswer(answer_message, message);
78 anna::diameter::comm::Message *msg = my_app.createCommMessage();
79 msg->setBody(answer_message->code());
80 /* response = NULL =*/clientSession->send(msg);
81 my_app.releaseCommMessage(msg);
83 if(my_app.logEnabled()) my_app.writeLogFile(*answer_message, "sent2e", clientSession->asString());
84 } catch(anna::RuntimeException &ex) {
87 if(my_app.logEnabled()) my_app.writeLogFile(*answer_message, "send2eError", clientSession->asString());
90 // Pop front the reacting answer:
91 a_reactingAnswers.nextMessage(code);
97 std::string msg = "No answers programmed (maybe sold out) for request coming from entity: ";
98 msg += anna::diameter::functions::commandIdAsPairString(cid);
99 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
102 // not found: forward to client (if exists)
103 // Forward to client:
104 anna::diameter::comm::LocalServer *localServer = my_app.getDiameterLocalServer();
106 if(localServer && (cid != anna::diameter::helpers::base::COMMANDID__Capabilities_Exchange_Request) /* don't forward CER */) {
108 anna::diameter::comm::Message *msg = my_app.createCommMessage();
109 msg->forwardEndToEnd(); // end-to-end will be kept
110 msg->setBody(message);
111 msg->setRequestClientSessionKey(clientSession->getKey());
112 bool success = localServer->send(msg);
115 if(my_app.logEnabled()) {
116 anna::diameter::comm::ServerSession *usedServerSession = localServer->getLastUsedResource();
117 std::string detail = usedServerSession ? usedServerSession->asString() : "<null server session>"; // esto no deberia ocurrir
118 my_app.writeLogFile(message, (success ? "fwd2c" : "fwd2cError"), detail, a_codecEngine);
120 } catch(anna::RuntimeException &ex) {
126 void MyDiameterEntity::eventResponse(const anna::diameter::comm::Response &response)
127 throw(anna::RuntimeException) {
128 LOGMETHOD(anna::TraceMethod tm("launcher::MyDiameterEntity", "eventResponse", ANNA_FILE_LOCATION));
129 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
130 CommandLine& cl(anna::CommandLine::instantiate());
131 anna::diameter::comm::ClassCode::_v code = response.getClassCode();
132 anna::diameter::comm::Response::ResultCode::_v result = response.getResultCode();
133 anna::diameter::comm::Message* request = const_cast<anna::diameter::comm::Message*>(response.getRequest());
134 const anna::DataBlock* message = response.getMessage();
135 const anna::diameter::comm::ClientSession *clientSession = static_cast<const anna::diameter::comm::ClientSession *>(response.getSession());
136 bool isBindResponse = (code == anna::diameter::comm::ClassCode::Bind);
137 bool isApplicationMessage = (code == anna::diameter::comm::ClassCode::ApplicationMessage);
138 bool contextExpired = (result == anna::diameter::comm::Response::ResultCode::Timeout);
139 bool isUnavailable = (result == anna::diameter::comm::Response::ResultCode::DiameterUnavailable);
140 bool isOK = (result == anna::diameter::comm::Response::ResultCode::Success);
142 anna::diameter::CommandId request_cid = request->getCommandId();
145 std::string msg = "Response received for original diameter request: ";
146 msg += anna::diameter::functions::commandIdAsPairString(request_cid);
147 msg += " | Response: ";
148 msg += response.asString();
149 msg += " | DiameterServer: ";
150 msg += anna::functions::socketLiteralAsString(clientSession->getAddress(), clientSession->getPort());
151 msg += " | EventTime: ";
152 msg += anna::time::functions::currentTimeAsString();
153 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
157 //if (isApplicationMessage)
158 LOGWARNING(anna::Logger::warning("Diameter entity unavailable for Diameter Request", ANNA_FILE_LOCATION));
162 //if (isApplicationMessage)
163 LOGWARNING(anna::Logger::warning("Context Expired for Diameter Request which was sent to the entity", ANNA_FILE_LOCATION));
165 if(request_cid != anna::diameter::helpers::base::COMMANDID__Capabilities_Exchange_Request) { // don't trace CEA
166 if(my_app.logEnabled()) my_app.writeLogFile(*request, "req2e-expired", clientSession->asString(), a_codecEngine);
172 std::string msg = "Received response for diameter message: ";
173 msg += anna::diameter::functions::commandIdAsPairString(request_cid);
174 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
178 if(request_cid != anna::diameter::helpers::base::COMMANDID__Capabilities_Exchange_Request) { // don't trace CEA
179 if(my_app.logEnabled()) {
180 my_app.writeLogFile(*message, "recvfe", clientSession->asString(), a_codecEngine);
184 // Forward to client:
185 anna::diameter::comm::LocalServer *localServer = my_app.getDiameterLocalServer();
187 if(localServer && (request_cid != anna::diameter::helpers::base::COMMANDID__Capabilities_Exchange_Request) /* don't forward CEA */) {
189 anna::diameter::comm::Message *msg = my_app.createCommMessage();
190 msg->forwardEndToEnd(); // end-to-end will be kept
191 msg->setBody(*message);
192 bool success = localServer->send(msg, request->getRequestServerSessionKey());
193 my_app.releaseCommMessage(msg);
194 my_app.releaseCommMessage(request);
197 anna::diameter::comm::ServerSession *usedServerSession = my_app.getMyDiameterEngine()->findServerSession(request->getRequestServerSessionKey());
198 std::string detail = usedServerSession ? usedServerSession->asString() : "<null server session>"; // esto no deberia ocurrir
200 if(my_app.logEnabled()) {
201 my_app.writeLogFile(*message, (success ? "fwd2c" : "fwd2cError"), detail, a_codecEngine);
203 } catch(anna::RuntimeException &ex) {
210 if(isOK || contextExpired) my_app.sendBurstMessage();
213 void MyDiameterEntity::eventUnknownResponse(anna::diameter::comm::ClientSession *clientSession, const anna::DataBlock &message)
214 throw(anna::RuntimeException) {
215 LOGMETHOD(anna::TraceMethod tm("launcher::MyDiameterEntity", "eventUnknownResponse", ANNA_FILE_LOCATION));
216 // Performance stats:
217 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
219 anna::diameter::CommandId cid = anna::diameter::codec::functions::getCommandId(message);
222 std::string msg = "Out-of-context response received from entity: ";
223 msg += anna::diameter::functions::commandIdAsPairString(cid);
224 msg += " | DiameterServer: ";
225 msg += anna::functions::socketLiteralAsString(clientSession->getAddress(), clientSession->getPort());
226 msg += " | EventTime: ";
227 msg += anna::time::functions::currentTimeAsString();
228 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
232 if(my_app.logEnabled()) my_app.writeLogFile(message, "recvfe-ans-unknown", clientSession->asString(), a_codecEngine);
235 void MyDiameterEntity::eventDPA(anna::diameter::comm::ClientSession *clientSession, const anna::DataBlock &message)
236 throw(anna::RuntimeException) {
237 LOGMETHOD(anna::TraceMethod tm("launcher::MyDiameterEntity", "eventDPA", ANNA_FILE_LOCATION));
238 // Performance stats:
239 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
241 anna::diameter::CommandId cid = anna::diameter::codec::functions::getCommandId(message);
244 std::string msg = "Disconnect-Peer-Answer received from entity: ";
245 msg += anna::diameter::functions::commandIdAsPairString(cid);
246 msg += " | DiameterServer: ";
247 msg += anna::functions::socketLiteralAsString(clientSession->getAddress(), clientSession->getPort());
248 msg += " | EventTime: ";
249 msg += anna::time::functions::currentTimeAsString();
250 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
254 if(my_app.logEnabled()) my_app.writeLogFile(message, "recvfe", clientSession->asString(), a_codecEngine);