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 //
9 #include <anna/core/tracing/Logger.hpp>
10 #include <anna/core/tracing/TraceMethod.hpp>
12 #include <anna/comm/Communicator.hpp>
13 #include <anna/comm/ClientSocket.hpp>
14 #include <anna/comm/Transport.hpp>
15 #include <anna/comm/Device.hpp>
16 #include <anna/comm/Receiver.hpp>
18 #include <anna/comm/handler/MetaClientSocket.hpp>
24 * Este método se ejecuta desde un único thread (Tx). Cada socket tiene asociado un thread que lo trata.
26 void comm::handler::MetaClientSocket::apply()
28 LOGMETHOD(TraceMethod tm(Logger::Local7, "comm::handler::MetaClientSocket", "apply", ANNA_FILE_LOCATION));
29 comm::ClientSocket* clientSocket = getClientSocket();
31 if(clientSocket == NULL) {
32 string msg("comm::handler::MetaClientSocket::apply | fd: ");
33 msg += functions::asString(getfd());
34 msg += " | getClientSocket returns NULL";
35 Logger::warning(msg, ANNA_FILE_LOCATION);
36 a_communicator->detach(this);
41 * En MT se ha comprobado que hay alguna combinaci�n en la que se llega a tratar un socket que ha sido cerrado previamente.
43 if(clientSocket->isOpened() == false) {
44 string msg("comm::handler::MetaClientSocket::apply | fd: ");
45 msg += functions::asString(getfd());
46 msg += " | Detected incoming socket overload";
47 Logger::error(msg, ANNA_FILE_LOCATION);
52 bool mustDetach(false);
54 Guard guard(clientSocket, "comm::ClientSocket from comm::handler::MetaClientSocket::apply");
55 comm::ClientSocket::Notify::_v notify = clientSocket->receive();
57 if(notify == comm::ClientSocket::Notify::ReceiveData) {
58 const Message* message;
59 const DataBlock* dataBlock;
60 int messageCounter = 0;
61 Transport* transport = clientSocket->getTransport();
62 Receiver* receiver = clientSocket->getReceiver();
63 clientSocket->activate(comm::ClientSocket::Status::Working);
65 while(canContinue() == true && (dataBlock = clientSocket->fetch()) != NULL) {
68 message = transport->decode(*dataBlock); // (4)
69 } catch(RuntimeException& ex) {
71 clientSocket->activate(comm::ClientSocket::Status::Corrupt);
80 a_communicator->eventReceiveMessage(*clientSocket, *message);
82 receiver->apply(*clientSocket, *message);
84 } catch(RuntimeException& ex) {
90 string msg("comm::handler::MetaClientSocket::apply | fd: ");
91 msg += functions::asString(getfd());
92 msg += functions::asText(" | Message Counter: ", messageCounter);
93 Logger::write(Logger::Local6, msg, ANNA_FILE_LOCATION);
95 clientSocket->deactivate(comm::ClientSocket::Status::Working);
97 if(clientSocket->hasRequestedClose() == true || clientSocket->isCorrupt()) {
98 if(clientSocket->isCorrupt()) {
99 string msg(clientSocket->asString());
100 msg += " | ClientSocket was closed because of wrong message";
101 Logger::error(msg, ANNA_FILE_LOCATION);
102 a_communicator->eventDiscardConnection(*clientSocket);
107 } else if(notify == comm::ClientSocket::Notify::Close || notify == comm::ClientSocket::Notify::Corrupt) { // (2)
108 if(clientSocket->isCorrupt()) {
109 string msg(clientSocket->asString());
110 msg += " | ClientSocket was closed because of wrong message";
111 Logger::error(msg, ANNA_FILE_LOCATION);
112 a_communicator->eventDiscardConnection(*clientSocket);
120 * Termina llamando al XXX::finalize sobre-escrito por la clase heredada de esta
122 if(mustDetach == true)
123 a_communicator->detach(this);
127 bool comm::handler::MetaClientSocket::testClose()
129 LOGMETHOD(TraceMethod tm(Logger::Local7, "comm::handler::MetaClientSocket", "testClose", ANNA_FILE_LOCATION));
130 comm::ClientSocket* clientSocket = getClientSocket();
132 if(clientSocket == NULL) {
133 string msg("comm::handler::MetaClientSocket::testClose | fd: ");
134 msg += functions::asString(getfd());
135 msg += " | getClientSocket returns NULL";
136 Logger::warning(msg, ANNA_FILE_LOCATION);
137 a_communicator->detach(this);
143 Guard guard(clientSocket, "comm::ClientSocket from comm::handler::MetaClientSocket::testClose");
144 mustClose = clientSocket->hasRequestedClose();
148 * Termina llamando al XXX::finalize sobre-escrito por la clase heredada de esta
150 if(mustClose == true)
151 a_communicator->detach(this);
157 * Este metodo se invoca cuando algun elemento externo detecta la caída de toda la red 'address'
159 * Por lo que se puede invocar desde cualquier otro thread no reconocido.
161 void comm::handler::MetaClientSocket::breakAddress(const in_addr_t& address)
163 comm::ClientSocket* clientSocket = getClientSocket();
165 if(clientSocket == NULL) {
166 string msg(asString());
167 msg += " | getClientSocket returns NULL";
168 throw RuntimeException(msg, ANNA_FILE_LOCATION);
172 Guard guard(clientSocket, "comm::ClientSocket from comm::handler::MetaClientSocket::breakAddress");
173 const comm::AccessPoint& accessPoint = clientSocket->getRemoteAccessPoint();
174 const comm::Device* device = accessPoint.getINetAddress().getDevice(false);
179 if(device->getAddress() != address)
183 string msg("comm::handler::MetaClientSocket::breakAddress | ");
184 msg += clientSocket->asString();
185 Logger::debug(msg, ANNA_FILE_LOCATION);
190 * Termina llamando al XXX::finalize sobre-escrito por la clase heredada de esta
192 a_communicator->detach(clientSocket);