Tizen 2.1 base
[framework/pim/calendar-service.git] / client / cal_client_ipc.c
1 /*
2  * Calendar Service
3  *
4  * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <unistd.h>
21 #include <stdlib.h>     //calloc
22 #include <pims-ipc.h>
23 #include <glib-object.h> //g_type_init
24
25 #include "calendar_service.h"
26 #include "calendar_db.h"
27 #include "calendar_types2.h"
28
29 #include "cal_internal.h"
30 #include "cal_typedef.h"
31 #include "cal_inotify.h"
32 #include "cal_view.h"
33 #include "cal_record.h"
34 #include "cal_list.h"
35 #include "cal_mutex.h"
36
37 #include "cal_ipc.h"
38 #include "cal_ipc_marshal.h"
39
40 #include "cal_client_ipc.h"
41
42 static TLS pims_ipc_h calendar_ipc_thread = NULL;
43 static pims_ipc_h calendar_ipc = NULL;
44 static int calendar_connection_count = 0;
45 static int calendar_change_version = 0;
46 static TLS int calendar_change_version_thread = 0;
47
48 pims_ipc_h __cal_client_ipc_get_handle(void);
49 void __cal_client_ipc_lock(void);
50 void __cal_client_ipc_unlock(void);
51
52 API int calendar_connect(void)
53 {
54     int ret = CALENDAR_ERROR_NONE;
55     pims_ipc_data_h indata = NULL;
56     pims_ipc_data_h outdata = NULL;
57     pims_ipc_h ipc_handle = NULL;
58
59     CAL_FN_CALL;
60
61     _cal_mutex_lock(CAL_MUTEX_CONNECTION);
62     // ipc create
63     if (calendar_ipc == NULL)
64     {
65         ipc_handle = pims_ipc_create(CAL_IPC_SOCKET_PATH);
66         if (ipc_handle == NULL)
67         {
68             ERR("pims_ipc_create() Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
69             ret = CALENDAR_ERROR_OUT_OF_MEMORY;
70             goto ERROR_RETURN;
71         }
72     }
73     else
74     {
75         calendar_connection_count++;
76         CAL_DBG("calendar already connected = %d",calendar_connection_count);
77         ret = CALENDAR_ERROR_NONE;
78         _cal_mutex_unlock(CAL_MUTEX_CONNECTION);
79         return ret;
80     }
81
82     // ipc call
83     if (pims_ipc_call(ipc_handle, CAL_IPC_MODULE, CAL_IPC_SERVER_CONNECT, indata, &outdata) != 0)
84     {
85         ERR("pims_ipc_call failed");
86         ret = CALENDAR_ERROR_IPC;
87         goto ERROR_RETURN;
88     }
89
90     if (outdata)
91     {
92         // check outdata
93         unsigned int size = 0;
94         ret = *(int*) pims_ipc_data_get(outdata,&size);
95
96         pims_ipc_data_destroy(outdata);
97
98         if (ret != CALENDAR_ERROR_NONE)
99         {
100             ERR("calendar_connect return (%d)",ret);
101             goto ERROR_RETURN;
102         }
103     }
104     else
105     {
106         ERR("ipc outdata is NULL");
107         ret = CALENDAR_ERROR_IPC;
108         goto ERROR_RETURN;
109     }
110
111     g_type_init();  // added for alarmmgr
112
113     if (_cal_inotify_initialize() !=  CALENDAR_ERROR_NONE)
114     {
115         ERR("_cal_inotify_initialize failed");
116     }
117
118     _cal_view_initialize();
119
120     calendar_connection_count++;
121     calendar_ipc = ipc_handle;
122     _cal_mutex_unlock(CAL_MUTEX_CONNECTION);
123
124         return ret;
125
126 ERROR_RETURN:
127     if (ipc_handle != NULL)
128     {
129         pims_ipc_destroy(ipc_handle);
130         ipc_handle = NULL;
131     }
132         _cal_mutex_unlock(CAL_MUTEX_CONNECTION);
133         return ret;
134 }
135
136 API int calendar_disconnect(void)
137 {
138     int ret = CALENDAR_ERROR_NONE;
139     pims_ipc_data_h indata = NULL;
140     pims_ipc_data_h outdata = NULL;
141
142     retvm_if(calendar_ipc==NULL,CALENDAR_ERROR_NOT_PERMITTED,"calendar not connected");
143
144     CAL_FN_CALL;
145     _cal_mutex_lock(CAL_MUTEX_CONNECTION);
146
147     if (calendar_connection_count > 1)
148     {
149         calendar_connection_count--;
150         CAL_DBG("calendar connect count -1 = %d",calendar_connection_count);
151         ret = CALENDAR_ERROR_NONE;
152         _cal_mutex_unlock(CAL_MUTEX_CONNECTION);
153         return ret;
154     }
155
156     // ipc call
157     if (pims_ipc_call(calendar_ipc, CAL_IPC_MODULE, CAL_IPC_SERVER_DISCONNECT, indata, &outdata) != 0)
158     {
159         ERR("pims_ipc_call failed");
160         ret = CALENDAR_ERROR_NOT_PERMITTED;
161         goto ERROR_RETURN;
162     }
163
164     if (outdata)
165     {
166         // check outdata
167         unsigned int size = 0;
168         ret = *(int*) pims_ipc_data_get(outdata,&size);
169
170         pims_ipc_data_destroy(outdata);
171
172     }
173     else
174     {
175         ERR("ipc outdata is NULL");
176         ret = CALENDAR_ERROR_IPC;
177         goto ERROR_RETURN;
178     }
179
180     if (calendar_ipc && ret == CALENDAR_ERROR_NONE)
181     {
182         pims_ipc_destroy(calendar_ipc);
183         calendar_ipc = NULL;
184
185         _cal_inotify_finalize();
186         _cal_view_finalize();
187     }
188
189     _cal_mutex_unlock(CAL_MUTEX_CONNECTION);
190     return ret;
191 ERROR_RETURN:
192
193     _cal_mutex_unlock(CAL_MUTEX_CONNECTION);
194     return ret;
195 }
196
197 API int calendar_connect_on_thread(void)
198 {
199     int ret = CALENDAR_ERROR_NONE;
200     pims_ipc_data_h indata = NULL;
201     pims_ipc_data_h outdata = NULL;
202
203     CAL_FN_CALL;
204
205     // ipc create
206     if (calendar_ipc_thread == NULL)
207     {
208         calendar_ipc_thread = pims_ipc_create(CAL_IPC_SOCKET_PATH);
209         if (calendar_ipc_thread == NULL)
210         {
211             ERR("pims_ipc_create() Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
212             ret = CALENDAR_ERROR_OUT_OF_MEMORY;
213             goto ERROR_RETURN;
214         }
215     }
216     else
217     {
218         CAL_DBG("calendar already connected");
219         ret = CALENDAR_ERROR_NONE;
220         goto ERROR_RETURN;
221     }
222
223     // ipc call
224     if (pims_ipc_call(calendar_ipc_thread, CAL_IPC_MODULE, CAL_IPC_SERVER_CONNECT, indata, &outdata) != 0)
225     {
226         ERR("pims_ipc_call failed");
227         ret = CALENDAR_ERROR_IPC;
228         goto ERROR_RETURN;
229     }
230
231     if (outdata)
232     {
233         // check outdata
234         unsigned int size = 0;
235         ret = *(int*) pims_ipc_data_get(outdata,&size);
236
237         pims_ipc_data_destroy(outdata);
238
239         if (ret != CALENDAR_ERROR_NONE)
240         {
241             ERR("calendar_connect return (%d)",ret);
242             goto ERROR_RETURN;
243         }
244     }
245     else
246     {
247         ERR("ipc outdata is NULL");
248         ret = CALENDAR_ERROR_IPC;
249         goto ERROR_RETURN;
250     }
251
252     if (_cal_inotify_initialize() !=  CALENDAR_ERROR_NONE)
253     {
254         ERR("_cal_inotify_initialize failed");
255     }
256
257     _cal_view_initialize();
258     return ret;
259
260 ERROR_RETURN:
261     if (calendar_ipc_thread != NULL)
262     {
263         pims_ipc_destroy(calendar_ipc_thread);
264         calendar_ipc_thread = NULL;
265     }
266
267     return ret;
268 }
269
270 API int calendar_disconnect_on_thread(void)
271 {
272     int ret = CALENDAR_ERROR_NONE;
273     pims_ipc_data_h indata = NULL;
274     pims_ipc_data_h outdata = NULL;
275
276     retvm_if(calendar_ipc_thread==NULL,CALENDAR_ERROR_NOT_PERMITTED,"calendar_thread not connected");
277
278     CAL_FN_CALL;
279
280     // ipc call
281     if (pims_ipc_call(calendar_ipc_thread, CAL_IPC_MODULE, CAL_IPC_SERVER_DISCONNECT, indata, &outdata) != 0)
282     {
283         ERR("pims_ipc_call failed");
284         ret = CALENDAR_ERROR_NOT_PERMITTED;
285         goto ERROR_RETURN;
286     }
287
288     if (outdata)
289     {
290         // check outdata
291         unsigned int size = 0;
292         ret = *(int*) pims_ipc_data_get(outdata,&size);
293
294         pims_ipc_data_destroy(outdata);
295
296     }
297     else
298     {
299         ERR("ipc outdata is NULL");
300         ret = CALENDAR_ERROR_IPC;
301         goto ERROR_RETURN;
302     }
303
304     if (calendar_ipc_thread && ret == CALENDAR_ERROR_NONE)
305     {
306         pims_ipc_destroy(calendar_ipc_thread);
307         calendar_ipc_thread = NULL;
308
309         _cal_inotify_finalize();
310         _cal_view_finalize();
311     }
312
313     return ret;
314 ERROR_RETURN:
315
316     return ret;
317 }
318
319 API int calendar_connect_with_flags(unsigned int flags)
320 {
321     int ret = CALENDAR_ERROR_NONE;
322
323     ret = calendar_connect();
324     if (ret != CALENDAR_ERROR_NONE)
325     {
326         if (flags & CALENDAR_CONNECT_FLAG_RETRY)
327         {
328             int retry_time = 500;
329             int i = 0;
330             for(i=0;i<6;i++)
331             {
332                 usleep(retry_time*1000);
333                 ret = calendar_connect();
334                 DBG("retry cnt=%d, ret=%x",(i+1), ret);
335                 if (ret == CALENDAR_ERROR_NONE)
336                     break;
337                 retry_time *= 2;
338             }
339
340         }
341     }
342
343     return ret;
344 }
345
346 bool _cal_client_ipc_is_call_inprogress(void)
347 {
348         return pims_ipc_is_call_in_progress(calendar_ipc);
349 }
350
351 pims_ipc_h __cal_client_ipc_get_handle(void)
352 {
353     if (calendar_ipc_thread == NULL)
354     {
355         return calendar_ipc;
356     }
357     return calendar_ipc_thread;
358 }
359
360 void __cal_client_ipc_lock(void)
361 {
362     if (calendar_ipc_thread == NULL)
363     {
364         _cal_mutex_lock(CAL_MUTEX_PIMS_IPC_CALL);
365     }
366 }
367
368 void __cal_client_ipc_unlock(void)
369 {
370     if (calendar_ipc_thread == NULL)
371     {
372         _cal_mutex_unlock(CAL_MUTEX_PIMS_IPC_CALL);
373     }
374 }
375
376 int _cal_client_ipc_call(char *module, char *function, pims_ipc_h data_in,
377         pims_ipc_data_h *data_out)
378 {
379     int ret = 0;
380     pims_ipc_h ipc_handle = __cal_client_ipc_get_handle();
381
382     __cal_client_ipc_lock();
383
384     ret = pims_ipc_call(ipc_handle, module, function, data_in, data_out);
385
386     __cal_client_ipc_unlock();
387
388     return ret;
389 }
390
391 int _cal_client_ipc_call_async(char *module, char *function, pims_ipc_h data_in,
392         pims_ipc_call_async_cb callback, void *userdata)
393 {
394     int ret = 0;
395     pims_ipc_h ipc_handle = __cal_client_ipc_get_handle();
396
397     __cal_client_ipc_lock();
398
399     ret = pims_ipc_call_async(ipc_handle, module, function, data_in, callback, userdata);
400
401     __cal_client_ipc_unlock();
402
403     return ret;
404 }
405
406 void _cal_client_ipc_set_change_version(int version)
407 {
408     if (calendar_ipc_thread == NULL)
409     {
410         calendar_change_version = version;
411         CAL_DBG("change_version=%d",version);
412         return ;
413     }
414     calendar_change_version_thread = version;
415     CAL_DBG("change_version=%d",version);
416 }
417
418 int _cal_client_ipc_get_change_version(void)
419 {
420     if (calendar_ipc_thread == NULL)
421     {
422         return calendar_change_version;
423     }
424     return calendar_change_version_thread;
425
426 }