Remove unnecessary setting
[platform/core/connectivity/nfc-manager-neard.git] / daemon / net_nfc_server_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
17
18 #include "net_nfc_debug_internal.h"
19 #include "net_nfc_util_internal.h"
20 #include "net_nfc_util_gdbus_internal.h"
21 #include "net_nfc_gdbus.h"
22 #include "net_nfc_server_controller.h"
23 #include "net_nfc_server_common.h"
24 #include "net_nfc_server_context.h"
25 #include "net_nfc_server_util.h"
26 #include "net_nfc_server_p2p.h"
27 #include "net_nfc_server_process_handover.h"
28 #include "net_nfc_util_ndef_record.h"
29 #include "net_nfc_server_tag.h"
30
31 typedef struct _CurrentTagInfoData CurrentTagInfoData;
32
33 struct _CurrentTagInfoData
34 {
35         NetNfcGDbusTag *tag;
36         GDBusMethodInvocation *invocation;
37 };
38
39 typedef struct _WatchDogData WatchDogData;
40
41 struct _WatchDogData
42 {
43         net_nfc_target_type_e dev_type;
44         net_nfc_target_handle_s *handle;
45 };
46
47 static NetNfcGDbusTag *tag_skeleton = NULL;
48
49 static net_nfc_current_target_info_s *current_target_info = NULL;
50
51 static gboolean tag_is_isp_dep_ndef_formatable(net_nfc_target_handle_s *handle,
52                 int dev_type)
53 {
54
55         gboolean result = false;
56         data_s *response = NULL;
57         net_nfc_transceive_info_s info;
58         net_nfc_error_e error = NET_NFC_OK;
59         uint8_t cmd[] = { 0x90, 0x60, 0x00, 0x00, 0x00 };
60
61         info.dev_type = dev_type;
62         info.trans_data.buffer = cmd;
63         info.trans_data.length = sizeof(cmd);
64
65         if (net_nfc_controller_transceive(handle, &info, &response, &error) == false)
66         {
67                 NFC_ERR("net_nfc_controller_transceive is failed");
68
69                 return result;
70         }
71
72         if (response != NULL)
73         {
74                 if (response->length == 9 && response->buffer[7] == (uint8_t)0x91 &&
75                                 response->buffer[8] == (uint8_t)0xAF)
76                 {
77                         result =  TRUE;
78                 }
79
80                 net_nfc_util_free_data(response);
81                 g_free(response);
82         }
83         else
84         {
85                 NFC_ERR("response is NULL");
86         }
87
88         return result;
89 }
90
91 static gboolean tag_read_ndef_message(net_nfc_target_handle_s *handle,
92                 int dev_type, data_s **read_ndef)
93 {
94         data_s *temp = NULL;
95         net_nfc_error_e result = NET_NFC_OK;
96
97         RETV_IF(NULL == handle, FALSE);
98         RETV_IF(NULL == read_ndef, FALSE);
99
100         *read_ndef = NULL;
101
102         if (NET_NFC_MIFARE_DESFIRE_PICC == dev_type)
103         {
104                 if (tag_is_isp_dep_ndef_formatable(handle, dev_type) == FALSE)
105                 {
106                         NFC_ERR("DESFIRE : ISO-DEP ndef not formatable");
107                         return FALSE;
108                 }
109
110                 NFC_DBG("DESFIRE : ISO-DEP ndef formatable");
111
112                 if (net_nfc_controller_connect(handle, &result) == false)
113                 {
114                         NFC_ERR("net_nfc_controller_connect failed & retry polling!!");
115
116                         if (net_nfc_controller_configure_discovery(NET_NFC_DISCOVERY_MODE_RESUME,
117                                                 NET_NFC_ALL_ENABLE, &result) == false)
118                         {
119                                 net_nfc_controller_exception_handler();
120                         }
121                         return FALSE;
122                 }
123         }
124
125         if (net_nfc_controller_read_ndef(handle, &temp, &result) == false)
126         {
127                 NFC_ERR("net_nfc_controller_read_ndef failed");
128                 return FALSE;
129         }
130
131         NFC_DBG("net_nfc_controller_read_ndef success");
132
133         if (NET_NFC_MIFARE_DESFIRE_PICC == dev_type)
134         {
135                 if (net_nfc_controller_connect(handle, &result) == false)
136                 {
137                         NFC_ERR("net_nfc_controller_connect failed, & retry polling!!");
138
139                         if (net_nfc_controller_configure_discovery(NET_NFC_DISCOVERY_MODE_RESUME,
140                                                 NET_NFC_ALL_ENABLE, &result) == false)
141                         {
142                                 net_nfc_controller_exception_handler();
143                         }
144
145                         if (temp)
146                         {
147                                 g_free(temp->buffer);
148                                 g_free(temp);
149                         }
150
151                         return FALSE;
152                 }
153         }
154
155         *read_ndef = temp;
156
157         return TRUE;
158 }
159
160 static void tag_watchdog_thread_func(gpointer user_data)
161 {
162         gboolean ret;
163         net_nfc_target_handle_s *handle;
164         bool is_present_target = false;
165         net_nfc_error_e result = NET_NFC_OK;
166         WatchDogData *watch_dog = user_data;
167
168         RET_IF(NULL == watch_dog);
169         RET_IF(NULL == watch_dog->handle);
170
171         /* IMPORTANT, TEMPORARY : switching context to another thread
172            for give CPU time */
173         g_usleep(10000);
174
175         handle = watch_dog->handle;
176         if (handle->connection_type == NET_NFC_P2P_CONNECTION_TARGET ||
177                         handle->connection_type == NET_NFC_TAG_CONNECTION)
178         {
179                 is_present_target = net_nfc_controller_check_target_presence(handle, &result);
180         }
181
182         if (true == is_present_target)
183         {
184                 ret = net_nfc_server_controller_async_queue_push(tag_watchdog_thread_func,
185                                         watch_dog);
186                 if(FALSE == ret)
187                 {
188                         NFC_ERR("can not create watch dog");
189                         g_free(watch_dog);
190                 }
191                 return;
192         }
193
194         if (result != NET_NFC_NOT_INITIALIZED && result != NET_NFC_INVALID_HANDLE)
195         {
196                 if(net_nfc_controller_disconnect(handle, &result) == false)
197                 {
198                         NFC_ERR("try to disconnect result = [%d]", result);
199                         net_nfc_controller_exception_handler();
200                 }
201         }
202
203         net_nfc_server_set_state(NET_NFC_SERVER_IDLE);
204
205         net_nfc_gdbus_tag_emit_tag_detached(tag_skeleton, GPOINTER_TO_UINT(handle),
206                         watch_dog->dev_type);
207
208         g_free(watch_dog);
209 }
210
211 static void tag_get_current_tag_info_thread_func(gpointer user_data)
212 {
213
214         /* FIXME : net_nfc_current_target_info_s should be removed */
215         bool ret;
216         data_s *raw_data = NULL;
217         gint number_of_keys = 0;
218         guint32 max_data_size = 0;
219         guint8 ndef_card_state = 0;
220         guint32 actual_data_size = 0;
221         gboolean is_ndef_supported = FALSE;
222         net_nfc_target_handle_s *handle = NULL;
223         data_s target_info_values = { NULL, 0 };
224         CurrentTagInfoData *info_data = user_data;
225         net_nfc_current_target_info_s *target_info;
226         net_nfc_error_e result = NET_NFC_OPERATION_FAIL;
227         net_nfc_target_type_e dev_type = NET_NFC_UNKNOWN_TARGET;
228
229         g_assert(info_data != NULL);
230         g_assert(info_data->tag != NULL);
231         g_assert(info_data->invocation != NULL);
232
233         target_info = net_nfc_server_get_target_info();
234         if (target_info != NULL && target_info->devType != NET_NFC_NFCIP1_TARGET &&
235                         target_info->devType != NET_NFC_NFCIP1_INITIATOR)
236         {
237                 handle = target_info->handle;
238                 number_of_keys = target_info->number_of_keys;
239
240                 target_info_values.buffer = target_info->target_info_values.buffer;
241                 target_info_values.length = target_info->target_info_values.length;
242
243                 dev_type = target_info->devType ;
244
245                 ret = net_nfc_controller_check_ndef(target_info->handle, &ndef_card_state,
246                                         (int *)&max_data_size, (int *)&actual_data_size, &result);
247                 if (true == ret)
248                         is_ndef_supported = TRUE;
249
250                 if (is_ndef_supported)
251                 {
252                         ret = net_nfc_controller_read_ndef(target_info->handle, &raw_data, &result);
253                         if (true == ret)
254                                 NFC_DBG("net_nfc_controller_read_ndef is success");
255                 }
256         }
257
258         net_nfc_gdbus_tag_complete_get_current_tag_info(info_data->tag,
259                         info_data->invocation,
260                         result,
261                         (dev_type != NET_NFC_UNKNOWN_TARGET),
262                         GPOINTER_TO_UINT(handle),
263                         dev_type,
264                         is_ndef_supported,
265                         ndef_card_state,
266                         max_data_size,
267                         actual_data_size,
268                         number_of_keys,
269                         net_nfc_util_gdbus_data_to_variant(&target_info_values),
270                         net_nfc_util_gdbus_data_to_variant(raw_data));
271
272         if (raw_data != NULL)
273         {
274                 net_nfc_util_free_data(raw_data);
275                 g_free(raw_data);
276         }
277
278         g_object_unref(info_data->invocation);
279         g_object_unref(info_data->tag);
280
281         g_free(info_data);
282 }
283
284 static void tag_slave_target_detected_thread_func(gpointer user_data)
285 {
286         bool ret;
287         GVariant *raw_data = NULL;
288         guint32 max_data_size = 0;
289         guint8 ndef_card_state = 0;
290         guint32 actual_data_size = 0;
291         WatchDogData *watch_dog = NULL;
292         bool isHandoverMessage = false;
293         net_nfc_error_e result = NET_NFC_OK;
294         gboolean is_ndef_supported = FALSE;
295         net_nfc_current_target_info_s *target;
296         GVariant *target_info_values = NULL;
297
298         target = net_nfc_server_get_target_info();
299
300         g_assert(target != NULL); /* raise exception!!! what;s wrong?? */
301
302         RET_IF(NULL == tag_skeleton);
303
304         if (net_nfc_controller_connect(target->handle, &result) == false)
305         {
306                 NFC_ERR("connect failed & Retry Polling!!");
307
308                 ret = net_nfc_controller_configure_discovery(NET_NFC_DISCOVERY_MODE_RESUME,
309                                         NET_NFC_ALL_ENABLE, &result);
310                 if (false == ret)
311                         net_nfc_controller_exception_handler();
312
313                 return;
314         }
315
316         net_nfc_server_set_state(NET_NFC_TAG_CONNECTED);
317
318         NFC_DBG("tag is connected");
319
320         target_info_values = net_nfc_util_gdbus_buffer_to_variant(
321                         target->target_info_values.buffer, target->target_info_values.length);
322
323         ret = net_nfc_controller_check_ndef(target->handle, &ndef_card_state,
324                                 (int *)&max_data_size, (int *)&actual_data_size, &result);
325         if (true == ret)
326                 is_ndef_supported = TRUE;
327
328         if (is_ndef_supported)
329         {
330                 data_s *recv_data = NULL;
331
332                 NFC_DBG("support NDEF");
333
334                 if (tag_read_ndef_message(target->handle, target->devType, &recv_data) == TRUE)
335                 {
336                         ndef_record_s *record;
337                         ndef_message_s *selector;
338                         ndef_record_s *recordasperpriority;
339
340                         result = net_nfc_server_handover_create_selector_from_rawdata(&selector,
341                                         recv_data);
342
343                         if (NET_NFC_OK == result)
344                         {
345                                 result = net_nfc_server_handover_get_carrier_record_by_priority_order(
346                                                         selector, &record);
347                                 isHandoverMessage = true;
348                                 if (NET_NFC_OK == result)
349                                 {
350                                         net_nfc_util_create_record(record->TNF, &record->type_s, &record->id_s,
351                                                         &record->payload_s, &recordasperpriority);
352
353                                         net_nfc_server_handover_process_carrier_record(recordasperpriority,
354                                                         NULL, NULL);
355                                 }
356                                 else
357                                 {
358                                         NFC_ERR("_get_carrier_record_by_priority_order failed, [%d]",result);
359                                 }
360                         }
361                         else
362                         {
363                                 net_nfc_app_util_process_ndef(recv_data);
364                                 raw_data = net_nfc_util_gdbus_data_to_variant(recv_data);
365                         }
366                 }
367                 else
368                 {
369                         NFC_ERR("net_nfc_controller_read_ndef failed");
370                         raw_data = net_nfc_util_gdbus_buffer_to_variant(NULL, 0);
371                 }
372         }
373         else
374         {
375                 /* raw-data of empty ndef msseages */
376                 uint8_t empty[] = { 0xd0, 0x00, 0x00 };
377                 data_s empty_data = { empty, sizeof(empty) };
378
379                 NFC_DBG("not support NDEF");
380
381                 net_nfc_app_util_process_ndef(&empty_data);
382                 raw_data = net_nfc_util_gdbus_data_to_variant(&empty_data);
383         }
384
385         if(isHandoverMessage == false)
386         {
387                 /* send TagDiscoverd signal */
388                 net_nfc_gdbus_tag_emit_tag_discovered(tag_skeleton,
389                                 GPOINTER_TO_UINT(target->handle),
390                                 target->devType,
391                                 is_ndef_supported,
392                                 ndef_card_state,
393                                 max_data_size,
394                                 actual_data_size,
395                                 target->number_of_keys,
396                                 target_info_values,
397                                 raw_data);
398         }
399
400         /* turn on watch dog */
401         NFC_DBG("turn on watch dog");
402
403         watch_dog = g_new0(WatchDogData, 1);
404         if(NULL == watch_dog)
405         {
406                 NFC_ERR("Memory allocation failed");
407                 return;
408         }
409
410         watch_dog->dev_type = target->devType;
411         watch_dog->handle = target->handle;
412
413         if (net_nfc_server_controller_async_queue_push(
414                                 tag_watchdog_thread_func, watch_dog) == FALSE)
415         {
416                 NFC_ERR("can not create watch dog");
417                 g_free(watch_dog);
418                 return;
419         }
420 }
421
422
423 static gboolean tag_handle_is_tag_connected(NetNfcGDbusTag *tag,
424                 GDBusMethodInvocation *invocation, GVariant *smack_privilege, gpointer user_data)
425 {
426         /* FIXME : net_nfc_current_target_info_s should be removed */
427         bool ret;
428         gint result;
429         gboolean is_connected = FALSE;
430         net_nfc_current_target_info_s *target_info;
431         net_nfc_target_type_e dev_type = NET_NFC_UNKNOWN_TARGET;
432
433         NFC_INFO(">>> REQUEST from [%s]", g_dbus_method_invocation_get_sender(invocation));
434
435         /* check privilege and update client context */
436         ret = net_nfc_server_gdbus_check_privilege(invocation, smack_privilege,
437                                 "nfc-manager::tag", "r");
438
439         if (false == ret)
440         {
441                 NFC_ERR("permission denied, and finished request");
442                 result = NET_NFC_SECURITY_FAIL;
443
444                 goto END;
445         }
446
447         target_info = net_nfc_server_get_target_info();
448         if (target_info != NULL)
449         {
450                 dev_type = target_info->devType;
451                 is_connected = TRUE;
452         }
453
454         result = NET_NFC_OK;
455
456 END :
457         net_nfc_gdbus_tag_complete_is_tag_connected(tag, invocation, result, is_connected,
458                         (gint32)dev_type);
459
460         return TRUE;
461 }
462
463 static gboolean tag_handle_get_current_tag_info(NetNfcGDbusTag *tag,
464                 GDBusMethodInvocation *invocation, GVariant *smack_privilege, gpointer user_data)
465 {
466         bool ret;
467         gboolean result;
468         CurrentTagInfoData *info_data;
469
470         NFC_INFO(">>> REQUEST from [%s]", g_dbus_method_invocation_get_sender(invocation));
471
472         /* check privilege and update client context */
473         ret = net_nfc_server_gdbus_check_privilege(invocation, smack_privilege,
474                                 "nfc-manager::tag", "r");
475         if (false == ret)
476         {
477                 NFC_ERR("permission denied, and finished request");
478
479                 return FALSE;
480         }
481
482         info_data = g_new0(CurrentTagInfoData, 1);
483         if (NULL == info_data)
484         {
485                 NFC_ERR("Memory allocation failed");
486                 g_dbus_method_invocation_return_dbus_error(invocation,
487                                 "org.tizen.NetNfcService.AllocationError", "Can not allocate memory");
488
489                 return FALSE;
490         }
491
492         info_data->tag = g_object_ref(tag);
493         info_data->invocation = g_object_ref(invocation);
494
495         result = net_nfc_server_controller_async_queue_push(
496                         tag_get_current_tag_info_thread_func, info_data);
497         if (FALSE == result)
498         {
499                 g_dbus_method_invocation_return_dbus_error(invocation,
500                                 "org.tizen.NetNfcService.ThreadError",
501                                 "can not push to controller thread");
502
503                 g_object_unref(info_data->invocation);
504                 g_object_unref(info_data->tag);
505
506                 g_free(info_data);
507         }
508
509         return result;
510 }
511
512 static gboolean tag_handle_get_current_target_handle(NetNfcGDbusTag *tag,
513                 GDBusMethodInvocation *invocation, GVariant *smack_privilege, gpointer user_data)
514 {
515         /* FIXME : net_nfc_current_target_info_s should be removed */
516         gint result;
517         gboolean ret;
518         net_nfc_target_handle_s *handle = NULL;
519         uint32_t devType = NET_NFC_UNKNOWN_TARGET;
520         net_nfc_current_target_info_s *target_info;
521
522         NFC_INFO(">>> REQUEST from [%s]", g_dbus_method_invocation_get_sender(invocation));
523
524         /* check privilege and update client context */
525         ret = net_nfc_server_gdbus_check_privilege(invocation, smack_privilege,
526                                 "nfc-manager::p2p", "r");
527         if (false == ret)
528         {
529                 NFC_ERR("permission denied, and finished request");
530                 result = NET_NFC_SECURITY_FAIL;
531
532                 goto END;
533         }
534
535         target_info = net_nfc_server_get_target_info();
536         if (target_info != NULL)
537         {
538                 handle = target_info->handle;
539                 devType = target_info->devType;
540         }
541
542         result = NET_NFC_OK;
543
544 END :
545         net_nfc_gdbus_tag_complete_get_current_target_handle(tag, invocation, result,
546                         (handle != NULL), GPOINTER_TO_UINT(handle), devType);
547
548         return TRUE;
549 }
550
551
552 gboolean net_nfc_server_tag_init(GDBusConnection *connection)
553 {
554         gboolean result;
555         GError *error = NULL;
556
557         if (tag_skeleton)
558                 net_nfc_server_tag_deinit();
559
560         tag_skeleton = net_nfc_gdbus_tag_skeleton_new();
561
562         g_signal_connect(tag_skeleton, "handle-is-tag-connected",
563                         G_CALLBACK(tag_handle_is_tag_connected), NULL);
564
565         g_signal_connect(tag_skeleton, "handle-get-current-tag-info",
566                         G_CALLBACK(tag_handle_get_current_tag_info), NULL);
567
568         g_signal_connect(tag_skeleton, "handle-get-current-target-handle",
569                         G_CALLBACK(tag_handle_get_current_target_handle), NULL);
570
571         result = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(tag_skeleton),
572                         connection, "/org/tizen/NetNfcService/Tag", &error);
573         if (FALSE == result)
574         {
575                 NFC_ERR("can not skeleton_export %s", error->message);
576
577                 g_error_free(error);
578
579                 net_nfc_server_tag_deinit();
580         }
581
582         return result;
583 }
584
585 void net_nfc_server_tag_deinit(void)
586 {
587         if (tag_skeleton)
588         {
589                 g_object_unref(tag_skeleton);
590                 tag_skeleton = NULL;
591         }
592 }
593
594 void net_nfc_server_set_target_info(void *info)
595 {
596         net_nfc_request_target_detected_t *target;
597
598         if (current_target_info)
599                 g_free(current_target_info);
600
601         target = (net_nfc_request_target_detected_t *)info;
602
603         current_target_info = g_malloc0(sizeof(net_nfc_current_target_info_s) +
604                         target->target_info_values.length);
605
606         current_target_info->handle = target->handle;
607         current_target_info->devType = target->devType;
608
609         if (current_target_info->devType != NET_NFC_NFCIP1_INITIATOR &&
610                         current_target_info->devType != NET_NFC_NFCIP1_TARGET)
611         {
612                 current_target_info->number_of_keys = target->number_of_keys;
613                 current_target_info->target_info_values.length =
614                         target->target_info_values.length;
615
616                 memcpy(&current_target_info->target_info_values,
617                                 &target->target_info_values,
618                                 current_target_info->target_info_values.length);
619         }
620 }
621
622 net_nfc_current_target_info_s *net_nfc_server_get_target_info(void)
623 {
624         return current_target_info;
625 }
626
627 gboolean net_nfc_server_target_connected(net_nfc_target_handle_s *handle)
628 {
629         if (NULL == current_target_info)
630                 return FALSE;
631
632         if (current_target_info->handle != handle)
633                 return FALSE;
634
635         return TRUE;
636 }
637
638 void net_nfc_server_free_target_info(void)
639 {
640         g_free(current_target_info);
641         current_target_info = NULL;
642 }
643
644 void net_nfc_server_tag_target_detected(void *info)
645 {
646         gboolean ret;
647
648         ret = net_nfc_server_controller_async_queue_push(
649                                 tag_slave_target_detected_thread_func, NULL);
650
651         if (FALSE == ret)
652                 NFC_ERR("can not push to controller thread");
653 }