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_handle.h"
35 #include "ctsvc_client_service_helper.h"
37 static int _ctsvc_connection = 0;
38 static __thread int _ctsvc_connection_on_thread = 0;
40 int ctsvc_client_get_thread_connection_count()
42 return _ctsvc_connection_on_thread;
45 int ctsvc_client_connect_with_flags(contacts_h contact, unsigned int flags)
48 int ret = CONTACTS_ERROR_NONE;
50 /* If new flag is defined, errer check should be updated */
51 RETVM_IF(flags & 0x11111110, CONTACTS_ERROR_INVALID_PARAMETER, "flags is invalid");
53 ret = ctsvc_client_connect(contact);
54 if (ret == CONTACTS_ERROR_PERMISSION_DENIED)
56 else if (ret == CONTACTS_ERROR_NONE)
59 if (flags & CONTACTS_CONNECT_FLAG_RETRY) {
61 int waiting_time = 500;
63 usleep(waiting_time * 1000);
64 CTS_DBG("retry cnt=%d, ret=%x, %d",(i+1), ret, waiting_time);
65 ret = ctsvc_client_connect(contact);
66 if (ret == CONTACTS_ERROR_NONE)
69 waiting_time += 30000;
78 static void _ctsvc_ipc_disconnected_cb(void *user_data)
80 ctsvc_ipc_set_disconnected(true);
83 static void _ctsvc_ipc_initialized_cb(void *user_data)
86 ctsvc_ipc_recover_for_change_subscription();
87 ctsvc_ipc_set_disconnected(false);
90 int ctsvc_client_connect(contacts_h contact)
94 ctsvc_base_s *base = (ctsvc_base_s *)contact;
96 ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
97 if (0 == base->connection_count) {
98 ret = ctsvc_ipc_connect(contact);
99 if (ret != CONTACTS_ERROR_NONE) {
100 CTS_ERR("ctsvc_ipc_connect() Fail(%d)", ret);
101 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
105 base->connection_count++;
107 if (0 == _ctsvc_connection) {
108 ret = ctsvc_socket_init();
109 if (ret != CONTACTS_ERROR_NONE) {
110 CTS_ERR("ctsvc_socket_init() Fail(%d)", ret);
111 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
115 ret = ctsvc_inotify_init();
116 if (ret != CONTACTS_ERROR_NONE) {
117 CTS_ERR("ctsvc_inotify_init() Fail(%d)", ret);
118 ctsvc_socket_final();
119 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
122 ctsvc_view_uri_init();
123 ctsvc_ipc_create_for_change_subscription();
124 ctsvc_ipc_set_disconnected_cb(_ctsvc_ipc_disconnected_cb, NULL);
127 CTS_DBG("System : Contacts service has been already connected(%d)", _ctsvc_connection + 1);
129 if (1 == base->connection_count)
130 ctsvc_inotify_subscribe_ipc_ready(contact, _ctsvc_ipc_initialized_cb, NULL);
133 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
135 return CONTACTS_ERROR_NONE;
138 int ctsvc_client_disconnect(contacts_h contact)
142 ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
144 ctsvc_base_s *base = (ctsvc_base_s *)contact;
145 if (1 == base->connection_count) {
146 ret = ctsvc_ipc_disconnect(contact, _ctsvc_connection);
147 if (ret != CONTACTS_ERROR_NONE) {
148 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
149 CTS_ERR("ctsvc_ipc_disconnect() Fail(%d)", ret);
152 ctsvc_inotify_unsubscribe_ipc_ready(contact);
153 ctsvc_client_handle_remove((contacts_h)base);
156 base->connection_count--;
159 if (1 == _ctsvc_connection) {
160 ctsvc_ipc_destroy_for_change_subscription();
161 ctsvc_view_uri_deinit();
162 ctsvc_inotify_close();
163 ctsvc_socket_final();
164 ctsvc_ipc_unset_disconnected_cb();
166 else if (1 < _ctsvc_connection)
167 CTS_DBG("System : connection count is %d", _ctsvc_connection);
169 CTS_DBG("System : please call contacts_connect(), connection count is (%d)", _ctsvc_connection);
170 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
171 return CONTACTS_ERROR_INVALID_PARAMETER;
175 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
177 return CONTACTS_ERROR_NONE;
180 int ctsvc_client_connect_on_thread(contacts_h contact)
183 ctsvc_base_s *base = (ctsvc_base_s *)contact;
185 ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
187 if (0 == base->connection_count) {
188 ret = ctsvc_ipc_connect(contact);
189 if (ret != CONTACTS_ERROR_NONE) {
190 CTS_ERR("ctsvc_ipc_connect() Fail(%d)", ret);
191 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
195 base->connection_count++;
197 if (0 == _ctsvc_connection_on_thread) {
198 ret = ctsvc_socket_init();
199 if (ret != CONTACTS_ERROR_NONE) {
200 CTS_ERR("ctsvc_socket_init() Fail(%d)", ret);
201 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
205 ret = ctsvc_inotify_init();
206 if (ret != CONTACTS_ERROR_NONE) {
207 CTS_ERR("ctsvc_inotify_init() Fail(%d)", ret);
208 ctsvc_socket_final();
209 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
212 ctsvc_view_uri_init();
213 ctsvc_ipc_create_for_change_subscription();
214 ctsvc_ipc_set_disconnected_cb(_ctsvc_ipc_disconnected_cb, NULL);
216 else if (0 < _ctsvc_connection_on_thread)
217 CTS_DBG("System : Contacts service has been already connected");
219 if (1 == base->connection_count)
220 ctsvc_inotify_subscribe_ipc_ready(contact, _ctsvc_ipc_initialized_cb, NULL);
222 _ctsvc_connection_on_thread++;
224 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
226 return CONTACTS_ERROR_NONE;
229 int ctsvc_client_disconnect_on_thread(contacts_h contact)
232 ctsvc_base_s *base = (ctsvc_base_s *)contact;
234 ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
236 if (1 == base->connection_count) {
237 ret = ctsvc_ipc_disconnect(contact, _ctsvc_connection_on_thread);
238 if (ret != CONTACTS_ERROR_NONE) {
239 CTS_ERR("ctsvc_ipc_disconnect_on_thread() Fail(%d)", ret);
240 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
243 ctsvc_inotify_unsubscribe_ipc_ready(contact);
244 ctsvc_client_handle_remove((contacts_h)base);
247 base->connection_count--;
250 if (1 == _ctsvc_connection_on_thread) {
251 ctsvc_ipc_destroy_for_change_subscription();
252 ctsvc_view_uri_deinit();
253 ctsvc_inotify_close();
254 ctsvc_socket_final();
255 ctsvc_ipc_unset_disconnected_cb();
256 CTS_DBG("System : connection_on_thread was destroyed successfully");
258 else if (1 < _ctsvc_connection_on_thread) {
259 CTS_DBG("System : connection count is %d", _ctsvc_connection_on_thread);
262 CTS_DBG("System : please call contacts_connect_on_thread(), connection count is (%d)", _ctsvc_connection_on_thread);
263 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
264 return CONTACTS_ERROR_INVALID_PARAMETER;
267 _ctsvc_connection_on_thread--;
269 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
271 return CONTACTS_ERROR_NONE;