4 * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <pims-ipc-data.h>
22 #include <security-server.h>
24 #include "ctsvc_client_ipc.h"
26 #include "ctsvc_internal.h"
27 #include "ctsvc_list.h"
28 #include "ctsvc_record.h"
29 #include "ctsvc_query.h"
30 #include "ctsvc_inotify.h"
32 #include "ctsvc_ipc_define.h"
33 #include "ctsvc_ipc_marshal.h"
34 #include "ctsvc_view.h"
35 #include "ctsvc_mutex.h"
37 static __thread pims_ipc_h __contacts_ipc = NULL;
38 static pims_ipc_h __contacts_global_ipc = NULL;
40 static __thread int __contacts_change_version = 0;
41 static int __contacts_global_change_version = 0;
43 static int __ctsvc_ipc_get_cookie_for_access_control(pims_ipc_data_h *indata)
46 size_t cookie_size = 0;
50 // Access control : get cookie from security-server
51 cookie_size = security_server_get_cookie_size();
52 if (cookie_size <= 0) {
53 CTS_ERR("security_server_get_cookie_size");
54 return CONTACTS_ERROR_SYSTEM;
57 char cookie[cookie_size];
59 ret = security_server_request_cookie(cookie, cookie_size);
61 CTS_ERR("security_server_request_cookie fail (%d)", ret);
62 return CONTACTS_ERROR_SYSTEM;
65 // Access control : put cookie to indata
66 data = pims_ipc_data_create(0);
68 CTS_ERR("ipc data created fail!");
69 return CONTACTS_ERROR_OUT_OF_MEMORY;
72 ret = ctsvc_ipc_marshal_unsigned_int(cookie_size, data);
73 if (ret != CONTACTS_ERROR_NONE) {
74 CTS_ERR("ctsvc_ipc_marshal_int fail");
75 pims_ipc_data_destroy(data);
79 buf = g_base64_encode((const guchar *)cookie, cookie_size);
81 ret = ctsvc_ipc_marshal_string(buf, data);
82 if (ret != CONTACTS_ERROR_NONE) {
83 CTS_ERR("ctsvc_ipc_marshal_string fail");
84 pims_ipc_data_destroy(data);
90 CTS_ERR("g_base64_encode fail");
91 pims_ipc_data_destroy(data);
92 return CONTACTS_ERROR_INTERNAL;
97 return CONTACTS_ERROR_NONE;
100 int ctsvc_ipc_connect_on_thread(void)
102 int ret = CONTACTS_ERROR_NONE;
103 pims_ipc_data_h indata = NULL;
104 pims_ipc_data_h outdata = NULL;
107 if (__contacts_ipc == NULL) {
108 __contacts_ipc = pims_ipc_create(CTSVC_IPC_SOCKET_PATH);
109 if (__contacts_ipc == NULL) {
110 CTS_ERR("pims_ipc_create() Failed(%d)", CONTACTS_ERROR_IPC_NOT_AVALIABLE);
111 return CONTACTS_ERROR_IPC_NOT_AVALIABLE;
115 CTS_DBG("contacts already connected");
116 return CONTACTS_ERROR_NONE;
119 ret = __ctsvc_ipc_get_cookie_for_access_control(&indata);
120 if (CONTACTS_ERROR_NONE != ret) {
121 CTS_ERR("__ctsvc_ipc_get_cookie_for_access_control fail (%d)", ret);
126 if (pims_ipc_call(__contacts_ipc, CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_CONNECT, indata, &outdata) != 0) {
127 CTS_ERR("pims_ipc_call failed");
128 pims_ipc_data_destroy(indata);
129 ret = CONTACTS_ERROR_IPC;
133 pims_ipc_data_destroy(indata);
136 unsigned int size = 0;
137 ret = *(int*) pims_ipc_data_get(outdata,&size);
139 pims_ipc_data_destroy(outdata);
141 if (ret != CONTACTS_ERROR_NONE) {
142 CTS_ERR("ctsvc_ipc_server_connect return(%d)", ret);
150 pims_ipc_destroy(__contacts_ipc);
151 __contacts_ipc = NULL;
156 int ctsvc_ipc_disconnect_on_thread(void)
158 int ret = CONTACTS_ERROR_NONE;
159 pims_ipc_data_h outdata = NULL;
161 RETVM_IF(__contacts_ipc == NULL, CONTACTS_ERROR_IPC, "contacts not connected");
163 if (pims_ipc_call(__contacts_ipc, CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_DISCONNECT, NULL, &outdata) != 0) {
164 CTS_ERR("pims_ipc_call failed");
165 return CONTACTS_ERROR_IPC;
169 unsigned int size = 0;
170 ret = *(int*) pims_ipc_data_get(outdata,&size);
171 pims_ipc_data_destroy(outdata);
173 if (ret != CONTACTS_ERROR_NONE)
174 CTS_ERR("[GLOBAL_IPC_CHANNEL] pims_ipc didn't destroyed!!!(%d)", ret);
176 pims_ipc_destroy(__contacts_ipc);
177 __contacts_ipc = NULL;
180 CTS_ERR("pims_ipc_call out data is NULL");
181 return CONTACTS_ERROR_IPC;
187 pims_ipc_h ctsvc_get_ipc_handle()
189 if(__contacts_ipc == NULL) {
190 if(__contacts_global_ipc == NULL ) {
191 ASSERT_NOT_REACHED("IPC haven't been initialized yet.");
194 CTS_DBG("fallback to global ipc channel");
195 return __contacts_global_ipc;
198 return __contacts_ipc;
201 bool ctsvc_ipc_is_busy()
205 if(__contacts_ipc != NULL) {
206 ret = pims_ipc_is_call_in_progress(__contacts_ipc);
208 CTS_ERR("thread local ipc channel is busy.");
211 ret = pims_ipc_is_call_in_progress(__contacts_global_ipc);
213 CTS_ERR("global ipc channel is busy.");
219 int ctsvc_ipc_connect(void)
221 int ret = CONTACTS_ERROR_NONE;
222 pims_ipc_data_h indata = NULL;
223 pims_ipc_data_h outdata = NULL;
226 if (__contacts_global_ipc == NULL) {
227 __contacts_global_ipc = pims_ipc_create(CTSVC_IPC_SOCKET_PATH);
228 if (__contacts_global_ipc == NULL) {
229 CTS_ERR("[GLOBAL_IPC_CHANNEL] pims_ipc_create() Failed(%d)", CONTACTS_ERROR_IPC_NOT_AVALIABLE);
230 return CONTACTS_ERROR_IPC_NOT_AVALIABLE;
234 CTS_DBG("[GLOBAL_IPC_CHANNEL] contacts already connected");
235 return CONTACTS_ERROR_NONE;
238 ret = __ctsvc_ipc_get_cookie_for_access_control(&indata);
239 if (CONTACTS_ERROR_NONE != ret) {
240 CTS_ERR("__ctsvc_ipc_get_cookie_for_access_control fail (%d)", ret);
245 if (pims_ipc_call(__contacts_global_ipc, CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_CONNECT, indata, &outdata) != 0) {
246 CTS_ERR("[GLOBAL_IPC_CHANNEL] pims_ipc_call failed");
247 pims_ipc_data_destroy(indata);
248 ret = CONTACTS_ERROR_IPC;
252 pims_ipc_data_destroy(indata);
255 unsigned int size = 0;
256 ret = *(int*) pims_ipc_data_get(outdata,&size);
257 pims_ipc_data_destroy(outdata);
259 if (ret != CONTACTS_ERROR_NONE) {
260 CTS_ERR("ctsvc_ipc_server_connect return(%d)", ret);
267 pims_ipc_destroy(__contacts_global_ipc);
268 __contacts_global_ipc = NULL;
273 int ctsvc_ipc_disconnect(void)
275 int ret = CONTACTS_ERROR_NONE;
276 pims_ipc_data_h outdata = NULL;
278 RETVM_IF(__contacts_global_ipc == NULL, CONTACTS_ERROR_IPC, "[GLOBAL_IPC_CHANNEL] contacts not connected");
280 if (pims_ipc_call(__contacts_global_ipc, CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_DISCONNECT, NULL, &outdata) != 0) {
281 CTS_ERR("[GLOBAL_IPC_CHANNEL] pims_ipc_call failed");
282 return CONTACTS_ERROR_IPC;
286 unsigned int size = 0;
287 ret = *(int*) pims_ipc_data_get(outdata,&size);
288 pims_ipc_data_destroy(outdata);
290 if (ret != CONTACTS_ERROR_NONE)
291 CTS_ERR("[GLOBAL_IPC_CHANNEL] pims_ipc didn't destroyed!!!(%d)", ret);
293 pims_ipc_destroy(__contacts_global_ipc);
294 __contacts_global_ipc = NULL;
297 CTS_ERR("pims_ipc_call out data is NULL");
298 return CONTACTS_ERROR_IPC;
304 static void __ctsvc_ipc_lock()
306 if (__contacts_ipc == NULL)
307 ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_CALL);
310 static void __ctsvc_ipc_unlock(void)
312 if (__contacts_ipc == NULL)
313 ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_CALL);
316 int ctsvc_ipc_call(char *module, char *function, pims_ipc_h data_in, pims_ipc_data_h *data_out)
318 pims_ipc_h ipc_handle = ctsvc_get_ipc_handle();
322 int ret = pims_ipc_call(ipc_handle, module, function, data_in, data_out);
324 __ctsvc_ipc_unlock();
329 int ctsvc_ipc_call_async(char *module, char *function, pims_ipc_h data_in, pims_ipc_call_async_cb callback, void *userdata)
331 pims_ipc_h ipc_handle = ctsvc_get_ipc_handle();
335 int ret = pims_ipc_call_async(ipc_handle, module, function, data_in, callback, userdata);
337 __ctsvc_ipc_unlock();
342 void ctsvc_client_ipc_set_change_version(int version)
344 if (__contacts_ipc == NULL) {
345 __contacts_global_change_version = version;
346 CTS_DBG("change_version = %d", version);
349 __contacts_change_version = version;
350 CTS_DBG("change_version = %d", version);
353 int ctsvc_client_ipc_get_change_version(void)
355 if (__contacts_ipc == NULL)
356 return __contacts_global_change_version;
358 return __contacts_change_version;