2 * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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"
31 typedef struct _CurrentTagInfoData CurrentTagInfoData;
33 struct _CurrentTagInfoData
36 GDBusMethodInvocation *invocation;
39 typedef struct _WatchDogData WatchDogData;
43 net_nfc_target_type_e dev_type;
44 net_nfc_target_handle_s *handle;
47 static NetNfcGDbusTag *tag_skeleton = NULL;
49 static net_nfc_current_target_info_s *current_target_info = NULL;
51 static gboolean tag_is_isp_dep_ndef_formatable(net_nfc_target_handle_s *handle,
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 };
61 info.dev_type = dev_type;
62 info.trans_data.buffer = cmd;
63 info.trans_data.length = sizeof(cmd);
65 if (net_nfc_controller_transceive(handle, &info, &response, &error) == false)
67 NFC_ERR("net_nfc_controller_transceive is failed");
74 if (response->length == 9 && response->buffer[7] == (uint8_t)0x91 &&
75 response->buffer[8] == (uint8_t)0xAF)
80 net_nfc_util_free_data(response);
85 NFC_ERR("response is NULL");
91 static gboolean tag_read_ndef_message(net_nfc_target_handle_s *handle,
92 int dev_type, data_s **read_ndef)
95 net_nfc_error_e result = NET_NFC_OK;
97 RETV_IF(NULL == handle, FALSE);
98 RETV_IF(NULL == read_ndef, FALSE);
102 if (NET_NFC_MIFARE_DESFIRE_PICC == dev_type)
104 if (tag_is_isp_dep_ndef_formatable(handle, dev_type) == FALSE)
106 NFC_ERR("DESFIRE : ISO-DEP ndef not formatable");
110 NFC_DBG("DESFIRE : ISO-DEP ndef formatable");
112 if (net_nfc_controller_connect(handle, &result) == false)
114 NFC_ERR("net_nfc_controller_connect failed & retry polling!!");
116 if (net_nfc_controller_configure_discovery(NET_NFC_DISCOVERY_MODE_RESUME,
117 NET_NFC_ALL_ENABLE, &result) == false)
119 net_nfc_controller_exception_handler();
125 if (net_nfc_controller_read_ndef(handle, &temp, &result) == false)
127 NFC_ERR("net_nfc_controller_read_ndef failed");
131 NFC_DBG("net_nfc_controller_read_ndef success");
133 if (NET_NFC_MIFARE_DESFIRE_PICC == dev_type)
135 if (net_nfc_controller_connect(handle, &result) == false)
137 NFC_ERR("net_nfc_controller_connect failed, & retry polling!!");
139 if (net_nfc_controller_configure_discovery(NET_NFC_DISCOVERY_MODE_RESUME,
140 NET_NFC_ALL_ENABLE, &result) == false)
142 net_nfc_controller_exception_handler();
147 g_free(temp->buffer);
160 static void tag_watchdog_thread_func(gpointer user_data)
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;
168 RET_IF(NULL == watch_dog);
169 RET_IF(NULL == watch_dog->handle);
171 /* IMPORTANT, TEMPORARY : switching context to another thread
175 handle = watch_dog->handle;
176 if (handle->connection_type == NET_NFC_P2P_CONNECTION_TARGET ||
177 handle->connection_type == NET_NFC_TAG_CONNECTION)
179 is_present_target = net_nfc_controller_check_target_presence(handle, &result);
182 if (true == is_present_target)
184 ret = net_nfc_server_controller_async_queue_push(tag_watchdog_thread_func,
188 NFC_ERR("can not create watch dog");
194 if (result != NET_NFC_NOT_INITIALIZED && result != NET_NFC_INVALID_HANDLE)
196 if(net_nfc_controller_disconnect(handle, &result) == false)
198 NFC_ERR("try to disconnect result = [%d]", result);
199 net_nfc_controller_exception_handler();
203 net_nfc_server_set_state(NET_NFC_SERVER_IDLE);
205 net_nfc_gdbus_tag_emit_tag_detached(tag_skeleton, GPOINTER_TO_UINT(handle),
206 watch_dog->dev_type);
211 static void tag_get_current_tag_info_thread_func(gpointer user_data)
214 /* FIXME : net_nfc_current_target_info_s should be removed */
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;
229 g_assert(info_data != NULL);
230 g_assert(info_data->tag != NULL);
231 g_assert(info_data->invocation != NULL);
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)
237 handle = target_info->handle;
238 number_of_keys = target_info->number_of_keys;
240 target_info_values.buffer = target_info->target_info_values.buffer;
241 target_info_values.length = target_info->target_info_values.length;
243 dev_type = target_info->devType ;
245 ret = net_nfc_controller_check_ndef(target_info->handle, &ndef_card_state,
246 (int *)&max_data_size, (int *)&actual_data_size, &result);
248 is_ndef_supported = TRUE;
250 if (is_ndef_supported)
252 ret = net_nfc_controller_read_ndef(target_info->handle, &raw_data, &result);
254 NFC_DBG("net_nfc_controller_read_ndef is success");
258 net_nfc_gdbus_tag_complete_get_current_tag_info(info_data->tag,
259 info_data->invocation,
261 (dev_type != NET_NFC_UNKNOWN_TARGET),
262 GPOINTER_TO_UINT(handle),
269 net_nfc_util_gdbus_data_to_variant(&target_info_values),
270 net_nfc_util_gdbus_data_to_variant(raw_data));
272 if (raw_data != NULL)
274 net_nfc_util_free_data(raw_data);
278 g_object_unref(info_data->invocation);
279 g_object_unref(info_data->tag);
284 static void tag_slave_target_detected_thread_func(gpointer user_data)
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;
298 target = net_nfc_server_get_target_info();
300 g_assert(target != NULL); /* raise exception!!! what;s wrong?? */
302 RET_IF(NULL == tag_skeleton);
304 if (net_nfc_controller_connect(target->handle, &result) == false)
306 NFC_ERR("connect failed & Retry Polling!!");
308 ret = net_nfc_controller_configure_discovery(NET_NFC_DISCOVERY_MODE_RESUME,
309 NET_NFC_ALL_ENABLE, &result);
311 net_nfc_controller_exception_handler();
316 net_nfc_server_set_state(NET_NFC_TAG_CONNECTED);
318 NFC_DBG("tag is connected");
320 target_info_values = net_nfc_util_gdbus_buffer_to_variant(
321 target->target_info_values.buffer, target->target_info_values.length);
323 ret = net_nfc_controller_check_ndef(target->handle, &ndef_card_state,
324 (int *)&max_data_size, (int *)&actual_data_size, &result);
326 is_ndef_supported = TRUE;
328 if (is_ndef_supported)
330 data_s *recv_data = NULL;
332 NFC_DBG("support NDEF");
334 if (tag_read_ndef_message(target->handle, target->devType, &recv_data) == TRUE)
336 ndef_record_s *record;
337 ndef_message_s *selector;
338 ndef_record_s *recordasperpriority;
340 result = net_nfc_server_handover_create_selector_from_rawdata(&selector,
343 if (NET_NFC_OK == result)
345 result = net_nfc_server_handover_get_carrier_record_by_priority_order(
347 isHandoverMessage = true;
348 if (NET_NFC_OK == result)
350 net_nfc_util_create_record(record->TNF, &record->type_s, &record->id_s,
351 &record->payload_s, &recordasperpriority);
353 net_nfc_server_handover_process_carrier_record(recordasperpriority,
358 NFC_ERR("_get_carrier_record_by_priority_order failed, [%d]",result);
363 net_nfc_app_util_process_ndef(recv_data);
364 raw_data = net_nfc_util_gdbus_data_to_variant(recv_data);
369 NFC_ERR("net_nfc_controller_read_ndef failed");
370 raw_data = net_nfc_util_gdbus_buffer_to_variant(NULL, 0);
375 /* raw-data of empty ndef msseages */
376 uint8_t empty[] = { 0xd0, 0x00, 0x00 };
377 data_s empty_data = { empty, sizeof(empty) };
379 NFC_DBG("not support NDEF");
381 net_nfc_app_util_process_ndef(&empty_data);
382 raw_data = net_nfc_util_gdbus_data_to_variant(&empty_data);
385 if(isHandoverMessage == false)
387 /* send TagDiscoverd signal */
388 net_nfc_gdbus_tag_emit_tag_discovered(tag_skeleton,
389 GPOINTER_TO_UINT(target->handle),
395 target->number_of_keys,
400 /* turn on watch dog */
401 NFC_DBG("turn on watch dog");
403 watch_dog = g_new0(WatchDogData, 1);
404 if(NULL == watch_dog)
406 NFC_ERR("Memory allocation failed");
410 watch_dog->dev_type = target->devType;
411 watch_dog->handle = target->handle;
413 if (net_nfc_server_controller_async_queue_push(
414 tag_watchdog_thread_func, watch_dog) == FALSE)
416 NFC_ERR("can not create watch dog");
423 static gboolean tag_handle_is_tag_connected(NetNfcGDbusTag *tag,
424 GDBusMethodInvocation *invocation, GVariant *smack_privilege, gpointer user_data)
426 /* FIXME : net_nfc_current_target_info_s should be removed */
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;
433 NFC_INFO(">>> REQUEST from [%s]", g_dbus_method_invocation_get_sender(invocation));
435 /* check privilege and update client context */
436 ret = net_nfc_server_gdbus_check_privilege(invocation, smack_privilege,
437 "nfc-manager::tag", "r");
441 NFC_ERR("permission denied, and finished request");
442 result = NET_NFC_SECURITY_FAIL;
447 target_info = net_nfc_server_get_target_info();
448 if (target_info != NULL)
450 dev_type = target_info->devType;
457 net_nfc_gdbus_tag_complete_is_tag_connected(tag, invocation, result, is_connected,
463 static gboolean tag_handle_get_current_tag_info(NetNfcGDbusTag *tag,
464 GDBusMethodInvocation *invocation, GVariant *smack_privilege, gpointer user_data)
468 CurrentTagInfoData *info_data;
470 NFC_INFO(">>> REQUEST from [%s]", g_dbus_method_invocation_get_sender(invocation));
472 /* check privilege and update client context */
473 ret = net_nfc_server_gdbus_check_privilege(invocation, smack_privilege,
474 "nfc-manager::tag", "r");
477 NFC_ERR("permission denied, and finished request");
482 info_data = g_new0(CurrentTagInfoData, 1);
483 if (NULL == info_data)
485 NFC_ERR("Memory allocation failed");
486 g_dbus_method_invocation_return_dbus_error(invocation,
487 "org.tizen.NetNfcService.AllocationError", "Can not allocate memory");
492 info_data->tag = g_object_ref(tag);
493 info_data->invocation = g_object_ref(invocation);
495 result = net_nfc_server_controller_async_queue_push(
496 tag_get_current_tag_info_thread_func, info_data);
499 g_dbus_method_invocation_return_dbus_error(invocation,
500 "org.tizen.NetNfcService.ThreadError",
501 "can not push to controller thread");
503 g_object_unref(info_data->invocation);
504 g_object_unref(info_data->tag);
512 static gboolean tag_handle_get_current_target_handle(NetNfcGDbusTag *tag,
513 GDBusMethodInvocation *invocation, GVariant *smack_privilege, gpointer user_data)
515 /* FIXME : net_nfc_current_target_info_s should be removed */
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;
522 NFC_INFO(">>> REQUEST from [%s]", g_dbus_method_invocation_get_sender(invocation));
524 /* check privilege and update client context */
525 ret = net_nfc_server_gdbus_check_privilege(invocation, smack_privilege,
526 "nfc-manager::p2p", "r");
529 NFC_ERR("permission denied, and finished request");
530 result = NET_NFC_SECURITY_FAIL;
535 target_info = net_nfc_server_get_target_info();
536 if (target_info != NULL)
538 handle = target_info->handle;
539 devType = target_info->devType;
545 net_nfc_gdbus_tag_complete_get_current_target_handle(tag, invocation, result,
546 (handle != NULL), GPOINTER_TO_UINT(handle), devType);
552 gboolean net_nfc_server_tag_init(GDBusConnection *connection)
555 GError *error = NULL;
558 net_nfc_server_tag_deinit();
560 tag_skeleton = net_nfc_gdbus_tag_skeleton_new();
562 g_signal_connect(tag_skeleton, "handle-is-tag-connected",
563 G_CALLBACK(tag_handle_is_tag_connected), NULL);
565 g_signal_connect(tag_skeleton, "handle-get-current-tag-info",
566 G_CALLBACK(tag_handle_get_current_tag_info), NULL);
568 g_signal_connect(tag_skeleton, "handle-get-current-target-handle",
569 G_CALLBACK(tag_handle_get_current_target_handle), NULL);
571 result = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(tag_skeleton),
572 connection, "/org/tizen/NetNfcService/Tag", &error);
575 NFC_ERR("can not skeleton_export %s", error->message);
579 net_nfc_server_tag_deinit();
585 void net_nfc_server_tag_deinit(void)
589 g_object_unref(tag_skeleton);
594 void net_nfc_server_set_target_info(void *info)
596 net_nfc_request_target_detected_t *target;
598 if (current_target_info)
599 g_free(current_target_info);
601 target = (net_nfc_request_target_detected_t *)info;
603 current_target_info = g_malloc0(sizeof(net_nfc_current_target_info_s) +
604 target->target_info_values.length);
606 current_target_info->handle = target->handle;
607 current_target_info->devType = target->devType;
609 if (current_target_info->devType != NET_NFC_NFCIP1_INITIATOR &&
610 current_target_info->devType != NET_NFC_NFCIP1_TARGET)
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;
616 memcpy(¤t_target_info->target_info_values,
617 &target->target_info_values,
618 current_target_info->target_info_values.length);
622 net_nfc_current_target_info_s *net_nfc_server_get_target_info(void)
624 return current_target_info;
627 gboolean net_nfc_server_target_connected(net_nfc_target_handle_s *handle)
629 if (NULL == current_target_info)
632 if (current_target_info->handle != handle)
638 void net_nfc_server_free_target_info(void)
640 g_free(current_target_info);
641 current_target_info = NULL;
644 void net_nfc_server_tag_target_detected(void *info)
648 ret = net_nfc_server_controller_async_queue_push(
649 tag_slave_target_detected_thread_func, NULL);
652 NFC_ERR("can not push to controller thread");