tizen 2.4 release
[framework/web/wrt-commons.git] / examples / fake_rpc / fake_rpc.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file        rpc.cpp
18  * @author      Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
19  * @author      Pawel Sikorski (p.sikorski@samsung.com)
20  * @version     1.0
21  * @brief       This file is the implementation file of RPC example
22  */
23 #include <stddef.h>
24 #include <dpl/unix_socket_rpc_client.h>
25 #include <dpl/unix_socket_rpc_server.h>
26 #include <dpl/unix_socket_rpc_connection.h>
27 #include <dpl/fake_rpc_connection.h>
28 #include <memory>
29 #include <dpl/application.h>
30 #include <dpl/controller.h>
31 #include <dpl/thread.h>
32 #include <dpl/log/wrt_log.h>
33 #include <string>
34
35 // FLOW:
36 // 1st connection - UnixSockets
37 // 2nd connection - Fake
38 // client sends data via fake IPC
39 // server sends back this data via unix IPC.
40 // client compare sent and received data
41
42 static const char *UNIX_RPC_NAME = "/tmp/unix_socket_rpc";
43 static const char *FAKE_RPC_NAME = "/tmp/fake_rpc";
44
45 typedef DPL::AbstractRPCConnectionEvents::AsyncCallEvent AsyncCallEvent;
46 typedef DPL::AbstractRPCConnectionEvents::ConnectionClosedEvent
47     ConnectionClosedEvent;
48 typedef DPL::AbstractRPCConnectionEvents::ConnectionBrokenEvent
49     ConnectionBrokenEvent;
50 typedef DPL::AbstractRPCConnectorEvents::ConnectionEstablishedEvent
51     ConnectionEstablishedEvent;
52
53 class MyThread
54     : public DPL::Thread,
55       private DPL::EventListener<AsyncCallEvent>,
56       private DPL::EventListener<ConnectionEstablishedEvent>
57 {
58 private:
59     DPL::UnixSocketRPCClient m_rpcUnixClient;
60     DPL::FakeRpcClient m_rpcFakeClient;
61     int m_connections;
62     int m_sentData;
63     int m_receivedData;
64
65     std::unique_ptr<DPL::AbstractRPCConnection> m_rpcUnixConnection;
66     std::unique_ptr<DPL::AbstractRPCConnection> m_rpcFakeConnection;
67
68     virtual void OnEventReceived(const AsyncCallEvent &event)
69     {
70         WrtLogD("CLIENT: AsyncCallEvent received");
71
72         event.GetArg0().ConsumeArg(m_receivedData);
73         WrtLogD("CLIENT: Result from server: %i", m_receivedData);
74
75         if (m_receivedData != m_sentData)
76             WrtLogE("Wrong data Received!");
77     }
78
79     virtual void OnEventReceived(const ConnectionEstablishedEvent &event)
80     {
81         if (dynamic_cast<DPL::FakeRpcConnection *>(event.GetArg1())){
82             ++m_connections;
83             WrtLogD("CLIENT: Acquiring new fake connection");
84             m_rpcFakeConnection.reset(event.GetArg1());
85             //this is not used on this side
86 //            m_rpcFakeConnection->DPL::EventSupport<AsyncCallEvent>::AddListener(this);
87         }
88         else{
89             ++m_connections;
90             WrtLogD("CLIENT: Acquiring new unix connection");
91             m_rpcUnixConnection.reset(event.GetArg1());
92             m_rpcUnixConnection->DPL::EventSupport<AsyncCallEvent>::AddListener(this);
93         }
94         if(m_connections == 2){
95             m_sentData = 1213;
96             // Emit RPC function call
97             DPL::RPCFunction proc;
98             proc.AppendArg(m_sentData);
99             WrtLogD("CLIENT: Calling RPC function");
100             m_rpcFakeConnection->AsyncCall(proc);
101         }
102     }
103
104 public:
105     MyThread() :
106         m_rpcUnixClient(NULL),
107         m_rpcFakeClient(NULL),
108         m_connections(0),
109         m_sentData(0),
110         m_receivedData(0)
111     {}
112
113     virtual ~MyThread()
114     {
115         // Always quit thread
116        Quit();
117     }
118
119     virtual int ThreadEntry()
120     {
121         m_connections = 0;
122         // Attach RPC listeners
123         WrtLogD("CLIENT: Attaching connection established event");
124         m_rpcUnixClient.DPL::EventSupport<ConnectionEstablishedEvent>::AddListener(this);
125         m_rpcFakeClient.DPL::EventSupport<ConnectionEstablishedEvent>::AddListener(this);
126
127         // Open connection to server
128         WrtLogD("CLIENT: Opening connection to RPC");
129         m_rpcUnixClient.Open(UNIX_RPC_NAME);
130         m_rpcFakeClient.Open(FAKE_RPC_NAME);
131
132         // Start message loop
133         WrtLogD("CLIENT: Starting thread event loop");
134         int ret = Exec();
135
136         if (m_rpcUnixConnection.get()){
137             WrtLogD("CLIENT: Removing Unix connection");
138             m_rpcUnixConnection->DPL::EventSupport<AsyncCallEvent>::RemoveListener(this);
139             m_rpcUnixConnection.reset();
140         }
141
142         WrtLogD("CLIENT: Closing");
143
144         if (m_rpcFakeConnection.get()){
145             WrtLogD("CLIENT: Removing Fake connection");
146             //this is not used on this side
147 //            m_rpcFakeConnection->DPL::EventSupport<AsyncCallEvent>::RemoveListener(this);
148             m_rpcFakeConnection.reset();
149         }
150
151         // Detach RPC client listener
152         WrtLogD("CLIENT: Detaching connection established event");
153         m_rpcUnixClient.DPL::EventSupport<ConnectionEstablishedEvent>::RemoveListener(this);
154         m_rpcFakeClient.DPL::EventSupport<ConnectionEstablishedEvent>::RemoveListener(this);
155
156         // Close RPC
157         WrtLogD("CLIENT: Closing RPC client");
158         m_rpcUnixClient.CloseAll();
159         m_rpcFakeClient.Close();//not needed
160
161         // Done
162         return ret;
163     }
164 };
165
166 DECLARE_GENERIC_EVENT_0(QuitEvent)
167 DECLARE_GENERIC_EVENT_0(CloseThreadEvent)
168
169 class MyApplication
170     : public DPL::Application,
171       private DPL::Controller<DPL::TypeListDecl<QuitEvent,
172                                                 CloseThreadEvent>::Type>,
173       private DPL::EventListener<AsyncCallEvent>,
174       private DPL::EventListener<ConnectionEstablishedEvent>
175 {
176 private:
177     DPL::UnixSocketRPCServer m_rpcUnixServer;
178     DPL::FakeRpcServer m_rpcFakeServer;
179
180     std::unique_ptr<DPL::AbstractRPCConnection> m_rpcUnixConnection;
181     std::unique_ptr<DPL::AbstractRPCConnection> m_rpcFakeConnection;
182
183     MyThread m_thread;
184
185     // Quit application event occurred
186     virtual void OnEventReceived(const QuitEvent &/*event*/){
187         // Close RPC now
188         WrtLogD("SERVER: Closing RPC connection...");
189
190         // Detach RPC connection listeners
191         if (m_rpcUnixConnection.get()) {
192             //this is not used on this side
193 //            m_rpcUnixConnection->DPL::EventSupport<AsyncCallEvent>::RemoveListener(this);
194             m_rpcUnixConnection.reset();
195         }
196
197         if (m_rpcFakeConnection.get()) {
198             m_rpcFakeConnection->DPL::EventSupport<AsyncCallEvent>::RemoveListener(this);
199             m_rpcFakeConnection.reset();
200         }
201
202         WrtLogD("SERVER: Closing Server");
203         m_rpcUnixServer.CloseAll();
204         m_rpcFakeServer.CloseAll();//not needed
205         m_rpcUnixServer.DPL::EventSupport<ConnectionEstablishedEvent>::RemoveListener(this);
206         m_rpcFakeServer.DPL::EventSupport<ConnectionEstablishedEvent>::RemoveListener(this);
207
208         WrtLogD("SERVER: Server closed");
209
210         Quit();
211     }
212
213     virtual void OnEventReceived(const CloseThreadEvent &/*event*/){
214         m_thread.Quit();
215     }
216
217     virtual void OnEventReceived(const AsyncCallEvent &event)
218     {
219         WrtLogD("SERVER: AsyncCallEvent received");
220
221         int value;
222         event.GetArg0().ConsumeArg(value);
223         WrtLogD("SERVER: Result from client: %i", value);
224
225         // send back data to client (via fake)
226         // Emit RPC function call
227         DPL::RPCFunction proc;
228         proc.AppendArg(value);
229         WrtLogD("SERVER: Calling RPC function");
230         m_rpcUnixConnection->AsyncCall(proc);
231     }
232
233     virtual void OnEventReceived(const ConnectionEstablishedEvent &event)
234     {
235         // Save connection pointer
236         if (dynamic_cast<DPL::FakeRpcConnection *>(event.GetArg1())){
237             WrtLogD("SERVER: Acquiring Fake RPC connection");
238             m_rpcFakeConnection.reset(event.GetArg1());
239             m_rpcFakeConnection->DPL::EventSupport<AsyncCallEvent>::AddListener(this);
240         }
241         else{
242             WrtLogD("SERVER: Acquiring Unix RPC connection");
243             m_rpcUnixConnection.reset(event.GetArg1());
244             //this is not used on this side
245 //            m_rpcUnixConnection->DPL::EventSupport<AsyncCallEvent>::AddListener(this);
246         }
247     }
248
249 public:
250     MyApplication(int argc, char **argv)
251         : Application(argc, argv, "rpc")
252     {
253         // Attach RPC server listeners
254         WrtLogD("SERVER: Attaching connection established event");
255         m_rpcUnixServer.DPL::EventSupport<ConnectionEstablishedEvent>::AddListener(this);
256         m_rpcFakeServer.DPL::EventSupport<ConnectionEstablishedEvent>::AddListener(this);
257
258         // Self touch
259         WrtLogD("SERVER: Touching controller");
260         Touch();
261
262         // Open RPC server
263         WrtLogD("SERVER: Opening server RPC");
264         m_rpcUnixServer.Open(UNIX_RPC_NAME);
265         m_rpcFakeServer.Open(FAKE_RPC_NAME);
266
267         // Run RPC client in thread
268         WrtLogD("SERVER: Starting RPC client thread");
269         m_thread.Run();
270
271         // Quit application automatically in few seconds
272         WrtLogD("SERVER: Sending control timed events");
273         DPL::ControllerEventHandler<CloseThreadEvent>::PostTimedEvent(CloseThreadEvent(), 2);
274         DPL::ControllerEventHandler<QuitEvent>::PostTimedEvent(QuitEvent(), 3);
275     }
276
277     virtual ~MyApplication()
278     {
279         // Quit thread
280         WrtLogD("SERVER: Quitting thread");
281     }
282 };
283
284 int main(int argc, char *argv[])
285 {
286     WrtLogD("Starting");
287     MyApplication app(argc, argv);
288     return app.Exec();
289 }