+// ANNA - Anna is Not Nothingness Anymore //
+// //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
+// //
+// See project site at http://redmine.teslayout.com/projects/anna-suite //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
+
+
+// Project
+#include <anna/diameter/helpers/base/functions.hpp>
+#include <anna/diameter/helpers/dcca/functions.hpp>
+#include <anna/http/Transport.hpp>
+
+// Process
+#include <MyCommunicator.hpp>
+
+
+void MyCommunicator::prepareAnswer(anna::diameter::codec::Message *answer, const anna::DataBlock &request) const throw() {
+ // Sequence values (hop-by-hop and end-to-end), session-id and subscription-id avps, are mirrored to the peer which sent the request.
+ // If user wants to test a specific answer without changing it, use send operations better than programming.
+ // Sequence substitution:
+ answer->setHopByHop(anna::diameter::codec::functions::getHopByHop(request));
+ answer->setEndToEnd(anna::diameter::codec::functions::getEndToEnd(request));
+
+ // Session-Id substitution:
+ try {
+ std::string sessionId = anna::diameter::helpers::base::functions::getSessionId(request);
+ LOGDEBUG(
+ std::string msg = "Extracted Session-Id: ";
+ msg += sessionId;
+ anna::Logger::debug(msg, ANNA_FILE_LOCATION);
+ );
+ answer->getAvp("Session-Id")->getUTF8String()->setValue(sessionId);
+ } catch(anna::RuntimeException &ex) {
+ ex.trace();
+ }
+
+ // Subscription-Id substitution: is not usual to carry Subscription-Id on answer messages, but if programmed answer have this information,
+ // then it will be adapted with the received data at request.
+ if(answer->countAvp("Subscription-Id") > 0) {
+ std::string msisdn = anna::diameter::helpers::dcca::functions::getSubscriptionIdData(request, anna::diameter::helpers::dcca::AVPVALUES__Subscription_Id_Type::END_USER_E164);
+ std::string imsi = anna::diameter::helpers::dcca::functions::getSubscriptionIdData(request, anna::diameter::helpers::dcca::AVPVALUES__Subscription_Id_Type::END_USER_IMSI);
+
+ if((msisdn != "") || (imsi != "")) { // Both request & answer have SID: replace answer one with the request information:
+ answer->removeAvp("Subscription-Id", 0 /* remove all */);
+ }
+
+ // Replacements:
+ if(msisdn != "") {
+ anna::diameter::codec::Avp *sid = answer->addAvp("Subscription-Id");
+ sid->addAvp("Subscription-Id-Type")->getEnumerated()->setValue(anna::diameter::helpers::dcca::AVPVALUES__Subscription_Id_Type::END_USER_E164);
+ sid->addAvp("Subscription-Id-Data")->getUTF8String()->setValue(msisdn);
+ }
+
+ if(imsi != "") {
+ anna::diameter::codec::Avp *sid = answer->addAvp("Subscription-Id"); // another
+ sid->addAvp("Subscription-Id-Type")->getEnumerated()->setValue(anna::diameter::helpers::dcca::AVPVALUES__Subscription_Id_Type::END_USER_IMSI);
+ sid->addAvp("Subscription-Id-Data")->getUTF8String()->setValue(imsi);
+ }
+ }
+}
+
+// HTTP
+void MyCommunicator::eventReceiveMessage(anna::comm::ClientSocket& clientSocket, const anna::comm::Message& message)
+throw(anna::RuntimeException) {
+ LOGMETHOD(anna::TraceMethod tm("MyCommunicator", "eventReceiveMessage", ANNA_FILE_LOCATION));
+
+ if(clientSocket.support(anna::http::Transport::className()) == false)
+ return;
+
+ MyHandler& httpHandler = a_contexts.get();
+ httpHandler.apply(clientSocket, message);
+}
+
+void MyCommunicator::eventBreakConnection(Server* server)
+throw() {
+ LOGMETHOD(anna::TraceMethod tm("MyCommunicator", "eventBreakConnection", ANNA_FILE_LOCATION));
+ terminate();
+ anna::comm::Communicator::eventBreakConnection(server);
+}
+
+void MyCommunicator::terminate()
+throw() {
+ if(hasRequestedStop() == true)
+ return;
+
+ requestStop();
+}