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;
174 if (0 == base->connection_count) {
175 CTS_INFO("connection_count is 0. remove handle");
176 ret = ctsvc_client_handle_remove(ctsvc_client_get_pid(), contact);
177 WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_client_handle_remove() Fail(%d)", ret);
179 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
181 return CONTACTS_ERROR_NONE;
184 int ctsvc_client_connect_on_thread(contacts_h contact)
187 ctsvc_base_s *base = (ctsvc_base_s *)contact;
188 RETV_IF(NULL == base, CONTACTS_ERROR_INVALID_PARAMETER);
190 ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
192 if (0 == base->connection_count) {
193 ret = ctsvc_ipc_connect(contact, ctsvc_client_get_tid());
194 if (ret != CONTACTS_ERROR_NONE) {
195 CTS_ERR("ctsvc_ipc_connect() Fail(%d)", ret);
196 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
200 base->connection_count++;
202 if (0 == _ctsvc_connection_on_thread) {
203 ret = ctsvc_socket_init();
204 if (ret != CONTACTS_ERROR_NONE) {
205 CTS_ERR("ctsvc_socket_init() Fail(%d)", ret);
206 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
210 ret = ctsvc_inotify_init();
211 if (ret != CONTACTS_ERROR_NONE) {
212 CTS_ERR("ctsvc_inotify_init() Fail(%d)", ret);
213 ctsvc_socket_final();
214 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
217 ctsvc_view_uri_init();
218 ctsvc_ipc_create_for_change_subscription();
220 else if (0 < _ctsvc_connection_on_thread)
221 CTS_DBG("System : Contacts service has been already connected");
223 if (1 == base->connection_count)
224 ctsvc_inotify_subscribe_ipc_ready(contact, _ctsvc_ipc_initialized_cb, NULL);
226 _ctsvc_connection_on_thread++;
228 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
230 return CONTACTS_ERROR_NONE;
233 int ctsvc_client_disconnect_on_thread(contacts_h contact)
236 ctsvc_base_s *base = (ctsvc_base_s *)contact;
237 RETV_IF(NULL == base, CONTACTS_ERROR_INVALID_PARAMETER);
239 ctsvc_mutex_lock(CTS_MUTEX_CONNECTION);
241 if (1 == base->connection_count) {
242 ret = ctsvc_ipc_disconnect(contact, ctsvc_client_get_tid(), _ctsvc_connection_on_thread);
243 if (ret != CONTACTS_ERROR_NONE) {
244 CTS_ERR("ctsvc_ipc_disconnect() Fail(%d)", ret);
245 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
248 ctsvc_inotify_unsubscribe_ipc_ready(contact);
250 base->connection_count--;
252 if (1 == _ctsvc_connection_on_thread) {
253 ctsvc_ipc_destroy_for_change_subscription();
254 ctsvc_view_uri_deinit();
255 ctsvc_inotify_close();
256 ctsvc_socket_final();
257 CTS_DBG("System : connection_on_thread was destroyed successfully");
259 else if (1 < _ctsvc_connection_on_thread) {
260 CTS_DBG("System : connection count is %d", _ctsvc_connection_on_thread);
263 CTS_DBG("System : please call contacts_connect_on_thread(), connection count is (%d)", _ctsvc_connection_on_thread);
264 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
265 return CONTACTS_ERROR_DB;
268 _ctsvc_connection_on_thread--;
270 if (0 == base->connection_count) {
271 CTS_INFO("connection_count is 0. remove handle");
272 ret = ctsvc_client_handle_remove(ctsvc_client_get_tid(), contact);
273 WARN_IF(CONTACTS_ERROR_NONE != ret, "ctsvc_client_handle_remove() Fail(%d)", ret);
275 ctsvc_mutex_unlock(CTS_MUTEX_CONNECTION);
277 return CONTACTS_ERROR_NONE;