1 /*
2  * barrier -- mouse and keyboard sharing utility
3  * Copyright (C) 2012-2016 Symless Ltd.
4  * Copyright (C) 2012 Nick Bolton
5  *
6  * This package is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * found in the file LICENSE that should have accompanied this file.
9  *
10  * This package is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "ipc/IpcClient.h"
20 #include "ipc/Ipc.h"
21 #include "ipc/IpcServerProxy.h"
22 #include "ipc/IpcMessage.h"
23 #include "base/TMethodEventJob.h"
24 
25 //
26 // IpcClient
27 //
28 
IpcClient(IEventQueue * events,SocketMultiplexer * socketMultiplexer)29 IpcClient::IpcClient(IEventQueue* events, SocketMultiplexer* socketMultiplexer) :
30     m_serverAddress(NetworkAddress(IPC_HOST, IPC_PORT)),
31     m_socket(events, socketMultiplexer, IArchNetwork::kINET),
32     m_server(nullptr),
33     m_events(events)
34 {
35     init();
36 }
37 
IpcClient(IEventQueue * events,SocketMultiplexer * socketMultiplexer,int port)38 IpcClient::IpcClient(IEventQueue* events, SocketMultiplexer* socketMultiplexer, int port) :
39     m_serverAddress(NetworkAddress(IPC_HOST, port)),
40     m_socket(events, socketMultiplexer, IArchNetwork::kINET),
41     m_server(nullptr),
42     m_events(events)
43 {
44     init();
45 }
46 
47 void
init()48 IpcClient::init()
49 {
50     m_serverAddress.resolve();
51 }
52 
~IpcClient()53 IpcClient::~IpcClient()
54 {
55 }
56 
57 void
connect()58 IpcClient::connect()
59 {
60     m_events->adoptHandler(
61         m_events->forIDataSocket().connected(), m_socket.getEventTarget(),
62         new TMethodEventJob<IpcClient>(
63         this, &IpcClient::handleConnected));
64 
65     m_socket.connect(m_serverAddress);
66     m_server = new IpcServerProxy(m_socket, m_events);
67 
68     m_events->adoptHandler(
69         m_events->forIpcServerProxy().messageReceived(), m_server,
70         new TMethodEventJob<IpcClient>(
71         this, &IpcClient::handleMessageReceived));
72 }
73 
74 void
disconnect()75 IpcClient::disconnect()
76 {
77     m_events->removeHandler(m_events->forIDataSocket().connected(), m_socket.getEventTarget());
78     m_events->removeHandler(m_events->forIpcServerProxy().messageReceived(), m_server);
79 
80     m_server->disconnect();
81     delete m_server;
82     m_server = nullptr;
83 }
84 
85 void
send(const IpcMessage & message)86 IpcClient::send(const IpcMessage& message)
87 {
88     assert(m_server != nullptr);
89     m_server->send(message);
90 }
91 
92 void
handleConnected(const Event &,void *)93 IpcClient::handleConnected(const Event&, void*)
94 {
95     m_events->addEvent(Event(
96         m_events->forIpcClient().connected(), this, m_server, Event::kDontFreeData));
97 
98     IpcHelloMessage message(kIpcClientNode);
99     send(message);
100 }
101 
102 void
handleMessageReceived(const Event & e,void *)103 IpcClient::handleMessageReceived(const Event& e, void*)
104 {
105     Event event(m_events->forIpcClient().messageReceived(), this);
106     event.setDataObject(e.getDataObject());
107     m_events->addEvent(event);
108 }
109