App counters including message name and result code if proceed
[anna.git] / source / diameter.comm / Message.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 // Local
10 #include <anna/diameter.comm/Message.hpp>
11 #include <anna/diameter.comm/ClientSession.hpp>
12 #include <anna/diameter.comm/ServerSession.hpp>
13 #include <anna/diameter/codec/functions.hpp>
14 #include <anna/diameter/defines.hpp>
15
16 #include <anna/xml/Node.hpp>
17 #include <anna/core/functions.hpp>
18 #include <anna/core/RuntimeException.hpp>
19 #include <anna/comm/ClientSocket.hpp>
20 #include <anna/core/tracing/Logger.hpp>
21
22 using namespace std;
23 using namespace anna::diameter;
24 using namespace anna::diameter::comm;
25
26
27
28 const char* Message::asText(const OnExpiry::_v rc)
29 throw() {
30   static const char* text [] = { "Abandon", "Ignore", "Retransmit" };
31   return text [rc];
32 }
33
34 string Message::asString() const
35 throw() {
36   string result("diameter::comm::Message { ");
37   result += "ClassCode: ";
38   result += ClassCode::asText(a_classCode);
39   result += " | OnExpiry: ";
40   result += asText(a_onExpiry);
41   result += " | Retries: ";
42   result += anna::functions::asString(a_retries);
43   return result += " }";
44 }
45
46 anna::xml::Node* Message::asXML(anna::xml::Node* parent) const
47 throw() {
48   anna::xml::Node* result = parent->createChild("diameter.comm.Message");
49   result->createAttribute("ClassCode", ClassCode::asText(a_classCode));
50   result->createAttribute("OnExpiry", asText(a_onExpiry));
51   result->createAttribute("Retries", anna::functions::asString(a_retries));
52   //isRequest ...
53   return result;
54 }
55
56 //void Message::clear ()
57 //   throw ()
58 //{
59 //   ::clear();
60 ////   a_classCode = ClassCode::Undefined;
61 ////   a_onExpiry = OnExpiry::Ignore;
62 //}
63
64
65 bool Message::fixRequestSequence(HopByHop hbh, EndToEnd ete) throw() {
66   setRequestHopByHop(getHopByHop()); // original request hop-by-hop (backup)
67   setRequestEndToEnd(getEndToEnd()); // original request end-to-end (backup)
68   bool result = false;
69
70   if(hbh != getRequestHopByHop()) {
71     codec::functions::setHopByHop((anna::DataBlock&)getBody(), hbh);
72     result = true;
73   }
74
75   if(a_endToEndSequenced) {
76     if(ete != getRequestEndToEnd()) {
77       codec::functions::setEndToEnd((anna::DataBlock&)getBody(), ete);
78       result = true;
79     }
80   }
81
82   LOGDEBUG(
83     string msg("diameter::comm::fixRequestSequence { ");
84     msg += "Hop by hop: ";
85     msg += anna::functions::asString(getRequestHopByHop());
86     msg += " (original) -> ";
87     msg += anna::functions::asString(hbh);
88     msg += " (session)";
89     msg += a_endToEndSequenced ? " | End to end: " : " | End to end [end-to-end unchanged]: ";
90     msg += anna::functions::asString(getRequestEndToEnd());
91     msg += " (original) -> ";
92     msg += anna::functions::asString(ete);
93     msg += " (session)";
94     anna::Logger::debug(msg, ANNA_FILE_LOCATION);
95   );
96   return result;
97 }
98
99
100
101 void Message::restoreSequencesAfterFix() throw() {
102   LOGDEBUG(
103     string msg("diameter::comm::restoreSequencesAfterFix { ");
104     msg += "Hop by hop: ";
105     msg += anna::functions::asString(getHopByHop());
106     msg += " (session) -> ";
107     msg += anna::functions::asString(getRequestHopByHop());
108     msg += " (original)";
109     msg += " | End to end: ";
110     msg += anna::functions::asString(getEndToEnd());
111     msg += " (session) -> ";
112     msg += anna::functions::asString(getRequestEndToEnd());
113     msg += " (original)";
114     anna::Logger::debug(msg, ANNA_FILE_LOCATION);
115   );
116   diameter::codec::functions::setHopByHop((anna::DataBlock&)getBody(), a_requestHopByHop);
117   diameter::codec::functions::setEndToEnd((anna::DataBlock&)getBody(), a_requestEndToEnd);
118 }
119
120
121 void Message::send(ClientSession& clientSession) const
122 throw(anna::RuntimeException) {
123   try {
124     clientSession.getServer()->send((Message *)this);
125   } catch(anna::RuntimeException&) {
126     throw;
127   }
128 }
129
130 void Message::send(ServerSession& serverSession) const
131 throw(anna::RuntimeException) {
132   try {
133     serverSession.getClientSocket()->send((Message *)this);
134   } catch(anna::RuntimeException&) {
135     throw;
136   }
137 }
138
139
140
141 anna::diameter::CommandId Message::getCommandId(bool &isRequest) const throw() {
142   diameter::CommandId result = diameter::codec::functions::getCommandId(getBody());
143   isRequest = result.second; // diameter::codec::functions::isRequest(result);
144   return result;
145 }
146
147 anna::diameter::ApplicationId Message::getApplicationId() const throw() {
148   diameter::ApplicationId result = diameter::codec::functions::getApplicationId(getBody());
149   return result;
150 }
151
152 HopByHop Message::getHopByHop() const throw() {
153   return (diameter::codec::functions::getHopByHop(getBody()));
154 }
155
156 EndToEnd Message::getEndToEnd() const throw() {
157   return (diameter::codec::functions::getEndToEnd(getBody()));
158 }