Add user space access control
[platform/core/pim/contacts-service.git] / client / ctsvc_client_service.c
1 /*
2  * Contacts Service
3  *
4  * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Dohyung Jin <dh.jin@samsung.com>
7  *                 Jongwon Lee <gogosing.lee@samsung.com>
8  *                 Donghee Ye <donghee.ye@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23 #include <errno.h>
24 #include <sys/socket.h>
25 #include <sys/un.h>
26 #include <unistd.h>
27 #include <pims-ipc-data.h>
28
29 #include "contacts.h"
30 #include "ctsvc_internal.h"
31 #include "ctsvc_socket.h"
32 #include "ctsvc_mutex.h"
33 #include "ctsvc_inotify.h"
34 #include "ctsvc_client_ipc.h"
35
36 static int ctsvc_connection = 0;
37
38 static __thread int ctsvc_connection_on_thread = 0;
39
40 API int contacts_connect_with_flags(unsigned int flags)
41 {
42         CTS_FN_CALL;
43         int ret = CONTACTS_ERROR_NONE;
44
45         ret = contacts_connect2();
46         if (ret == CONTACTS_ERROR_NONE)
47                 return ret;
48
49         if (flags & CONTACTS_CONNECT_FLAG_RETRY) {
50                 int i;
51                 int waiting_time = 500;
52                 for (i=0;i<9;i++) {
53                         usleep(waiting_time * 1000);
54                         CTS_DBG("retry cnt=%d, ret=%x, %d",(i+1), ret, waiting_time);
55                         ret = contacts_connect2();
56                         if (ret == CONTACTS_ERROR_NONE)
57                                 break;
58                         if (6 < i)
59                                 waiting_time += 30000;
60                         else
61                                 waiting_time *= 2;
62                 }
63         }
64
65         return ret;
66 }
67
68 API int contacts_connect2()
69 {
70         CTS_FN_CALL;
71         int ret;
72
73         ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
74         if (0 == ctsvc_connection) {
75
76                 ret = ctsvc_ipc_connect();
77                 if (ret != CONTACTS_ERROR_NONE) {
78                         CTS_ERR("ctsvc_ipc_connect() Failed(%d)", ret);
79                         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
80                         return ret;
81                 }
82
83                 ret = ctsvc_socket_init();
84                 if (ret != CONTACTS_ERROR_NONE) {
85                         CTS_ERR("ctsvc_socket_init() Failed(%d)", ret);
86                         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
87                         return ret;
88                 }
89
90                 ret = ctsvc_inotify_init();
91                 if (ret != CONTACTS_ERROR_NONE) {
92                         CTS_ERR("ctsvc_inotify_init() Failed(%d)", ret);
93                         ctsvc_socket_final();
94                         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
95                         return ret;
96                 }
97
98                 ctsvc_view_uri_init();
99                 ctsvc_ipc_create_for_change_subscription();
100         }
101         else
102                 CTS_DBG("System : Contacts service has been already connected(%d)", ctsvc_connection + 1);
103
104         ctsvc_connection++;
105         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
106
107         return CONTACTS_ERROR_NONE;
108 }
109
110 API int contacts_disconnect2()
111 {
112         int ret;
113
114         CTS_FN_CALL;
115
116         ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
117         if (1 == ctsvc_connection) {
118                 ctsvc_ipc_destroy_for_change_subscription();
119
120                 ret = ctsvc_ipc_disconnect();
121                 if (ret != CONTACTS_ERROR_NONE) {
122                         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
123                         CTS_ERR("ctsvc_ipc_disconnect() Failed(%d)", ret);
124                         return ret;
125                 }
126
127                 ctsvc_view_uri_deinit();
128                 ctsvc_inotify_close();
129                 ctsvc_socket_final();
130         }
131         else if (1 < ctsvc_connection)
132                 CTS_DBG("System : connection count is %d", ctsvc_connection);
133         else {
134                 CTS_DBG("System : please call contacts_connect2(), connection count is (%d)", ctsvc_connection);
135                 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
136                 return CONTACTS_ERROR_INVALID_PARAMETER;
137         }
138
139         ctsvc_connection--;
140         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
141
142         return CONTACTS_ERROR_NONE;
143 }
144
145 API int contacts_connect_on_thread()
146 {
147         int ret;
148
149         ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
150
151         if (0 == ctsvc_connection_on_thread) {
152                 ret = ctsvc_ipc_connect_on_thread();
153                 if (ret != CONTACTS_ERROR_NONE) {
154                         CTS_ERR("ctsvc_ipc_connect_on_thread() Failed(%d)", ret);
155                         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
156                         return ret;
157                 }
158
159                 ret = ctsvc_socket_init();
160                 if (ret != CONTACTS_ERROR_NONE) {
161                         CTS_ERR("ctsvc_socket_init() Failed(%d)", ret);
162                         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
163                         return ret;
164                 }
165
166                 ret = ctsvc_inotify_init();
167                 if (ret != CONTACTS_ERROR_NONE) {
168                         CTS_ERR("ctsvc_inotify_init() Failed(%d)", ret);
169                         ctsvc_socket_final();
170                         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
171                         return ret;
172                 }
173
174                 ctsvc_view_uri_init();
175                 ctsvc_ipc_create_for_change_subscription();
176         }
177         else if (0 < ctsvc_connection_on_thread)
178                 CTS_DBG("System : Contacts service has been already connected");
179
180         ctsvc_connection_on_thread++;
181
182         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
183
184         return CONTACTS_ERROR_NONE;
185 }
186
187 API int contacts_disconnect_on_thread()
188 {
189         int ret;
190
191         ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
192
193         if (1 == ctsvc_connection_on_thread) {
194                 ctsvc_ipc_destroy_for_change_subscription();
195
196                 ret = ctsvc_ipc_disconnect_on_thread();
197                 if (ret != CONTACTS_ERROR_NONE) {
198                         CTS_ERR("ctsvc_ipc_disconnect_on_thread() Failed(%d)", ret);
199                         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
200                         return ret;
201                 }
202
203                 ctsvc_view_uri_deinit();
204                 ctsvc_inotify_close();
205                 ctsvc_socket_final();
206                 CTS_DBG("System : connection_on_thread was destroyed successfully");
207         }
208         else if (1 < ctsvc_connection_on_thread) {
209                 CTS_DBG("System : connection count is %d", ctsvc_connection_on_thread);
210         }
211         else {
212                 CTS_DBG("System : please call contacts_connect_on_thread(), connection count is (%d)", ctsvc_connection_on_thread);
213                 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
214                 return CONTACTS_ERROR_INVALID_PARAMETER;
215         }
216
217         ctsvc_connection_on_thread--;
218
219         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
220
221         return CONTACTS_ERROR_NONE;
222 }