Remove unnecessary setting
[platform/core/connectivity/nfc-manager-neard.git] / client / net_nfc_client_tag.c
1 /*
2  * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (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://www.apache.org/licenses/LICENSE-2.0
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 #include "net_nfc_typedef_internal.h"
17 #include "net_nfc_debug_internal.h"
18 #include "net_nfc_util_gdbus_internal.h"
19 #include "net_nfc_gdbus.h"
20 #include "net_nfc_data.h"
21 #include "net_nfc_target_info.h"
22 #include "net_nfc_client.h"
23 #include "net_nfc_client_manager.h"
24 #include "net_nfc_client_tag.h"
25 #include "net_nfc_client_tag_internal.h"
26 #include "net_nfc_neard.h"
27
28
29 static NetNfcGDbusTag *tag_proxy = NULL;
30
31 static NetNfcCallback tag_discovered_func_data;
32 static NetNfcCallback tag_detached_func_data;
33
34 static net_nfc_target_info_s *client_target_info = NULL;
35 static net_nfc_event_filter_e client_filter = NET_NFC_ALL_ENABLE;
36
37 static gboolean tag_check_filter(net_nfc_target_type_e type)
38 {
39         net_nfc_event_filter_e converted = NET_NFC_ALL_ENABLE;
40
41         NFC_DBG("client filter =  %d", client_filter);
42
43         if (type >= NET_NFC_ISO14443_A_PICC
44                         && type <= NET_NFC_MIFARE_DESFIRE_PICC)
45         {
46                 converted = NET_NFC_ISO14443A_ENABLE;
47         }
48         else if (type >= NET_NFC_ISO14443_B_PICC
49                         && type <= NET_NFC_ISO14443_BPRIME_PICC)
50         {
51                 converted = NET_NFC_ISO14443B_ENABLE;
52         }
53         else if (type == NET_NFC_FELICA_PICC)
54         {
55                 converted = NET_NFC_FELICA_ENABLE;
56         }
57         else if (type == NET_NFC_JEWEL_PICC)
58         {
59                 converted = NET_NFC_FELICA_ENABLE;
60         }
61         else if (type == NET_NFC_ISO15693_PICC)
62         {
63                 converted = NET_NFC_ISO15693_ENABLE;
64         }
65
66         if ((converted & client_filter) == 0)
67                 return FALSE;
68
69         return TRUE;
70 }
71
72 static void tag_get_info_list(guint8 *buffer, gint number_of_keys,
73                 net_nfc_tag_info_s **list)
74 {
75         gint i = 0;
76         gint length;
77         guint8 *pos = buffer;
78         net_nfc_tag_info_s *current = NULL;
79         net_nfc_tag_info_s *tmp_list = NULL;
80
81         RET_IF(NULL == buffer);
82
83         tmp_list = g_new0(net_nfc_tag_info_s, number_of_keys);
84         current = tmp_list;
85
86         while (i < number_of_keys)
87         {
88                 gchar *str = NULL;
89                 data_s *value = NULL;
90
91                 /* key */
92                 length = *pos;  /* first values is length of key */
93                 pos++;
94
95                 str = g_new0(gchar, length + 1);
96                 memcpy(str, pos, length);
97
98                 NFC_DBG("key = [%s]", str);
99
100                 pos += length;
101
102                 current->key = str;
103
104                 /* value */
105                 length = *pos; /* first value is length of value */
106                 pos++;
107
108                 value = NULL;
109                 if (length > 0)
110                 {
111                         net_nfc_create_data(&value, pos, length);
112                         pos += length;
113                 }
114
115                 current->value = value;
116
117                 current++;
118                 i++;
119         }
120
121         *list = tmp_list;
122 }
123
124 static void tag_get_target_info(guint handle,
125                 guint dev_type,
126                 gboolean is_ndef_supported,
127                 guchar ndef_card_state,
128                 guint max_data_size,
129                 guint actual_data_size,
130                 guint number_of_keys,
131                 GVariant *target_info_values,
132                 GVariant *raw_data,
133                 net_nfc_target_info_s **info)
134 {
135         guint8 *buffer = NULL;
136         net_nfc_tag_info_s *list = NULL;
137         net_nfc_target_info_s *info_data = NULL;
138
139         RET_IF(NULL == info);
140
141         net_nfc_util_gdbus_variant_to_buffer(target_info_values, &buffer, NULL);
142
143         tag_get_info_list(buffer, number_of_keys, &list);
144
145         info_data = g_new0(net_nfc_target_info_s, 1);
146
147         info_data->ndefCardState = ndef_card_state;
148         info_data->actualDataSize = actual_data_size;
149         info_data->maxDataSize = max_data_size;
150         info_data->devType = dev_type;
151         info_data->handle = GUINT_TO_POINTER(handle);
152         info_data->is_ndef_supported = (uint8_t)is_ndef_supported;
153         info_data->number_of_keys = number_of_keys;
154         info_data->tag_info_list = list;
155
156         net_nfc_util_gdbus_variant_to_data_s(raw_data, &info_data->raw_data);
157
158         *info = info_data;
159 }
160 #if 0
161 static void tag_is_tag_connected(GObject *source_object,
162                 GAsyncResult *res, gpointer user_data)
163 {
164         gboolean ret;
165         GError *error = NULL;
166         net_nfc_error_e out_result;
167         gboolean out_is_connected = false;
168         NetNfcCallback *func_data = (NetNfcCallback *)user_data;
169         net_nfc_target_type_e out_dev_type = NET_NFC_UNKNOWN_TARGET;
170
171         g_assert(user_data != NULL);
172
173         ret = net_nfc_gdbus_tag_call_is_tag_connected_finish(
174                         NET_NFC_GDBUS_TAG(source_object),
175                         &out_result,
176                         &out_is_connected,
177                         (gint32 *)&out_dev_type,
178                         res,
179                         &error);
180
181         if (FALSE == ret)
182         {
183                 NFC_ERR("Can not finish is_tag_connected: %s", error->message);
184                 g_error_free(error);
185
186                 out_result = NET_NFC_IPC_FAIL;
187         }
188
189         if (func_data->callback != NULL)
190         {
191                 net_nfc_client_tag_is_tag_connected_completed callback =
192                         (net_nfc_client_tag_is_tag_connected_completed)func_data->callback;
193
194                 if (out_is_connected == FALSE)
195                         out_result = NET_NFC_NOT_CONNECTED;
196
197                 callback(out_result, out_dev_type, func_data->user_data);
198         }
199
200         g_free(func_data);
201 }
202
203 static void tag_get_current_tag_info(GObject *source_object,
204                 GAsyncResult *res, gpointer user_data)
205 {
206         gboolean ret;
207         guint out_handle = 0;
208         GError *error = NULL;
209         guint out_max_data_size = 0;
210         guint out_number_of_keys = 0;
211         GVariant *out_raw_data = NULL;
212         guchar out_ndef_card_state = 0;
213         guint out_actual_data_size = 0;
214         gboolean out_is_connected = FALSE;
215         gboolean out_is_ndef_supported = FALSE;
216         GVariant *out_target_info_values = NULL;
217         net_nfc_error_e out_result = NET_NFC_OK;
218         NetNfcCallback *func_data = (NetNfcCallback *)user_data;
219         net_nfc_target_type_e out_dev_type = NET_NFC_UNKNOWN_TARGET;
220
221         g_assert(user_data != NULL);
222
223         ret = net_nfc_gdbus_tag_call_get_current_tag_info_finish (
224                         NET_NFC_GDBUS_TAG(source_object),
225                         &out_result,
226                         &out_is_connected,
227                         &out_handle,
228                         (gint *)&out_dev_type,
229                         &out_is_ndef_supported,
230                         &out_ndef_card_state,
231                         &out_max_data_size,
232                         &out_actual_data_size,
233                         &out_number_of_keys,
234                         &out_target_info_values,
235                         &out_raw_data,
236                         res,
237                         &error);
238
239         if (FALSE == ret)
240         {
241                 out_result = NET_NFC_IPC_FAIL;
242
243                 NFC_ERR("Can not finish get_current_tag_info: %s", error->message);
244                 g_error_free(error);
245         }
246
247         if (out_result == NET_NFC_OK && out_is_connected == true)
248         {
249                 net_nfc_release_tag_info(client_target_info);
250                 client_target_info = NULL;
251
252                 if (tag_check_filter(out_dev_type) == true)
253                 {
254                         tag_get_target_info(out_handle,
255                                         out_dev_type,
256                                         out_is_ndef_supported,
257                                         out_ndef_card_state,
258                                         out_max_data_size,
259                                         out_actual_data_size,
260                                         out_number_of_keys,
261                                         out_target_info_values,
262                                         out_raw_data,
263                                         &client_target_info);
264                 }
265                 else
266                 {
267                         NFC_INFO("The detected target is filtered out, type [%d]", out_dev_type);
268
269                         out_is_connected = false;
270                 }
271         }
272
273         if (func_data->callback != NULL)
274         {
275                 net_nfc_client_tag_get_current_tag_info_completed callback =
276                         (net_nfc_client_tag_get_current_tag_info_completed)func_data->callback;
277
278                 if (out_result == NET_NFC_OK && out_is_connected == false)
279                         out_result = NET_NFC_NOT_CONNECTED;
280
281                 callback(out_result, client_target_info, func_data->user_data);
282         }
283
284         g_free(func_data);
285 }
286
287 static void tag_get_current_target_handle(GObject *source_object,
288                 GAsyncResult *res, gpointer user_data)
289 {
290         gboolean ret;
291         GError *error = NULL;
292         gboolean out_is_connected = false;
293         net_nfc_error_e out_result = NET_NFC_OK;
294         net_nfc_target_handle_s *out_handle = NULL;
295         NetNfcCallback *func_data = (NetNfcCallback *)user_data;
296         net_nfc_target_type_e out_dev_type = NET_NFC_UNKNOWN_TARGET;
297
298         g_assert(user_data != NULL);
299
300         ret = net_nfc_gdbus_tag_call_get_current_target_handle_finish(
301                         NET_NFC_GDBUS_TAG(source_object),
302                         &out_result,
303                         &out_is_connected,
304                         (guint *)&out_handle,
305                         (gint *)&out_dev_type,
306                         res,
307                         &error);
308
309         if (FALSE == ret)
310         {
311                 NFC_ERR("Can not finish get_current_target_handle: %s", error->message);
312                 g_error_free(error);
313
314                 out_result = NET_NFC_IPC_FAIL;
315         }
316
317         if (func_data->callback != NULL)
318         {
319                 net_nfc_client_tag_get_current_target_handle_completed callback =
320                         (net_nfc_client_tag_get_current_target_handle_completed)func_data->callback;
321
322                 if (out_result == NET_NFC_OK && out_is_connected == FALSE)
323                         out_result = NET_NFC_NOT_CONNECTED;
324
325                 callback(out_result, GUINT_TO_POINTER(out_handle), func_data->user_data);
326         }
327
328         g_free(func_data);
329 }
330 #endif
331 static void tag_tag_discovered(NetNfcGDbusTag *object,
332                 guint arg_handle,
333                 gint arg_dev_type,
334                 gboolean arg_is_ndef_supported,
335                 guchar arg_ndef_card_state,
336                 guint arg_max_data_size,
337                 guint arg_actual_data_size,
338                 guint arg_number_of_keys,
339                 GVariant *arg_target_info_values,
340                 GVariant *arg_raw_data,
341                 gpointer user_data)
342 {
343         net_nfc_client_tag_tag_discovered callback;
344
345         NFC_INFO(">>> SIGNAL arrived");
346
347         net_nfc_release_tag_info(client_target_info);
348         client_target_info = NULL;
349
350         if (tag_check_filter(arg_dev_type) == FALSE)
351         {
352                 NFC_INFO("The detected target is filtered out, type [%d]", arg_dev_type);
353
354                 return;
355         }
356
357         tag_get_target_info(arg_handle,
358                         arg_dev_type,
359                         arg_is_ndef_supported,
360                         arg_ndef_card_state,
361                         arg_max_data_size,
362                         arg_actual_data_size,
363                         arg_number_of_keys,
364                         arg_target_info_values,
365                         arg_raw_data,
366                         &client_target_info);
367
368         if (tag_discovered_func_data.callback != NULL)
369         {
370                 callback = (net_nfc_client_tag_tag_discovered)tag_discovered_func_data.callback;
371
372                 callback(client_target_info, tag_discovered_func_data.user_data);
373         }
374 }
375
376 static void tag_tag_detached(NetNfcGDbusTag *object, guint arg_handle,
377                 gint arg_dev_type, gpointer user_data)
378 {
379         NFC_INFO(">>> SIGNAL arrived");
380         net_nfc_client_tag_tag_detached callback;
381         if (tag_check_filter(arg_dev_type) == TRUE)
382         {
383                 if (tag_detached_func_data.callback != NULL)
384                 {
385                         callback = (net_nfc_client_tag_tag_detached)tag_detached_func_data.callback;
386
387                         callback(tag_detached_func_data.user_data);
388                 }
389         }
390         else
391         {
392                 NFC_INFO("The detected target is filtered out, type [%d]", arg_dev_type);
393         }
394
395         net_nfc_release_tag_info(client_target_info);
396         client_target_info = NULL;
397 }
398
399 /* internal function */
400 gboolean net_nfc_client_tag_is_connected(void)
401 {
402         return net_nfc_neard_is_tag_connected();
403 }
404
405 net_nfc_target_info_s *net_nfc_client_tag_get_client_target_info(void)
406 {
407         net_nfc_neard_get_current_tag_info(&client_target_info);
408         return client_target_info;
409 }
410
411 /* public APIs */
412 #if 0
413 API net_nfc_error_e net_nfc_client_tag_is_tag_connected(
414                 net_nfc_client_tag_is_tag_connected_completed callback, void *user_data)
415 {
416         NetNfcCallback *func_data;
417
418         RETV_IF(NULL == tag_proxy, NET_NFC_NOT_INITIALIZED);
419
420         /* prevent executing daemon when nfc is off */
421         RETV_IF(net_nfc_client_manager_is_activated() == false, NET_NFC_INVALID_STATE);
422
423         func_data = g_try_new0(NetNfcCallback, 1);
424         if (func_data == NULL)
425                 return NET_NFC_ALLOC_FAIL;
426
427         func_data->callback = (gpointer)callback;
428         func_data->user_data = user_data;
429
430         net_nfc_gdbus_tag_call_is_tag_connected(tag_proxy,
431                         net_nfc_client_gdbus_get_privilege(),
432                         NULL,
433                         tag_is_tag_connected,
434                         func_data);
435
436         return NET_NFC_OK;
437 }
438 #endif
439
440 API net_nfc_error_e net_nfc_client_tag_is_tag_connected_sync(
441                 net_nfc_target_type_e *dev_type)
442 {
443         gboolean ret;
444         GError *error = NULL;
445         net_nfc_target_info_s *info;
446         gboolean out_is_connected = FALSE;
447         net_nfc_error_e result = NET_NFC_OK;
448         net_nfc_target_type_e out_dev_type = NET_NFC_UNKNOWN_TARGET;
449
450         RETV_IF(NULL == tag_proxy, NET_NFC_NOT_INITIALIZED);
451
452         /* prevent executing daemon when nfc is off */
453         RETV_IF(net_nfc_client_manager_is_activated() == false, NET_NFC_INVALID_STATE);
454
455         info = net_nfc_client_tag_get_client_target_info();
456         if (NULL == info)
457         {
458                 /* try to request target information from server */
459                 ret = net_nfc_gdbus_tag_call_is_tag_connected_sync(tag_proxy,
460                                 net_nfc_client_gdbus_get_privilege(),
461                                 &result,
462                                 &out_is_connected,
463                                 (gint *)&out_dev_type,
464                                 NULL,
465                                 &error);
466
467                 if (FALSE == ret)
468                 {
469                         NFC_ERR("Can not get is_tag_connected result: %s", error->message);
470                         g_error_free(error);
471
472                         return NET_NFC_IPC_FAIL;
473                 }
474
475                 if (TRUE == out_is_connected)
476                 {
477                         if (dev_type)
478                                 *dev_type = out_dev_type;
479
480                         result = NET_NFC_OK;
481                 }
482                 else
483                 {
484                         result = NET_NFC_NOT_CONNECTED;
485                 }
486         }
487         else
488         {
489                 /* target was connected */
490                 if (dev_type != NULL)
491                         *dev_type = info->devType;
492
493                 result = NET_NFC_OK;
494         }
495
496         return result;
497 }
498
499 #if 0
500 API net_nfc_error_e net_nfc_client_tag_get_current_tag_info(
501                 net_nfc_client_tag_get_current_tag_info_completed callback, void *user_data)
502 {
503         NetNfcCallback *func_data;
504
505         RETV_IF(NULL == tag_proxy, NET_NFC_NOT_INITIALIZED);
506
507         /* prevent executing daemon when nfc is off */
508         RETV_IF(net_nfc_client_manager_is_activated() == false, NET_NFC_INVALID_STATE);
509
510         func_data = g_try_new0(NetNfcCallback, 1);
511         if (func_data == NULL)
512                 return NET_NFC_ALLOC_FAIL;
513
514         func_data->callback = (gpointer)callback;
515         func_data->user_data = user_data;
516
517         net_nfc_gdbus_tag_call_get_current_tag_info(tag_proxy,
518                         net_nfc_client_gdbus_get_privilege(),
519                         NULL,
520                         tag_get_current_tag_info,
521                         func_data);
522
523         return NET_NFC_OK;
524 }
525 #endif
526
527 API net_nfc_error_e net_nfc_client_tag_get_current_tag_info_sync(
528                 net_nfc_target_info_s **info)
529 {
530         /* prevent executing daemon when nfc is off */
531         RETV_IF(net_nfc_client_manager_is_activated() == false, NET_NFC_INVALID_STATE);
532
533         return net_nfc_neard_get_current_tag_info(info);
534 }
535
536 #if 0
537 API net_nfc_error_e net_nfc_client_tag_get_current_target_handle(
538                 net_nfc_client_tag_get_current_target_handle_completed callback, void *user_data)
539 {
540         NetNfcCallback *func_data;
541
542         RETV_IF(NULL == tag_proxy, NET_NFC_NOT_INITIALIZED);
543
544         /* prevent executing daemon when nfc is off */
545         RETV_IF(net_nfc_client_manager_is_activated() == false, NET_NFC_INVALID_STATE);
546
547         func_data = g_try_new0(NetNfcCallback, 1);
548         if (func_data == NULL)
549                 return NET_NFC_ALLOC_FAIL;
550
551         func_data->callback = (gpointer)callback;
552         func_data->user_data = user_data;
553
554         net_nfc_gdbus_tag_call_get_current_target_handle(tag_proxy,
555                         net_nfc_client_gdbus_get_privilege(),
556                         NULL,
557                         tag_get_current_target_handle,
558                         func_data);
559
560         return NET_NFC_OK;
561 }
562 #endif
563
564 API net_nfc_error_e net_nfc_client_tag_get_current_target_handle_sync(
565                 net_nfc_target_handle_s **handle)
566 {
567         /* prevent executing daemon when nfc is off */
568         RETV_IF(net_nfc_client_manager_is_activated() == false, NET_NFC_INVALID_STATE);
569
570         return net_nfc_neard_get_current_target_handle(handle);
571 }
572
573 API void net_nfc_client_tag_set_tag_discovered(
574                 net_nfc_client_tag_tag_discovered callback, void *user_data)
575 {
576         RET_IF(NULL == callback);
577
578         net_nfc_neard_set_tag_discovered(callback, user_data);
579 }
580
581 API void net_nfc_client_tag_unset_tag_discovered(void)
582 {
583         net_nfc_neard_unset_tag_discovered();
584 }
585
586 API void net_nfc_client_tag_set_tag_detached(
587                 net_nfc_client_tag_tag_detached callback, void *user_data)
588 {
589         RET_IF(NULL == callback);
590
591         net_nfc_neard_set_tag_detached(callback, user_data);
592 }
593
594 API void net_nfc_client_tag_unset_tag_detached(void)
595 {
596         net_nfc_neard_unset_tag_detached();
597 }
598
599 API void net_nfc_client_tag_set_filter(net_nfc_event_filter_e filter)
600 {
601         client_filter = filter;
602 }
603
604 API net_nfc_event_filter_e net_nfc_client_tag_get_filter(void)
605 {
606         return client_filter;
607 }
608
609 net_nfc_error_e net_nfc_client_tag_init(void)
610 {
611         GError *error = NULL;
612
613         if (tag_proxy)
614         {
615                 NFC_WARN("Alrady initialized");
616                 return NET_NFC_OK;
617         }
618
619         if (client_target_info)
620         {
621                 net_nfc_release_tag_info(client_target_info);
622                 client_target_info = NULL;
623         }
624
625         client_filter = NET_NFC_ALL_ENABLE;
626
627         tag_proxy = net_nfc_gdbus_tag_proxy_new_for_bus_sync(
628                         G_BUS_TYPE_SYSTEM,
629                         G_DBUS_PROXY_FLAGS_NONE,
630                         "org.tizen.NetNfcService",
631                         "/org/tizen/NetNfcService/Tag",
632                         NULL,
633                         &error);
634         if (NULL == tag_proxy)
635         {
636                 NFC_ERR("Can not create proxy : %s", error->message);
637                 g_error_free(error);
638
639                 return NET_NFC_UNKNOWN_ERROR;
640         }
641
642         g_signal_connect(tag_proxy, "tag-discovered", G_CALLBACK(tag_tag_discovered), NULL);
643         g_signal_connect(tag_proxy, "tag-detached", G_CALLBACK(tag_tag_detached), NULL);
644
645         return NET_NFC_OK;
646 }
647
648 void net_nfc_client_tag_deinit(void)
649 {
650         client_filter = NET_NFC_ALL_ENABLE;
651
652         net_nfc_release_tag_info(client_target_info);
653         client_target_info = NULL;
654
655         net_nfc_client_tag_unset_tag_discovered();
656         net_nfc_client_tag_unset_tag_detached();
657
658         if (tag_proxy)
659         {
660                 g_object_unref(tag_proxy);
661                 tag_proxy = NULL;
662         }
663 }