First commit
[anna.git] / include / anna / diameter.comm / Message.hpp
1 // ANNA - Anna is Not 'N' Anymore
2 //
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
4 //
5 // https://bitbucket.org/testillano/anna
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 //
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
16 // distribution.
17 //     * Neither the name of Google Inc. 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.
20 //
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.
32 //
33 // Authors: eduardo.ramos.testillano@gmail.com
34 //          cisco.tierra@gmail.com
35
36
37 #ifndef anna_diameter_comm_Message_hpp
38 #define anna_diameter_comm_Message_hpp
39
40 // Local
41 #include <anna/diameter/defines.hpp>
42 #include <anna/diameter.comm/ClassCode.hpp>
43
44 #include <anna/core/RuntimeException.hpp>
45 #include <anna/comm/Message.hpp>
46 #include <anna/core/util/Millisecond.hpp>
47 #include <anna/core/functions.hpp>
48
49
50
51 namespace anna {
52 namespace xml {
53 class Node;
54 }
55 }
56
57
58
59 namespace anna {
60
61 namespace diameter {
62
63 namespace comm {
64
65
66 class ClientSession;
67 class ServerSession;
68
69 /**
70    Messages launched to diameter servers
71 */
72 class Message : public anna::comm::Message {
73 public:
74
75   /**
76    * Define las acciones a realizar en caso de que el temporizador de la petición expire.
77    */
78   struct OnExpiry { enum _v { Abandon, Ignore }; };
79
80   /**
81      Constructor.
82      \param onExpiry Indica la acción a realizar si el temporizador de esta transación expira.
83   */
84   Message(const OnExpiry::_v onExpiry = OnExpiry::Ignore) : anna::comm::Message(StatusCodeBuffer::Reserve),
85     a_classCode(ClassCode::ApplicationMessage),
86     a_onExpiry(onExpiry) { initialize(); }
87
88   /**
89      Devuelve el tipo de la clase de esta peticion indicada en el contructor.
90      \return El tipo de la clase de esta peticion indicada en el contructor.
91   */
92   const ClassCode::_v & getClassCode() const throw() { return a_classCode; }
93
94   /**
95    * Devuelve la acción a realizar en caso de que el temporizador asociado a esta petición expire.
96    * \return la acción a realizar en caso de que el temporizador asociado a esta petición expire.
97    */
98   OnExpiry::_v getOnExpiry() const throw() { return a_onExpiry; }
99
100   /**
101    * Establece la acción a realizar en caso de que el temporizador asociado a esta petición expire.
102    * \param onExpiry Indica la acción a realizar en caso de que el temporizador asociado a esta petición expire.
103    *
104    * \warning Establecer el valor OnExpiry::Ignore podría causar pérdida de memoria y uso innecesario de recursos.
105    */
106   void setOnExpiry(const OnExpiry::_v onExpiry) throw() { a_onExpiry = onExpiry; }
107
108   // Internal use (CER message)
109   void setClassCode(const ClassCode::_v & classCode) throw() { a_classCode = classCode; }
110
111
112   /**
113      Class string representation
114      \return String with relevant information for this instance.
115   */
116   virtual std::string asString() const throw();
117
118   /**
119      Class xml representation
120      \param parent Parent XML node on which hold this instance information.
121      \return XML document with relevant information for this instance.
122   */
123   virtual anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
124
125
126   // Helpers
127   HopByHop getHopByHop() const throw();
128   EndToEnd getEndToEnd() const throw();
129   HopByHop getRequestHopByHop() const throw() { return a_requestHopByHop; }
130   EndToEnd getRequestEndToEnd() const throw() { return a_requestEndToEnd; }
131   void setRequestHopByHop(HopByHop hbh) throw() { a_requestHopByHop = hbh; }
132   void setRequestEndToEnd(EndToEnd ete) throw() { a_requestEndToEnd = ete; }
133   CommandId getCommandId(bool &isRequest) const throw();
134   CommandId getCommandId() const throw() { bool dummy; return getCommandId(dummy); }
135
136   bool fixRequestSequence(HopByHop hbh, EndToEnd ete, bool freezeEndToEnd) throw();
137
138   // Statistics
139   void updateRequestTimestampMs(void) throw() { a_request_timestamp_ms = anna::functions::millisecond(); }
140   const anna::Millisecond & getRequestTimestampMs() const throw() { return (a_request_timestamp_ms); }
141
142   int getRetries() const throw() { return a_retries; }
143   void setRetries(int value) throw() { a_retries = value; }
144
145
146   int getRequestServerSessionKey() const throw() { return a_requestServerSessionKey; }
147
148   /** Application specific socket id to keep origin track for request which came from a specific client, at asyncronous contexts (process with both diameter interfaces: client & entities) */
149   void setRequestServerSessionKey(int value) throw() { a_requestServerSessionKey = value; }
150
151   const std::string & getRequestClientSessionKey() const throw() { return a_requestClientSessionKey; }
152
153   /** Application specific socket id to keep origin track for request which came from a specific server (entity), at asyncronous contexts (process with both diameter interfaces: client & entities) */
154   void setRequestClientSessionKey(const std::string & value) throw() { a_requestClientSessionKey = value; }
155
156   /** Initializes class information */
157   void initialize() throw() {
158     a_retries = 0;
159     a_requestServerSessionKey = -1; // means unknown/unset
160     a_requestClientSessionKey = ""; // means unknown/unset
161     a_requestHopByHop = 0;
162     a_requestEndToEnd = 0;
163   }
164
165
166 protected:
167   /**
168      Constructor.
169      \param classCode Tipo de clase de esta peticion.
170      \param onExpiry Indica la acción a realizar si el temporizador de esta transación expira.
171   */
172   Message(const ClassCode::_v & classCode, const OnExpiry::_v onExpiry = OnExpiry::Ignore) : anna::comm::Message(StatusCodeBuffer::Reserve),
173     a_classCode(classCode),
174     a_onExpiry(onExpiry) { initialize(); }
175
176
177 private:
178   ClassCode::_v a_classCode;
179   OnExpiry::_v a_onExpiry;
180   anna::Millisecond a_request_timestamp_ms;    // Lapsed timestamp milliseconds at request event. Used for statistic purposes.
181   int a_retries;
182   int a_requestServerSessionKey;            // useful to resolve origin of messages when diameter sessions are involved in the other side (if another interface, inherit from this Message class and put/carry context information)
183   std::string a_requestClientSessionKey;    // idem for request which was received from servers
184   HopByHop a_requestHopByHop; // application backup for hop-by-hop in order to restore on answer receive
185   EndToEnd a_requestEndToEnd; // application backup for end-to-end in order to restore on answer receive
186
187   void send(ClientSession&) const throw(anna::RuntimeException);
188   void send(ServerSession&) const throw(anna::RuntimeException);
189   void restoreSequencesAfterFix() throw();
190
191   static const char* asText(const OnExpiry::_v) throw();
192
193   friend class Session;
194   friend class ClientSession;
195   friend class ServerSession;
196 };
197
198 }
199 }
200 }
201
202 #endif
203