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;
94 RETV_IF(NULL == base, CONTACTS_ERROR_INVALID_PARAMETER);
96 ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
97 if (0 == base->connection_count) {
98 ret = ctsvc_ipc_connect(contact, ctsvc_client_get_pid());
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();
126 CTS_DBG("System : Contacts service has been already connected(%d)", _ctsvc_connection + 1);
128 if (1 == base->connection_count)
129 ctsvc_inotify_subscribe_ipc_ready(contact, _ctsvc_ipc_initialized_cb, NULL);
132 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
134 return CONTACTS_ERROR_NONE;
137 int ctsvc_client_disconnect(contacts_h contact)
141 ctsvc_base_s *base = (ctsvc_base_s *)contact;
142 RETV_IF(NULL == base, CONTACTS_ERROR_INVALID_PARAMETER);
144 ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
146 if (1 == base->connection_count) {
147 ret = ctsvc_ipc_disconnect(contact, ctsvc_client_get_pid(), _ctsvc_connection);
148 if (ret != CONTACTS_ERROR_NONE) {
149 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
150 CTS_ERR("ctsvc_ipc_disconnect() Fail(%d)", ret);
153 ctsvc_inotify_unsubscribe_ipc_ready(contact);
155 base->connection_count--;
157 if (1 == _ctsvc_connection) {
158 ctsvc_ipc_destroy_for_change_subscription();
159 ctsvc_view_uri_deinit();
160 ctsvc_inotify_close();
161 ctsvc_socket_final();
164 else if (1 < _ctsvc_connection)
165 CTS_DBG("System : connection count is %d", _ctsvc_connection);
167 CTS_DBG("System : please call contacts_connect(), connection count is (%d)", _ctsvc_connection);
168 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
169 return CONTACTS_ERROR_DB;
173 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
175 return CONTACTS_ERROR_NONE;
178 int ctsvc_client_connect_on_thread(contacts_h contact)
181 ctsvc_base_s *base = (ctsvc_base_s *)contact;
182 RETV_IF(NULL == base, CONTACTS_ERROR_INVALID_PARAMETER);
184 ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
186 if (0 == base->connection_count) {
187 ret = ctsvc_ipc_connect(contact, ctsvc_client_get_tid());
188 if (ret != CONTACTS_ERROR_NONE) {
189 CTS_ERR("ctsvc_ipc_connect() Fail(%d)", ret);
190 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
194 base->connection_count++;
196 if (0 == _ctsvc_connection_on_thread) {
197 ret = ctsvc_socket_init();
198 if (ret != CONTACTS_ERROR_NONE) {
199 CTS_ERR("ctsvc_socket_init() Fail(%d)", ret);
200 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
204 ret = ctsvc_inotify_init();
205 if (ret != CONTACTS_ERROR_NONE) {
206 CTS_ERR("ctsvc_inotify_init() Fail(%d)", ret);
207 ctsvc_socket_final();
208 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
211 ctsvc_view_uri_init();
212 ctsvc_ipc_create_for_change_subscription();
214 else if (0 < _ctsvc_connection_on_thread)
215 CTS_DBG("System : Contacts service has been already connected");
217 if (1 == base->connection_count)
218 ctsvc_inotify_subscribe_ipc_ready(contact, _ctsvc_ipc_initialized_cb, NULL);
220 _ctsvc_connection_on_thread++;
222 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
224 return CONTACTS_ERROR_NONE;
227 int ctsvc_client_disconnect_on_thread(contacts_h contact)
230 ctsvc_base_s *base = (ctsvc_base_s *)contact;
231 RETV_IF(NULL == base, CONTACTS_ERROR_INVALID_PARAMETER);
233 ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
235 if (1 == base->connection_count) {
236 ret = ctsvc_ipc_disconnect(contact, ctsvc_client_get_tid(), _ctsvc_connection_on_thread);
237 if (ret != CONTACTS_ERROR_NONE) {
238 CTS_ERR("ctsvc_ipc_disconnect() Fail(%d)", ret);
239 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
242 ctsvc_inotify_unsubscribe_ipc_ready(contact);
244 base->connection_count--;
246 if (1 == _ctsvc_connection_on_thread) {
247 ctsvc_ipc_destroy_for_change_subscription();
248 ctsvc_view_uri_deinit();
249 ctsvc_inotify_close();
250 ctsvc_socket_final();
251 CTS_DBG("System : connection_on_thread was destroyed successfully");
253 else if (1 < _ctsvc_connection_on_thread) {
254 CTS_DBG("System : connection count is %d", _ctsvc_connection_on_thread);
257 CTS_DBG("System : please call contacts_connect_on_thread(), connection count is (%d)", _ctsvc_connection_on_thread);
258 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
259 return CONTACTS_ERROR_DB;
262 _ctsvc_connection_on_thread--;
264 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
266 return CONTACTS_ERROR_NONE;