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/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>
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>
23 using namespace anna::diameter;
24 using namespace anna::diameter::comm;
28 const char* Message::asText(const OnExpiry::_v rc)
30 static const char* text [] = { "Abandon", "Ignore", "Retransmit" };
34 string Message::asString() const
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 += " }";
46 anna::xml::Node* Message::asXML(anna::xml::Node* parent) const
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));
56 //void Message::clear ()
60 //// a_classCode = ClassCode::Undefined;
61 //// a_onExpiry = OnExpiry::Ignore;
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)
70 if(hbh != getRequestHopByHop()) {
71 codec::functions::setHopByHop((anna::DataBlock&)getBody(), hbh);
75 if(a_endToEndSequenced) {
76 if(ete != getRequestEndToEnd()) {
77 codec::functions::setEndToEnd((anna::DataBlock&)getBody(), ete);
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);
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);
94 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
101 void Message::restoreSequencesAfterFix() throw() {
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);
116 diameter::codec::functions::setHopByHop((anna::DataBlock&)getBody(), a_requestHopByHop);
117 diameter::codec::functions::setEndToEnd((anna::DataBlock&)getBody(), a_requestEndToEnd);
121 void Message::send(ClientSession& clientSession) const
122 throw(anna::RuntimeException) {
124 clientSession.getServer()->send((Message *)this);
125 } catch(anna::RuntimeException&) {
130 void Message::send(ServerSession& serverSession) const
131 throw(anna::RuntimeException) {
133 serverSession.getClientSocket()->send((Message *)this);
134 } catch(anna::RuntimeException&) {
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);
147 anna::diameter::ApplicationId Message::getApplicationId() const throw() {
148 diameter::ApplicationId result = diameter::codec::functions::getApplicationId(getBody());
152 HopByHop Message::getHopByHop() const throw() {
153 return (diameter::codec::functions::getHopByHop(getBody()));
156 EndToEnd Message::getEndToEnd() const throw() {
157 return (diameter::codec::functions::getEndToEnd(getBody()));