Sync code with Tizen 3.0 branch
[platform/core/api/nfc.git] / src / net_nfc_client_manager.c
1 /*
2  * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "net_nfc_debug_internal.h"
18
19 #include "net_nfc_gdbus.h"
20 #include "net_nfc_client.h"
21 #include "net_nfc_client_util_internal.h"
22 #include "net_nfc_client_context.h"
23 #include "net_nfc_client_manager.h"
24
25 #ifndef NET_NFC_EXPORT_API
26 #define NET_NFC_EXPORT_API __attribute__((visibility("default")))
27 #endif
28
29 /* LCOV_EXCL_START */
30
31 #define DEACTIVATE_DELAY        500 /* ms */
32 #define ACTIVATE_DELAY 100 /* ms */
33
34 typedef struct _ManagerFuncData ManagerFuncData;
35
36 struct _ManagerFuncData {
37         gpointer callback;
38         gpointer user_data;
39         net_nfc_error_e result;
40 };
41
42 static NetNfcGDbusManager *manager_proxy = NULL;
43 static NetNfcGDbusManager *auto_start_proxy = NULL;
44 static ManagerFuncData activated_func_data;
45 static int is_activated = -1;
46 static guint timeout_id[2];
47
48 static void manager_call_set_active_callback(GObject *source_object,
49                                         GAsyncResult *res,
50                                         gpointer user_data);
51
52 static void manager_call_get_server_state_callback(GObject *source_object,
53                                                 GAsyncResult *res,
54                                                 gpointer user_data);
55
56
57 static void manager_activated(NetNfcGDbusManager *manager,
58                                 gboolean activated,
59                                 gpointer user_data);
60
61
62 static gboolean _set_activate_time_elapsed_callback(gpointer user_data)
63 {
64         ManagerFuncData *func_data = (ManagerFuncData *)user_data;
65         net_nfc_client_manager_set_active_completed callback;
66
67         if (timeout_id[0] > 0) {
68                 g_assert(func_data != NULL);
69
70                 g_source_remove(timeout_id[0]);
71                 timeout_id[0] = 0;
72
73                 callback = (net_nfc_client_manager_set_active_completed)func_data->callback;
74
75                 callback(func_data->result, func_data->user_data);
76
77                 g_free(func_data);
78         }
79
80         return false;
81 }
82
83 static void manager_call_set_active_callback(GObject *source_object,
84                                         GAsyncResult *res,
85                                         gpointer user_data)
86 {
87         ManagerFuncData *func_data = (ManagerFuncData *)user_data;
88         net_nfc_error_e result;
89         GError *error = NULL;
90
91         g_assert(user_data != NULL);
92
93         if (net_nfc_gdbus_manager_call_set_active_finish(
94                                 NET_NFC_GDBUS_MANAGER(source_object),
95                                 &result,
96                                 res,
97                                 &error) == FALSE) {
98                 DEBUG_ERR_MSG("Can not finish call_set_active: %s",
99                         error->message);
100                 result = NET_NFC_IPC_FAIL;
101
102                 g_error_free(error);
103         }
104
105         func_data->result = result;
106         net_nfc_client_get_nfc_state(&is_activated);
107
108         if (is_activated == false) {
109                 /* FIXME : wait several times */
110                 timeout_id[0] = g_timeout_add(DEACTIVATE_DELAY,
111                         _set_activate_time_elapsed_callback,
112                         func_data);
113         } else {
114                 timeout_id[0] = g_timeout_add(ACTIVATE_DELAY,
115                         _set_activate_time_elapsed_callback,
116                         func_data);
117         }
118 }
119
120 static void manager_call_get_server_state_callback(GObject *source_object,
121                                                 GAsyncResult *res,
122                                                 gpointer user_data)
123 {
124         NetNfcCallback *func_data = (NetNfcCallback *)user_data;
125         net_nfc_error_e result;
126         guint out_state = 0;
127         GError *error = NULL;
128
129         g_assert(user_data != NULL);
130
131         if (net_nfc_gdbus_manager_call_get_server_state_finish(
132                                 NET_NFC_GDBUS_MANAGER(source_object),
133                                 &result,
134                                 &out_state,
135                                 res,
136                                 &error) == FALSE) {
137                 DEBUG_ERR_MSG("Can not finish get_server_state: %s",
138                         error->message);
139                 result = NET_NFC_IPC_FAIL;
140
141                 g_error_free(error);
142         }
143
144         if (func_data->callback != NULL) {
145                 net_nfc_client_manager_get_server_state_completed callback =
146                         (net_nfc_client_manager_get_server_state_completed)func_data->callback;
147
148                 callback(result, out_state, func_data->user_data);
149         }
150
151         g_free(func_data);
152 }
153
154 static gboolean _activated_time_elapsed_callback(gpointer user_data)
155 {
156         net_nfc_client_manager_activated callback =
157                 (net_nfc_client_manager_activated)activated_func_data.callback;
158
159         if (timeout_id[1] > 0) {
160                 g_source_remove(timeout_id[1]);
161                 timeout_id[1] = 0;
162
163                 callback(is_activated, activated_func_data.user_data);
164         }
165
166         return false;
167 }
168
169 static void manager_activated(NetNfcGDbusManager *manager,
170                                 gboolean activated,
171                                 gpointer user_data)
172 {
173         INFO_MSG(">>> SIGNAL arrived");
174         DEBUG_CLIENT_MSG("activated %d", activated);
175
176         /* update current state */
177         is_activated = (int)activated;
178
179         if (activated_func_data.callback != NULL) {
180                 if (is_activated == false) {
181                         /* FIXME : wait several times */
182                         timeout_id[1] = g_timeout_add(DEACTIVATE_DELAY,
183                                 _activated_time_elapsed_callback,
184                                 NULL);
185                 } else {
186                         timeout_id[1] = g_timeout_add(ACTIVATE_DELAY,
187                                 _activated_time_elapsed_callback,
188                                 NULL);
189                 }
190         }
191 }
192
193 NET_NFC_EXPORT_API
194 void net_nfc_client_manager_set_activated(
195                         net_nfc_client_manager_activated callback,
196                         void *user_data)
197 {
198         if (callback == NULL)
199                 return;
200
201         if (manager_proxy == NULL) {
202                 if (net_nfc_client_manager_init() != NET_NFC_OK) {
203                         DEBUG_ERR_MSG("manager_proxy fail");
204                         /* FIXME : return result of this error */
205                         return;
206                 }
207         }
208
209         activated_func_data.callback = callback;
210         activated_func_data.user_data = user_data;
211 }
212
213 NET_NFC_EXPORT_API
214 void net_nfc_client_manager_unset_activated(void)
215 {
216         activated_func_data.callback = NULL;
217         activated_func_data.user_data = NULL;
218 }
219
220 NET_NFC_EXPORT_API
221 net_nfc_error_e net_nfc_client_manager_set_active(int state,
222                         net_nfc_client_manager_set_active_completed callback,
223                         void *user_data)
224 {
225         gboolean active = FALSE;
226         ManagerFuncData *func_data;
227
228         if (auto_start_proxy == NULL) {
229                 GError *error = NULL;
230
231                 auto_start_proxy = net_nfc_gdbus_manager_proxy_new_for_bus_sync(
232                         G_BUS_TYPE_SYSTEM,
233                         G_DBUS_PROXY_FLAGS_NONE,
234                         "org.tizen.NetNfcService",
235                         "/org/tizen/NetNfcService/Manager",
236                         NULL,
237                         &error);
238                 if (auto_start_proxy == NULL) {
239                         DEBUG_ERR_MSG("Can not create proxy : %s", error->message);
240                         g_error_free(error);
241
242                         return NET_NFC_UNKNOWN_ERROR;
243                 }
244         }
245
246         /* allow this function even nfc is off */
247
248         func_data = g_try_new0(ManagerFuncData, 1);
249         if (func_data == NULL)
250                 return NET_NFC_ALLOC_FAIL;
251
252         func_data->callback = (gpointer)callback;
253         func_data->user_data = user_data;
254
255         if (state == true)
256                 active = TRUE;
257
258         net_nfc_gdbus_manager_call_set_active(auto_start_proxy,
259                 active,
260                 NULL,
261                 manager_call_set_active_callback,
262                 func_data);
263
264         return NET_NFC_OK;
265 }
266
267 NET_NFC_EXPORT_API
268 net_nfc_error_e net_nfc_client_manager_set_active_sync(int state)
269 {
270         net_nfc_error_e out_result = NET_NFC_OK;
271         GError *error = NULL;
272
273         if (auto_start_proxy == NULL) {
274                 GError *error = NULL;
275
276                 auto_start_proxy = net_nfc_gdbus_manager_proxy_new_for_bus_sync(
277                         G_BUS_TYPE_SYSTEM,
278                         G_DBUS_PROXY_FLAGS_NONE,
279                         "org.tizen.NetNfcService",
280                         "/org/tizen/NetNfcService/Manager",
281                         NULL,
282                         &error);
283                 if (auto_start_proxy == NULL) {
284                         DEBUG_ERR_MSG("Can not create proxy : %s", error->message);
285                         g_error_free(error);
286
287                         return NET_NFC_UNKNOWN_ERROR;
288                 }
289         }
290
291         /* allow this function even nfc is off */
292
293         if (net_nfc_gdbus_manager_call_set_active_sync(auto_start_proxy,
294                 (gboolean)state,
295                 &out_result,
296                 NULL,
297                 &error) == FALSE) {
298                 DEBUG_ERR_MSG("can not call SetActive: %s",
299                                 error->message);
300                 out_result = NET_NFC_IPC_FAIL;
301
302                 g_error_free(error);
303         }
304
305         return out_result;
306 }
307
308 NET_NFC_EXPORT_API
309 net_nfc_error_e net_nfc_client_manager_get_server_state(
310                 net_nfc_client_manager_get_server_state_completed callback,
311                 void *user_data)
312 {
313         NetNfcCallback *func_data;
314
315         if (manager_proxy == NULL)
316                 return NET_NFC_NOT_INITIALIZED;
317
318         /* prevent executing daemon when nfc is off */
319         if (net_nfc_client_manager_is_activated() == false)
320                 return NET_NFC_NOT_ACTIVATED;
321
322         func_data = g_try_new0(NetNfcCallback, 1);
323         if (func_data == NULL)
324                 return NET_NFC_ALLOC_FAIL;
325
326         func_data->callback = (gpointer) callback;
327         func_data->user_data = user_data;
328
329         net_nfc_gdbus_manager_call_get_server_state(manager_proxy,
330                                         NULL,
331                                         manager_call_get_server_state_callback,
332                                         func_data);
333
334         return NET_NFC_OK;
335 }
336
337 NET_NFC_EXPORT_API
338 net_nfc_error_e net_nfc_client_manager_get_server_state_sync(
339                                                         unsigned int *state)
340 {
341         net_nfc_error_e out_result = NET_NFC_OK;
342         guint out_state = 0;
343         GError *error = NULL;
344
345         if (state == NULL)
346                 return NET_NFC_NULL_PARAMETER;
347
348         *state = 0;
349
350         if (manager_proxy == NULL)
351                 return NET_NFC_NOT_INITIALIZED;
352
353         /* prevent executing daemon when nfc is off */
354         if (net_nfc_client_manager_is_activated() == false)
355                 return NET_NFC_NOT_ACTIVATED;
356
357         if (net_nfc_gdbus_manager_call_get_server_state_sync(manager_proxy,
358                                         &out_result,
359                                         &out_state,
360                                         NULL,
361                                         &error) == TRUE) {
362                 *state = out_state;
363         } else {
364                 DEBUG_ERR_MSG("can not call GetServerState: %s",
365                                 error->message);
366                 out_result = NET_NFC_IPC_FAIL;
367
368                 g_error_free(error);
369         }
370
371         return out_result;
372
373 }
374
375 net_nfc_error_e net_nfc_client_manager_init(void)
376 {
377         GError *error = NULL;
378
379         if (manager_proxy) {
380                 DEBUG_CLIENT_MSG("Already initialized");
381
382                 return NET_NFC_OK;
383         }
384
385         manager_proxy = net_nfc_gdbus_manager_proxy_new_for_bus_sync(
386                 G_BUS_TYPE_SYSTEM,
387                 G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
388                 "org.tizen.NetNfcService",
389                 "/org/tizen/NetNfcService/Manager",
390                 NULL,
391                 &error);
392         if (manager_proxy == NULL) {
393                 DEBUG_ERR_MSG("Can not create proxy : %s", error->message);
394                 g_error_free(error);
395
396                 return NET_NFC_UNKNOWN_ERROR;
397         }
398
399         g_signal_connect(manager_proxy, "activated",
400                         G_CALLBACK(manager_activated), NULL);
401
402         return NET_NFC_OK;
403 }
404
405 void net_nfc_client_manager_deinit(void)
406 {
407         if (manager_proxy) {
408                 int i;
409
410                 for (i = 0; i < 2; i++) {
411                         if (timeout_id[i] > 0) {
412                                 g_source_remove(timeout_id[i]);
413                                 timeout_id[i] = 0;
414                         }
415                 }
416
417                 g_object_unref(manager_proxy);
418                 manager_proxy = NULL;
419         }
420
421         if (auto_start_proxy) {
422                 g_object_unref(auto_start_proxy);
423                 auto_start_proxy = NULL;
424         }
425 }
426
427 /* internal function */
428 bool net_nfc_client_manager_is_activated()
429 {
430         if (is_activated < 0)
431                 net_nfc_client_get_nfc_state(&is_activated);
432
433         return is_activated;
434 }
435
436 /* LCOV_EXCL_STOP */
437