4 * Copyright (c) 2010 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Dohyung Jin <dh.jin@samsung.com>
7 * Jongwon Lee <gogosing.lee@samsung.com>
8 * Donghee Ye <donghee.ye@samsung.com>
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
14 * http://www.apache.org/licenses/LICENSE-2.0
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.
24 #include <sys/socket.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"
38 static int _ctsvc_connection = 0;
39 static __thread int _ctsvc_connection_on_thread = 0;
41 int ctsvc_client_get_thread_connection_count()
43 return _ctsvc_connection_on_thread;
46 int ctsvc_client_connect_with_flags(contacts_h contact, unsigned int flags)
49 int ret = CONTACTS_ERROR_NONE;
51 /* If new flag is defined, errer check should be updated */
52 RETVM_IF(flags & 0x11111110, CONTACTS_ERROR_INVALID_PARAMETER, "flags is invalid");
54 ret = ctsvc_client_connect(contact);
55 if (ret == CONTACTS_ERROR_PERMISSION_DENIED)
57 else if (ret == CONTACTS_ERROR_NONE)
60 if (flags & CONTACTS_CONNECT_FLAG_RETRY) {
62 int waiting_time = 500;
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)
70 waiting_time += 30000;
79 static void _ctsvc_ipc_initialized_cb(void *user_data)
82 if (true == ctsvc_ipc_get_disconnected()) {
83 ctsvc_ipc_set_disconnected(false);
85 ctsvc_ipc_recover_for_change_subscription();
89 int ctsvc_client_connect(contacts_h contact)
93 ctsvc_base_s *base = (ctsvc_base_s *)contact;
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);
104 base->connection_count++;
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);
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);
121 ctsvc_view_uri_init();
122 ctsvc_ipc_create_for_change_subscription();
125 CTS_DBG("System : Contacts service has been already connected(%d)", _ctsvc_connection + 1);
127 if (1 == base->connection_count)
128 ctsvc_inotify_subscribe_ipc_ready(contact, _ctsvc_ipc_initialized_cb, NULL);
131 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
133 return CONTACTS_ERROR_NONE;
136 int ctsvc_client_disconnect(contacts_h contact)
140 ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
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);
150 ctsvc_inotify_unsubscribe_ipc_ready(contact);
152 base->connection_count--;
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();
161 else if (1 < _ctsvc_connection)
162 CTS_DBG("System : connection count is %d", _ctsvc_connection);
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;
170 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
172 return CONTACTS_ERROR_NONE;
175 int ctsvc_client_connect_on_thread(contacts_h contact)
178 ctsvc_base_s *base = (ctsvc_base_s *)contact;
180 ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
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);
190 base->connection_count++;
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);
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);
207 ctsvc_view_uri_init();
208 ctsvc_ipc_create_for_change_subscription();
210 else if (0 < _ctsvc_connection_on_thread)
211 CTS_DBG("System : Contacts service has been already connected");
213 if (1 == base->connection_count)
214 ctsvc_inotify_subscribe_ipc_ready(contact, _ctsvc_ipc_initialized_cb, NULL);
216 _ctsvc_connection_on_thread++;
218 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
220 return CONTACTS_ERROR_NONE;
223 int ctsvc_client_disconnect_on_thread(contacts_h contact)
226 ctsvc_base_s *base = (ctsvc_base_s *)contact;
228 ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
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);
237 ctsvc_inotify_unsubscribe_ipc_ready(contact);
239 base->connection_count--;
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");
248 else if (1 < _ctsvc_connection_on_thread) {
249 CTS_DBG("System : connection count is %d", _ctsvc_connection_on_thread);
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;
257 _ctsvc_connection_on_thread--;
259 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
261 return CONTACTS_ERROR_NONE;