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.
22 #include <pims-ipc-data.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 int ctsvc_ipc_connect_on_thread(void)
45 int ret = CONTACTS_ERROR_NONE;
46 pims_ipc_data_h outdata = NULL;
49 if (__contacts_ipc == NULL) {
50 char sock_file[CTSVC_PATH_MAX_LEN] = {0};
51 snprintf(sock_file, sizeof(sock_file), CTSVC_SOCK_PATH"/.%s", getuid(), CTSVC_IPC_SERVICE);
52 __contacts_ipc = pims_ipc_create(sock_file);
53 if (__contacts_ipc == NULL) {
54 if (errno == EACCES) {
55 CTS_ERR("pims_ipc_create() Fail(%d)", CONTACTS_ERROR_PERMISSION_DENIED);
56 return CONTACTS_ERROR_PERMISSION_DENIED;
59 CTS_ERR("pims_ipc_create() Fail(%d)", CONTACTS_ERROR_IPC_NOT_AVALIABLE);
60 return CONTACTS_ERROR_IPC_NOT_AVALIABLE;
65 CTS_DBG("contacts already connected");
66 return CONTACTS_ERROR_NONE;
70 if (pims_ipc_call(__contacts_ipc, CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_CONNECT, NULL, &outdata) != 0) {
71 CTS_ERR("pims_ipc_call Fail");
72 ret = CONTACTS_ERROR_IPC;
77 unsigned int size = 0;
78 ret = *(int*) pims_ipc_data_get(outdata,&size);
80 pims_ipc_data_destroy(outdata);
82 if (ret != CONTACTS_ERROR_NONE) {
83 CTS_ERR("ctsvc_ipc_server_connect return(%d)", ret);
91 pims_ipc_destroy(__contacts_ipc);
92 __contacts_ipc = NULL;
97 int ctsvc_ipc_disconnect_on_thread(void)
99 int ret = CONTACTS_ERROR_NONE;
100 pims_ipc_data_h outdata = NULL;
102 RETVM_IF(__contacts_ipc == NULL, CONTACTS_ERROR_IPC, "contacts not connected");
104 if (pims_ipc_call(__contacts_ipc, CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_DISCONNECT, NULL, &outdata) != 0) {
105 CTS_ERR("pims_ipc_call Fail");
106 return CONTACTS_ERROR_IPC;
110 unsigned int size = 0;
111 ret = *(int*) pims_ipc_data_get(outdata,&size);
112 pims_ipc_data_destroy(outdata);
114 if (ret != CONTACTS_ERROR_NONE)
115 CTS_ERR("[GLOBAL_IPC_CHANNEL] pims_ipc didn't destroyed!!!(%d)", ret);
117 pims_ipc_destroy(__contacts_ipc);
118 __contacts_ipc = NULL;
121 CTS_ERR("pims_ipc_call out data is NULL");
122 return CONTACTS_ERROR_IPC;
128 pims_ipc_h ctsvc_get_ipc_handle()
130 if (__contacts_ipc == NULL) {
131 if (__contacts_global_ipc == NULL) {
132 CTS_ERR("IPC haven't been initialized yet.");
135 CTS_DBG("fallback to global ipc channel");
136 return __contacts_global_ipc;
139 return __contacts_ipc;
142 bool ctsvc_ipc_is_busy()
146 if (__contacts_ipc != NULL) {
147 ret = pims_ipc_is_call_in_progress(__contacts_ipc);
149 CTS_ERR("thread local ipc channel is busy.");
152 ret = pims_ipc_is_call_in_progress(__contacts_global_ipc);
154 CTS_ERR("global ipc channel is busy.");
160 int ctsvc_ipc_connect(void)
162 int ret = CONTACTS_ERROR_NONE;
163 pims_ipc_data_h outdata = NULL;
166 if (__contacts_global_ipc == NULL) {
167 char sock_file[CTSVC_PATH_MAX_LEN] = {0};
168 snprintf(sock_file, sizeof(sock_file), CTSVC_SOCK_PATH"/.%s", getuid(), CTSVC_IPC_SERVICE);
169 __contacts_global_ipc = pims_ipc_create(sock_file);
170 if (__contacts_global_ipc == NULL) {
171 if (errno == EACCES) {
172 CTS_ERR("[GLOBAL_IPC_CHANNEL] pims_ipc_create() Fail(%d)", CONTACTS_ERROR_PERMISSION_DENIED);
173 return CONTACTS_ERROR_PERMISSION_DENIED;
176 CTS_ERR("[GLOBAL_IPC_CHANNEL] pims_ipc_create() Fail(%d)", CONTACTS_ERROR_IPC_NOT_AVALIABLE);
177 return CONTACTS_ERROR_IPC_NOT_AVALIABLE;
182 CTS_DBG("[GLOBAL_IPC_CHANNEL] contacts already connected");
183 return CONTACTS_ERROR_NONE;
187 if (pims_ipc_call(__contacts_global_ipc, CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_CONNECT, NULL, &outdata) != 0) {
188 CTS_ERR("[GLOBAL_IPC_CHANNEL] pims_ipc_call Fail");
189 ret = CONTACTS_ERROR_IPC;
194 unsigned int size = 0;
195 ret = *(int*) pims_ipc_data_get(outdata,&size);
196 pims_ipc_data_destroy(outdata);
198 if (ret != CONTACTS_ERROR_NONE) {
199 CTS_ERR("ctsvc_ipc_server_connect return(%d)", ret);
206 pims_ipc_destroy(__contacts_global_ipc);
207 __contacts_global_ipc = NULL;
212 int ctsvc_ipc_disconnect(void)
214 int ret = CONTACTS_ERROR_NONE;
215 pims_ipc_data_h outdata = NULL;
217 RETVM_IF(__contacts_global_ipc == NULL, CONTACTS_ERROR_IPC, "[GLOBAL_IPC_CHANNEL] contacts not connected");
219 if (pims_ipc_call(__contacts_global_ipc, CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_DISCONNECT, NULL, &outdata) != 0) {
220 CTS_ERR("[GLOBAL_IPC_CHANNEL] pims_ipc_call Fail");
221 return CONTACTS_ERROR_IPC;
225 unsigned int size = 0;
226 ret = *(int*) pims_ipc_data_get(outdata,&size);
227 pims_ipc_data_destroy(outdata);
229 if (ret != CONTACTS_ERROR_NONE)
230 CTS_ERR("[GLOBAL_IPC_CHANNEL] pims_ipc didn't destroyed!!!(%d)", ret);
232 pims_ipc_destroy(__contacts_global_ipc);
233 __contacts_global_ipc = NULL;
236 CTS_ERR("pims_ipc_call out data is NULL");
237 return CONTACTS_ERROR_IPC;
243 static void __ctsvc_ipc_lock()
245 if (__contacts_ipc == NULL)
246 ctsvc_mutex_lock(CTS_MUTEX_PIMS_IPC_CALL);
249 static void __ctsvc_ipc_unlock(void)
251 if (__contacts_ipc == NULL)
252 ctsvc_mutex_unlock(CTS_MUTEX_PIMS_IPC_CALL);
255 int ctsvc_ipc_call(char *module, char *function, pims_ipc_h data_in, pims_ipc_data_h *data_out)
257 pims_ipc_h ipc_handle = ctsvc_get_ipc_handle();
261 int ret = pims_ipc_call(ipc_handle, module, function, data_in, data_out);
263 __ctsvc_ipc_unlock();
268 void ctsvc_client_ipc_set_change_version(int version)
270 if (__contacts_ipc == NULL) {
271 __contacts_global_change_version = version;
272 CTS_DBG("change_version = %d", version);
275 __contacts_change_version = version;
276 CTS_DBG("change_version = %d", version);
279 int ctsvc_client_ipc_get_change_version(void)
281 if (__contacts_ipc == NULL)
282 return __contacts_global_change_version;
284 return __contacts_change_version;
287 int ctsvc_ipc_client_check_permission(int permission, bool *result)
289 pims_ipc_data_h indata = NULL;
290 pims_ipc_data_h outdata = NULL;
296 indata = pims_ipc_data_create(0);
297 if (indata == NULL) {
298 CTS_ERR("ipc data created fail !");
299 return CONTACTS_ERROR_OUT_OF_MEMORY;
302 ret = ctsvc_ipc_marshal_int(permission, indata);
303 if (ret != CONTACTS_ERROR_NONE) {
304 CTS_ERR("marshal fail");
305 pims_ipc_data_destroy(indata);
309 if (ctsvc_ipc_call(CTSVC_IPC_MODULE, CTSVC_IPC_SERVER_CHECK_PERMISSION, indata, &outdata) != 0) {
310 CTS_ERR("ctsvc_ipc_call Fail");
311 pims_ipc_data_destroy(indata);
312 return CONTACTS_ERROR_IPC;
315 pims_ipc_data_destroy(indata);
318 unsigned int size = 0;
319 ret = *(int*) pims_ipc_data_get(outdata,&size);
321 if (ret == CONTACTS_ERROR_NONE) {
323 *result = *(bool*) pims_ipc_data_get(outdata, &size);
325 pims_ipc_data_destroy(outdata);