6d4207b8a6f74a6c8b3c7554303e2fc9dd33a848
[platform/core/pim/contacts-service.git] / client / ctsvc_client_service_helper.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
28 #include "contacts.h"
29 #include "ctsvc_internal.h"
30 #include "ctsvc_socket.h"
31 #include "ctsvc_mutex.h"
32 #include "ctsvc_inotify.h"
33 #include "ctsvc_client_ipc.h"
34 #include "ctsvc_client_utils.h"
35 #include "ctsvc_client_handle.h"
36 #include "ctsvc_client_service_helper.h"
37
38 static int _ctsvc_connection = 0;
39 static __thread int _ctsvc_connection_on_thread = 0;
40
41 int ctsvc_client_get_thread_connection_count()
42 {
43         return _ctsvc_connection_on_thread;
44 }
45
46 int ctsvc_client_connect_with_flags(contacts_h contact, unsigned int flags)
47 {
48         CTS_FN_CALL;
49         int ret = CONTACTS_ERROR_NONE;
50
51         /* If new flag is defined, errer check should be updated */
52         RETVM_IF(flags & 0x11111110, CONTACTS_ERROR_INVALID_PARAMETER, "flags is invalid");
53
54         ret = ctsvc_client_connect(contact);
55         if (ret == CONTACTS_ERROR_PERMISSION_DENIED)
56                 return ret;
57         else if (ret == CONTACTS_ERROR_NONE)
58                 return ret;
59
60         if (flags & CONTACTS_CONNECT_FLAG_RETRY) {
61                 int i;
62                 int waiting_time = 500;
63                 for (i=0;i<9;i++) {
64                         usleep(waiting_time * 1000);
65                         CTS_DBG("retry cnt=%d, ret=%x, %d",(i+1), ret, waiting_time);
66                         ret = ctsvc_client_connect(contact);
67                         if (ret == CONTACTS_ERROR_NONE)
68                                 break;
69                         if (6 < i)
70                                 waiting_time += 30000;
71                         else
72                                 waiting_time *= 2;
73                 }
74         }
75
76         return ret;
77 }
78
79 static void _ctsvc_ipc_initialized_cb(void *user_data)
80 {
81         CTS_FN_CALL;
82         if (true == ctsvc_ipc_get_disconnected()) {
83                 ctsvc_ipc_set_disconnected(false);
84                 ctsvc_ipc_recovery();
85                 ctsvc_ipc_recover_for_change_subscription();
86         }
87 }
88
89 int ctsvc_client_connect(contacts_h contact)
90 {
91         CTS_FN_CALL;
92         int ret;
93         ctsvc_base_s *base = (ctsvc_base_s *)contact;
94
95         ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
96         if (0 == base->connection_count) {
97                 ret = ctsvc_ipc_connect(contact, ctsvc_client_get_pid());
98                 if (ret != CONTACTS_ERROR_NONE) {
99                         CTS_ERR("ctsvc_ipc_connect() Fail(%d)", ret);
100                         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
101                         return ret;
102                 }
103         }
104         base->connection_count++;
105
106         if (0 == _ctsvc_connection) {
107                 ret = ctsvc_socket_init();
108                 if (ret != CONTACTS_ERROR_NONE) {
109                         CTS_ERR("ctsvc_socket_init() Fail(%d)", ret);
110                         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
111                         return ret;
112                 }
113
114                 ret = ctsvc_inotify_init();
115                 if (ret != CONTACTS_ERROR_NONE) {
116                         CTS_ERR("ctsvc_inotify_init() Fail(%d)", ret);
117                         ctsvc_socket_final();
118                         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
119                         return ret;
120                 }
121                 ctsvc_view_uri_init();
122                 ctsvc_ipc_create_for_change_subscription();
123         }
124         else
125                 CTS_DBG("System : Contacts service has been already connected(%d)", _ctsvc_connection + 1);
126
127         if (1 == base->connection_count)
128                 ctsvc_inotify_subscribe_ipc_ready(contact, _ctsvc_ipc_initialized_cb, NULL);
129
130         _ctsvc_connection++;
131         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
132
133         return CONTACTS_ERROR_NONE;
134 }
135
136 int ctsvc_client_disconnect(contacts_h contact)
137 {
138         CTS_FN_CALL;
139         int ret;
140         ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
141
142         ctsvc_base_s *base = (ctsvc_base_s *)contact;
143         if (1 == base->connection_count) {
144                 ret = ctsvc_ipc_disconnect(contact, ctsvc_client_get_pid(), _ctsvc_connection);
145                 if (ret != CONTACTS_ERROR_NONE) {
146                         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
147                         CTS_ERR("ctsvc_ipc_disconnect() Fail(%d)", ret);
148                         return ret;
149                 }
150                 ctsvc_inotify_unsubscribe_ipc_ready(contact);
151         }
152         base->connection_count--;
153
154         if (1 == _ctsvc_connection) {
155                 ctsvc_ipc_destroy_for_change_subscription();
156                 ctsvc_view_uri_deinit();
157                 ctsvc_inotify_close();
158                 ctsvc_socket_final();
159
160         }
161         else if (1 < _ctsvc_connection)
162                 CTS_DBG("System : connection count is %d", _ctsvc_connection);
163         else {
164                 CTS_DBG("System : please call contacts_connect(), connection count is (%d)", _ctsvc_connection);
165                 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
166                 return CONTACTS_ERROR_DB;
167         }
168
169         _ctsvc_connection--;
170         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
171
172         return CONTACTS_ERROR_NONE;
173 }
174
175 int ctsvc_client_connect_on_thread(contacts_h contact)
176 {
177         int ret;
178         ctsvc_base_s *base = (ctsvc_base_s *)contact;
179
180         ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
181
182         if (0 == base->connection_count) {
183                 ret = ctsvc_ipc_connect(contact, ctsvc_client_get_tid());
184                 if (ret != CONTACTS_ERROR_NONE) {
185                         CTS_ERR("ctsvc_ipc_connect() Fail(%d)", ret);
186                         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
187                         return ret;
188                 }
189         }
190         base->connection_count++;
191
192         if (0 == _ctsvc_connection_on_thread) {
193                 ret = ctsvc_socket_init();
194                 if (ret != CONTACTS_ERROR_NONE) {
195                         CTS_ERR("ctsvc_socket_init() Fail(%d)", ret);
196                         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
197                         return ret;
198                 }
199
200                 ret = ctsvc_inotify_init();
201                 if (ret != CONTACTS_ERROR_NONE) {
202                         CTS_ERR("ctsvc_inotify_init() Fail(%d)", ret);
203                         ctsvc_socket_final();
204                         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
205                         return ret;
206                 }
207                 ctsvc_view_uri_init();
208                 ctsvc_ipc_create_for_change_subscription();
209         }
210         else if (0 < _ctsvc_connection_on_thread)
211                 CTS_DBG("System : Contacts service has been already connected");
212
213         if (1 == base->connection_count)
214                 ctsvc_inotify_subscribe_ipc_ready(contact, _ctsvc_ipc_initialized_cb, NULL);
215
216         _ctsvc_connection_on_thread++;
217
218         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
219
220         return CONTACTS_ERROR_NONE;
221 }
222
223 int ctsvc_client_disconnect_on_thread(contacts_h contact)
224 {
225         int ret;
226         ctsvc_base_s *base = (ctsvc_base_s *)contact;
227
228         ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
229
230         if (1 == base->connection_count) {
231                 ret = ctsvc_ipc_disconnect(contact, ctsvc_client_get_tid(), _ctsvc_connection_on_thread);
232                 if (ret != CONTACTS_ERROR_NONE) {
233                         CTS_ERR("ctsvc_ipc_disconnect() Fail(%d)", ret);
234                         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
235                         return ret;
236                 }
237                 ctsvc_inotify_unsubscribe_ipc_ready(contact);
238         }
239         base->connection_count--;
240
241         if (1 == _ctsvc_connection_on_thread) {
242                 ctsvc_ipc_destroy_for_change_subscription();
243                 ctsvc_view_uri_deinit();
244                 ctsvc_inotify_close();
245                 ctsvc_socket_final();
246                 CTS_DBG("System : connection_on_thread was destroyed successfully");
247         }
248         else if (1 < _ctsvc_connection_on_thread) {
249                 CTS_DBG("System : connection count is %d", _ctsvc_connection_on_thread);
250         }
251         else {
252                 CTS_DBG("System : please call contacts_connect_on_thread(), connection count is (%d)", _ctsvc_connection_on_thread);
253                 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
254                 return CONTACTS_ERROR_DB;
255         }
256
257         _ctsvc_connection_on_thread--;
258
259         ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
260
261         return CONTACTS_ERROR_NONE;
262 }
263