Add deployment for ADML agent with http interface
[anna.git] / example / diameter / launcher / MyCommunicator.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 // Project
10 #include <anna/diameter/helpers/base/functions.hpp>
11 #include <anna/diameter/helpers/dcca/functions.hpp>
12 #include <anna/http/Transport.hpp>
13
14 // Process
15 #include <MyCommunicator.hpp>
16
17
18 void MyCommunicator::prepareAnswer(anna::diameter::codec::Message *answer, const anna::DataBlock &request) const throw() {
19   // Sequence values (hop-by-hop and end-to-end), session-id and subscription-id avps, are mirrored to the peer which sent the request.
20   // If user wants to test a specific answer without changing it, use send operations better than programming.
21   // Sequence substitution:
22   answer->setHopByHop(anna::diameter::codec::functions::getHopByHop(request));
23   answer->setEndToEnd(anna::diameter::codec::functions::getEndToEnd(request));
24
25   // Session-Id substitution:
26   try {
27     std::string sessionId = anna::diameter::helpers::base::functions::getSessionId(request);
28     LOGDEBUG(
29       std::string msg = "Extracted Session-Id: ";
30       msg += sessionId;
31       anna::Logger::debug(msg, ANNA_FILE_LOCATION);
32     );
33     answer->getAvp("Session-Id")->getUTF8String()->setValue(sessionId);
34   } catch(anna::RuntimeException &ex) {
35     ex.trace();
36   }
37
38   // Subscription-Id substitution: is not usual to carry Subscription-Id on answer messages, but if programmed answer have this information,
39   // then it will be adapted with the received data at request.
40   if(answer->countAvp("Subscription-Id") > 0) {
41     std::string msisdn = anna::diameter::helpers::dcca::functions::getSubscriptionIdData(request, anna::diameter::helpers::dcca::AVPVALUES__Subscription_Id_Type::END_USER_E164);
42     std::string imsi = anna::diameter::helpers::dcca::functions::getSubscriptionIdData(request, anna::diameter::helpers::dcca::AVPVALUES__Subscription_Id_Type::END_USER_IMSI);
43
44     if((msisdn != "") || (imsi != "")) {  // Both request & answer have SID: replace answer one with the request information:
45       answer->removeAvp("Subscription-Id", 0 /* remove all */);
46     }
47
48     // Replacements:
49     if(msisdn != "") {
50       anna::diameter::codec::Avp *sid = answer->addAvp("Subscription-Id");
51       sid->addAvp("Subscription-Id-Type")->getEnumerated()->setValue(anna::diameter::helpers::dcca::AVPVALUES__Subscription_Id_Type::END_USER_E164);
52       sid->addAvp("Subscription-Id-Data")->getUTF8String()->setValue(msisdn);
53     }
54
55     if(imsi != "") {
56       anna::diameter::codec::Avp *sid = answer->addAvp("Subscription-Id"); // another
57       sid->addAvp("Subscription-Id-Type")->getEnumerated()->setValue(anna::diameter::helpers::dcca::AVPVALUES__Subscription_Id_Type::END_USER_IMSI);
58       sid->addAvp("Subscription-Id-Data")->getUTF8String()->setValue(imsi);
59     }
60   }
61 }
62
63 // HTTP
64 void MyCommunicator::eventReceiveMessage(anna::comm::ClientSocket& clientSocket, const anna::comm::Message& message)
65 throw(anna::RuntimeException) {
66   LOGMETHOD(anna::TraceMethod tm("MyCommunicator", "eventReceiveMessage", ANNA_FILE_LOCATION));
67
68   if(clientSocket.support(anna::http::Transport::className()) == false)
69     return;
70
71   MyHandler& httpHandler = a_contexts.get();
72   httpHandler.apply(clientSocket, message);
73 }
74
75 void MyCommunicator::eventBreakConnection(Server* server)
76 throw() {
77   LOGMETHOD(anna::TraceMethod tm("MyCommunicator", "eventBreakConnection", ANNA_FILE_LOCATION));
78   terminate();
79   anna::comm::Communicator::eventBreakConnection(server);
80 }
81
82 void MyCommunicator::terminate()
83 throw() {
84   if(hasRequestedStop() == true)
85     return;
86
87   requestStop();
88 }