NEW Restruct launcher source code. Separate classes in different files to improve...
[anna.git] / example / diameter / launcher / MyCommunicator.cpp
index e69de29..6a85871 100644 (file)
@@ -0,0 +1,88 @@
+// 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();
+}