1 // ANNA - Anna is Not Nothingness Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // http://redmine.teslayout.com/projects/anna-suite
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
38 #include <anna/diameter.comm/Message.hpp>
39 #include <anna/diameter.comm/ClientSession.hpp>
40 #include <anna/diameter.comm/ServerSession.hpp>
41 #include <anna/diameter/codec/functions.hpp>
42 #include <anna/diameter/defines.hpp>
44 #include <anna/xml/Node.hpp>
45 #include <anna/core/functions.hpp>
46 #include <anna/core/RuntimeException.hpp>
47 #include <anna/comm/ClientSocket.hpp>
48 #include <anna/core/tracing/Logger.hpp>
51 using namespace anna::diameter;
52 using namespace anna::diameter::comm;
56 const char* Message::asText(const OnExpiry::_v rc)
58 static const char* text [] = { "Abandon", "Ignore" };
62 string Message::asString() const
64 string result("diameter::comm::Message { ");
65 result += "ClassCode: ";
66 result += ClassCode::asText(a_classCode);
67 result += " | OnExpiry: ";
68 result += asText(a_onExpiry);
69 result += " | Retries: ";
70 result += anna::functions::asString(a_retries);
71 return result += " }";
74 anna::xml::Node* Message::asXML(anna::xml::Node* parent) const
76 anna::xml::Node* result = parent->createChild("diameter.comm.Message");
77 result->createAttribute("ClassCode", ClassCode::asText(a_classCode));
78 result->createAttribute("OnExpiry", asText(a_onExpiry));
79 result->createAttribute("Retries", anna::functions::asString(a_retries));
84 //void Message::clear ()
88 //// a_classCode = ClassCode::Undefined;
89 //// a_onExpiry = OnExpiry::Ignore;
92 bool Message::fixRequestSequence(HopByHop hbh, EndToEnd ete, bool freezeEndToEnd) throw() {
93 setRequestHopByHop(getHopByHop()); // original request hop-by-hop (backup)
94 setRequestEndToEnd(getEndToEnd()); // original request end-to-end (backup)
97 if(hbh != getRequestHopByHop()) {
98 codec::functions::setHopByHop((anna::DataBlock&)getBody(), hbh);
102 if(!freezeEndToEnd) {
103 if(ete != getRequestEndToEnd()) {
104 codec::functions::setEndToEnd((anna::DataBlock&)getBody(), ete);
110 string msg("diameter::comm::fixRequestSequence { ");
111 msg += "Hop by hop: ";
112 msg += anna::functions::asString(getRequestHopByHop());
113 msg += " (original) -> ";
114 msg += anna::functions::asString(hbh);
116 msg += freezeEndToEnd ? " | End to end [freezed]: " : " | End to end: ";
117 msg += anna::functions::asString(getRequestEndToEnd());
118 msg += " (original) -> ";
119 msg += anna::functions::asString(ete);
121 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
128 void Message::restoreSequencesAfterFix() throw() {
130 string msg("diameter::comm::restoreSequencesAfterFix { ");
131 msg += "Hop by hop: ";
132 msg += anna::functions::asString(getHopByHop());
133 msg += " (session) -> ";
134 msg += anna::functions::asString(getRequestHopByHop());
135 msg += " (original)";
136 msg += " | End to end: ";
137 msg += anna::functions::asString(getEndToEnd());
138 msg += " (session) -> ";
139 msg += anna::functions::asString(getRequestEndToEnd());
140 msg += " (original)";
141 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
143 diameter::codec::functions::setHopByHop((anna::DataBlock&)getBody(), a_requestHopByHop);
144 diameter::codec::functions::setEndToEnd((anna::DataBlock&)getBody(), a_requestEndToEnd);
148 void Message::send(ClientSession& clientSession) const
149 throw(anna::RuntimeException) {
151 clientSession.getServer()->send((Message *)this);
152 } catch(anna::RuntimeException&) {
157 void Message::send(ServerSession& serverSession) const
158 throw(anna::RuntimeException) {
160 serverSession.getClientSocket()->send((Message *)this);
161 } catch(anna::RuntimeException&) {
168 anna::diameter::CommandId Message::getCommandId(bool &isRequest) const throw() {
169 diameter::CommandId result = diameter::codec::functions::getCommandId(getBody());
170 isRequest = result.second; // diameter::codec::functions::isRequest(result);
174 HopByHop Message::getHopByHop() const throw() {
175 return (diameter::codec::functions::getHopByHop(getBody()));
178 EndToEnd Message::getEndToEnd() const throw() {
179 return (diameter::codec::functions::getEndToEnd(getBody()));