Get the latest NFC state from neard
[platform/core/connectivity/nfc-manager-neard.git] / daemon / net_nfc_server_se.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 #include <vconf.h>
17 #include <tapi_common.h>
18 #include <ITapiSim.h>
19
20 #include "net_nfc_typedef_internal.h"
21 #include "net_nfc_debug_internal.h"
22 #include "net_nfc_util_internal.h"
23 #include "net_nfc_util_gdbus_internal.h"
24 #include "net_nfc_gdbus.h"
25 #include "net_nfc_server_common.h"
26 #include "net_nfc_server_context.h"
27 #include "net_nfc_server_manager.h"
28 #include "net_nfc_server_controller.h"
29 #include "net_nfc_server_util.h"
30 #include "net_nfc_server_se.h"
31
32 enum
33 {
34         SE_UICC_UNAVAILABLE = -1,
35         SE_UICC_ON_PROGRESS = 0,
36         SE_UICC_READY = 1,
37 };
38
39 typedef struct _nfc_se_setting_t
40 {
41         bool busy;
42         uint8_t type;
43         uint8_t return_type;
44         uint8_t mode;
45 }
46 net_nfc_server_se_setting_t;
47
48
49 static NetNfcGDbusSecureElement *se_skeleton = NULL;
50 #if 0
51 static uint8_t gdbus_se_prev_type = SECURE_ELEMENT_TYPE_INVALID;
52 static uint8_t gdbus_se_prev_mode = SECURE_ELEMENT_OFF_MODE;
53 #endif
54 static net_nfc_server_se_setting_t gdbus_se_setting;
55
56 /* TODO : make a list for handles */
57 static TapiHandle *gdbus_uicc_handle;
58 static net_nfc_target_handle_s *gdbus_ese_handle;
59
60 static int gdbus_uicc_ready;
61
62 /* server_side */
63 typedef struct _ServerSeData ServerSeData;
64
65 struct _ServerSeData
66 {
67         data_s aid;
68         data_s param;
69         guint event;
70 };
71
72 typedef struct _SeSetCardEmul SeSetCardEmul;
73
74 struct _SeSetCardEmul
75 {
76         NetNfcGDbusSecureElement *object;
77         GDBusMethodInvocation *invocation;
78         gint mode;
79 };
80
81 typedef struct _SeDataSeType SeDataSeType;
82
83 struct _SeDataSeType
84 {
85         NetNfcGDbusSecureElement *object;
86         GDBusMethodInvocation *invocation;
87         gint se_type;
88 };
89
90
91 typedef struct _SeDataHandle SeDataHandle;
92
93 struct _SeDataHandle
94 {
95         NetNfcGDbusSecureElement *object;
96         GDBusMethodInvocation *invocation;
97         net_nfc_target_handle_s *handle;
98 };
99
100 typedef struct _SeDataApdu SeDataApdu;
101
102 struct _SeDataApdu
103 {
104         NetNfcGDbusSecureElement *object;
105         GDBusMethodInvocation *invocation;
106         net_nfc_target_handle_s *handle;
107         GVariant *data;
108 };
109
110 typedef struct _ChangeCardEmulMode ChangeCardEmulMode;
111
112 struct _ChangeCardEmulMode
113 {
114         NetNfcGDbusSecureElement *object;
115         GDBusMethodInvocation *invocation;
116         gint mode;
117 };
118
119 uint8_t net_nfc_server_se_get_se_type()
120 {
121         return gdbus_se_setting.type;
122 }
123
124 uint8_t net_nfc_server_se_get_return_se_mode()
125 {
126         return gdbus_se_setting.return_type;
127 }
128
129 uint8_t net_nfc_server_se_get_se_mode()
130 {
131         return gdbus_se_setting.mode;
132 }
133
134 static void net_nfc_server_se_set_se_type(uint8_t type)
135 {
136         gdbus_se_setting.return_type = gdbus_se_setting.type;
137         gdbus_se_setting.type = type;
138 }
139
140 static void net_nfc_server_se_set_se_mode(uint8_t mode)
141 {
142         gdbus_se_setting.mode = mode;
143 }
144
145
146 /* eSE functions */
147 static bool net_nfc_server_se_is_ese_handle(net_nfc_target_handle_s *handle)
148 {
149         return (gdbus_ese_handle != NULL && gdbus_ese_handle == handle);
150 }
151
152 static void net_nfc_server_se_set_current_ese_handle(
153                 net_nfc_target_handle_s *handle)
154 {
155         gdbus_ese_handle = handle;
156 }
157
158 static net_nfc_target_handle_s *net_nfc_server_se_open_ese()
159 {
160         bool ret;
161
162         if (NULL == gdbus_ese_handle)
163         {
164                 net_nfc_error_e result = NET_NFC_OK;
165                 net_nfc_target_handle_s *handle = NULL;
166
167                 ret = net_nfc_controller_secure_element_open(SECURE_ELEMENT_TYPE_ESE,
168                                         &handle, &result);
169                 if (true == ret)
170                 {
171                         net_nfc_server_se_set_current_ese_handle(handle);
172
173                         NFC_DBG("handle [%p]", handle);
174                 }
175                 else
176                 {
177                         NFC_ERR("net_nfc_controller_secure_element_open failed [%d]", result);
178                 }
179         }
180
181         return gdbus_ese_handle;
182 }
183
184 static net_nfc_error_e net_nfc_server_se_close_ese()
185 {
186         net_nfc_error_e result = NET_NFC_OK;
187
188         if (gdbus_ese_handle != NULL && net_nfc_server_gdbus_is_server_busy() == false)
189         {
190                 if (net_nfc_controller_secure_element_close(gdbus_ese_handle, &result) == false)
191                         net_nfc_controller_exception_handler();
192
193                 net_nfc_server_se_set_current_ese_handle(NULL);
194          }
195
196         return result;
197 }
198
199 static void _se_uicc_enable_card_emulation()
200 {
201         net_nfc_error_e result;
202
203         /*turn off ESE*/
204         net_nfc_controller_set_secure_element_mode(SECURE_ELEMENT_TYPE_ESE,
205                         SECURE_ELEMENT_OFF_MODE, &result);
206
207         /*turn on UICC*/
208         net_nfc_controller_set_secure_element_mode(SECURE_ELEMENT_TYPE_UICC,
209                         SECURE_ELEMENT_VIRTUAL_MODE, &result);
210
211         if (NET_NFC_OK == result)
212         {
213                 NFC_INFO("card emulation changed to SECURE_ELEMENT_TYPE_UICC");
214
215                 net_nfc_server_se_set_se_type(SECURE_ELEMENT_TYPE_UICC);
216                 net_nfc_server_se_set_se_mode(SECURE_ELEMENT_VIRTUAL_MODE);
217
218                 if (vconf_set_int(VCONFKEY_NFC_SE_TYPE, VCONFKEY_NFC_SE_TYPE_UICC) < 0)
219                         NFC_ERR("vconf_set_int failed");
220         }
221         else
222         {
223                 NFC_ERR("net_nfc_controller_set_secure_element_mode failed, [%d]", result);
224         }
225 }
226
227 static void _se_uicc_prepare(void)
228 {
229         char **cpList;
230
231         cpList = tel_get_cp_name_list();
232         if (cpList != NULL)
233         {
234                 gdbus_uicc_handle = tel_init(cpList[0]);
235                 if (NULL == gdbus_uicc_handle)
236                         NFC_ERR("tel_init() failed");
237
238         }
239         else
240         {
241                 NFC_ERR("tel_get_cp_name_list() failed");
242         }
243 }
244
245 static void _se_uicc_status_noti_cb(TapiHandle *handle,
246                 const char *noti_id, void *data, void *user_data)
247 {
248         TelSimCardStatus_t *status = data;
249
250         NFC_DBG("_se_uicc_status_noti_cb");
251
252         switch (*status)
253         {
254         case TAPI_SIM_STATUS_SIM_INIT_COMPLETED :
255                 gdbus_uicc_ready = SE_UICC_READY;
256
257                 _se_uicc_prepare();
258
259                 if (gdbus_se_setting.busy == true &&
260                                 net_nfc_server_se_get_se_type() == SECURE_ELEMENT_TYPE_UICC)
261                 {
262                         gdbus_se_setting.busy = false;
263
264                         _se_uicc_enable_card_emulation();
265                 }
266                 break;
267
268         case TAPI_SIM_STATUS_CARD_REMOVED :
269                 NFC_DBG("TAPI_SIM_STATUS_CARD_REMOVED");
270                 gdbus_uicc_ready = SE_UICC_UNAVAILABLE;
271
272                 if (net_nfc_server_se_get_se_type() == SECURE_ELEMENT_TYPE_UICC)
273                 {
274                         net_nfc_error_e result;
275
276                         /*turn off UICC*/
277                         net_nfc_controller_set_secure_element_mode(SECURE_ELEMENT_TYPE_UICC,
278                                         SECURE_ELEMENT_OFF_MODE, &result);
279
280                         net_nfc_server_se_set_se_type(SECURE_ELEMENT_TYPE_INVALID);
281                         net_nfc_server_se_set_se_mode(SECURE_ELEMENT_OFF_MODE);
282                 }
283                 break;
284
285         default:
286                 break;
287         }
288 }
289
290 static void _se_uicc_init(void)
291 {
292         _se_uicc_prepare();
293         tel_register_noti_event(gdbus_uicc_handle, TAPI_NOTI_SIM_STATUS,
294                         _se_uicc_status_noti_cb, NULL);
295 }
296
297 static void _se_uicc_deinit()
298 {
299         if (gdbus_uicc_handle != NULL)
300         {
301                 tel_deregister_noti_event(gdbus_uicc_handle, TAPI_NOTI_SIM_STATUS);
302
303                 tel_deinit(gdbus_uicc_handle);
304
305                 gdbus_uicc_handle = NULL;
306         }
307 }
308
309 static net_nfc_target_handle_s* _se_uicc_open()
310 {
311         net_nfc_target_handle_s *result = NULL;
312
313         if (gdbus_uicc_ready == SE_UICC_READY && gdbus_uicc_handle != NULL)
314                 result = (net_nfc_target_handle_s *)gdbus_uicc_handle;
315
316         return result;
317 }
318
319 static bool _se_is_uicc_handle(net_nfc_target_handle_s *handle)
320 {
321         return (gdbus_uicc_ready == SE_UICC_READY && gdbus_uicc_handle != NULL &&
322                         (TapiHandle *)handle == gdbus_uicc_handle);
323 }
324
325 static void _se_uicc_close(net_nfc_target_handle_s *handle)
326 {
327 }
328
329 /* SE Functions */
330 net_nfc_error_e net_nfc_server_se_disable_card_emulation()
331 {
332         net_nfc_error_e result;
333
334         net_nfc_server_se_set_se_type(SECURE_ELEMENT_TYPE_INVALID);
335         net_nfc_server_se_set_se_mode(SECURE_ELEMENT_OFF_MODE);
336
337         /*turn off ESE*/
338         net_nfc_controller_set_secure_element_mode(SECURE_ELEMENT_TYPE_ESE,
339                         SECURE_ELEMENT_OFF_MODE, &result);
340
341         /*turn off UICC*/
342         net_nfc_controller_set_secure_element_mode(SECURE_ELEMENT_TYPE_UICC,
343                         SECURE_ELEMENT_OFF_MODE, &result);
344
345         return NET_NFC_OK;
346 }
347
348 net_nfc_error_e net_nfc_server_se_change_se(uint8_t type)
349 {
350         net_nfc_error_e result = NET_NFC_OK;
351
352         switch (type)
353         {
354         case SECURE_ELEMENT_TYPE_UICC :
355                 if (false == gdbus_se_setting.busy)
356                 {
357                         if (SE_UICC_READY == gdbus_uicc_ready)
358                         {
359                                 _se_uicc_enable_card_emulation();
360                         }
361                         else if (SE_UICC_ON_PROGRESS == gdbus_uicc_ready)
362                         {
363                                 NFC_INFO("waiting for uicc initializing complete...");
364
365                                 net_nfc_server_se_set_se_type(SECURE_ELEMENT_TYPE_UICC);
366                                 net_nfc_server_se_set_se_mode(SECURE_ELEMENT_VIRTUAL_MODE);
367
368                                 gdbus_se_setting.busy = true;
369                         }
370                         else
371                         {
372                                 result = NET_NFC_NOT_SUPPORTED;
373                         }
374                 }
375                 else
376                 {
377                         NFC_DBG("Previous request is processing.");
378
379                         result = NET_NFC_BUSY;
380                 }
381                 break;
382
383         case SECURE_ELEMENT_TYPE_ESE :
384                 /*turn off UICC*/
385                 net_nfc_controller_set_secure_element_mode(SECURE_ELEMENT_TYPE_UICC,
386                                 SECURE_ELEMENT_OFF_MODE, &result);
387
388                 /*turn on ESE*/
389                 net_nfc_controller_set_secure_element_mode(SECURE_ELEMENT_TYPE_ESE,
390                                 SECURE_ELEMENT_VIRTUAL_MODE, &result);
391
392                 if (NET_NFC_OK == result)
393                 {
394                         NFC_INFO("card emulation changed to SECURE_ELEMENT_TYPE_ESE");
395
396                         net_nfc_server_se_set_se_type(SECURE_ELEMENT_TYPE_ESE);
397                         net_nfc_server_se_set_se_mode(SECURE_ELEMENT_VIRTUAL_MODE);
398
399                         if (vconf_set_int(VCONFKEY_NFC_SE_TYPE, VCONFKEY_NFC_SE_TYPE_ESE) != 0)
400                                 NFC_ERR("vconf_set_int failed");
401                 }
402                 else
403                 {
404                         NFC_ERR("net_nfc_controller_set_secure_element_mode failed, [%d]", result);
405                 }
406                 break;
407
408         default:
409                 result = net_nfc_server_se_disable_card_emulation();
410                 if (NET_NFC_OK == result)
411                 {
412                         NFC_INFO("card emulation turned off");
413
414                         if (vconf_set_int(VCONFKEY_NFC_SE_TYPE, VCONFKEY_NFC_SE_TYPE_NONE) != 0)
415                                 NFC_ERR("vconf_set_int failed");
416                 }
417                 break;
418         }
419
420         return result;
421 }
422
423 static void se_close_secure_element_thread_func(gpointer user_data)
424 {
425         net_nfc_error_e result;
426         SeDataHandle *detail = user_data;
427
428         g_assert(detail != NULL);
429         g_assert(detail->object != NULL);
430         g_assert(detail->invocation != NULL);
431
432         if (_se_is_uicc_handle(detail->handle) == true)
433         {
434                 _se_uicc_close(detail->handle);
435
436                 result = NET_NFC_OK;
437         }
438         else if (net_nfc_server_se_is_ese_handle(detail->handle) == true)
439         {
440                 /* decrease client reference count */
441                 net_nfc_server_gdbus_decrease_se_count(
442                                 g_dbus_method_invocation_get_sender(detail->invocation));
443
444                 result = net_nfc_server_se_close_ese();
445         }
446         else
447         {
448                 result = NET_NFC_INVALID_HANDLE;
449         }
450 #if 0
451         if ((gdbus_se_prev_type != net_nfc_server_se_get_se_type()) ||
452                         (gdbus_se_prev_mode != net_nfc_server_se_get_se_mode()))
453         {
454                 /*return back se mode*/
455                 net_nfc_controller_set_secure_element_mode(gdbus_se_prev_type,
456                                 gdbus_se_prev_mode, &result);
457
458                 net_nfc_server_se_set_se_type(gdbus_se_prev_type);
459                 net_nfc_server_se_set_se_mode(gdbus_se_prev_mode);
460         }
461 #endif
462         net_nfc_gdbus_secure_element_complete_close_secure_element(
463                         detail->object, detail->invocation, result);
464
465         g_object_unref(detail->invocation);
466         g_object_unref(detail->object);
467
468         g_free(detail);
469
470         /* shutdown process if it doesn't need */
471         if (net_nfc_server_manager_get_active() == false &&
472                         net_nfc_server_gdbus_is_server_busy() == false)
473         {
474                 net_nfc_server_controller_deinit();
475         }
476 }
477
478 static gboolean se_handle_close_secure_element(
479                 NetNfcGDbusSecureElement *object,
480                 GDBusMethodInvocation *invocation,
481                 guint arg_handle,
482                 GVariant *smack_privilege)
483 {
484         bool ret;
485         gboolean result;
486         SeDataHandle *data;
487
488         NFC_INFO(">>> REQUEST from [%s]", g_dbus_method_invocation_get_sender(invocation));
489
490         /* check privilege and update client context */
491         ret = net_nfc_server_gdbus_check_privilege(invocation, smack_privilege,
492                                 "nfc-manager", "rw");
493         if (false == ret)
494         {
495                 NFC_ERR("permission denied, and finished request");
496
497                 return FALSE;
498         }
499
500         data = g_try_new0(SeDataHandle, 1);
501         if (NULL == data)
502         {
503                 NFC_ERR("Memory allocation failed");
504                 g_dbus_method_invocation_return_dbus_error(invocation,
505                                 "org.tizen.NetNfcService.AllocationError", "Can not allocate memory");
506
507                 return FALSE;
508         }
509
510         data->object = g_object_ref(object);
511         data->invocation = g_object_ref(invocation);
512         data->handle = GUINT_TO_POINTER(arg_handle);
513
514         result = net_nfc_server_controller_async_queue_push(
515                         se_close_secure_element_thread_func, data);
516         if (FALSE == result)
517         {
518                 g_dbus_method_invocation_return_dbus_error(invocation,
519                                 "org.tizen.NetNfcService.Se.ThreadError",
520                                 "can not push to controller thread");
521
522                 g_object_unref(data->object);
523                 g_object_unref(data->invocation);
524
525                 g_free(data);
526         }
527
528         return result;
529 }
530
531 static void se_get_atr_thread_func(gpointer user_data)
532 {
533         GVariant *data;
534         data_s *atr = NULL;
535         SeDataHandle *detail = user_data;
536         net_nfc_error_e result = NET_NFC_OK;
537
538         g_assert(detail != NULL);
539         g_assert(detail->object != NULL);
540         g_assert(detail->invocation != NULL);
541
542         if (_se_is_uicc_handle(detail->handle) == true)
543         {
544                 result = NET_NFC_NOT_SUPPORTED;
545         }
546         else if (net_nfc_server_se_is_ese_handle(detail->handle) == true)
547         {
548                 net_nfc_controller_secure_element_get_atr(detail->handle, &atr, &result);
549         }
550         else
551         {
552                 NFC_ERR("invalid se handle");
553
554                 result = NET_NFC_INVALID_HANDLE;
555         }
556
557         data = net_nfc_util_gdbus_data_to_variant(atr);
558
559         net_nfc_gdbus_secure_element_complete_get_atr(detail->object, detail->invocation,
560                         result, data);
561
562         if (atr != NULL)
563         {
564                 net_nfc_util_free_data(atr);
565                 g_free(atr);
566         }
567
568         g_object_unref(detail->invocation);
569         g_object_unref(detail->object);
570
571         g_free(detail);
572 }
573
574 static gboolean se_handle_get_atr(
575                 NetNfcGDbusSecureElement *object,
576                 GDBusMethodInvocation *invocation,
577                 guint arg_handle,
578                 GVariant *smack_privilege)
579 {
580         bool ret;
581         gboolean result;
582         SeDataHandle *data;
583
584         NFC_INFO(">>> REQUEST from [%s]", g_dbus_method_invocation_get_sender(invocation));
585
586         /* check privilege and update client context */
587         ret = net_nfc_server_gdbus_check_privilege(invocation, smack_privilege,
588                                 "nfc-manager", "r");
589         if (false == ret)
590         {
591                 NFC_ERR("permission denied, and finished request");
592
593                 return FALSE;
594         }
595
596         data = g_try_new0(SeDataHandle, 1);
597         if (NULL == data)
598         {
599                 NFC_ERR("Memory allocation failed");
600                 g_dbus_method_invocation_return_dbus_error(invocation,
601                                 "org.tizen.NetNfcService.AllocationError", "Can not allocate memory");
602
603                 return FALSE;
604         }
605
606         data->object = g_object_ref(object);
607         data->invocation = g_object_ref(invocation);
608         data->handle = GUINT_TO_POINTER(arg_handle);
609
610         result = net_nfc_server_controller_async_queue_push(se_get_atr_thread_func, data);
611         if (FALSE == result)
612         {
613                 g_dbus_method_invocation_return_dbus_error(invocation,
614                                 "org.tizen.NetNfcService.Se.ThreadError",
615                                 "can not push to controller thread");
616
617                 g_object_unref(data->object);
618                 g_object_unref(data->invocation);
619
620                 g_free(data);
621         }
622
623         return result;
624 }
625
626 static void se_open_secure_element_thread_func(gpointer user_data)
627 {
628         SeDataSeType *detail = user_data;
629         net_nfc_error_e result = NET_NFC_OK;
630         net_nfc_target_handle_s *handle = NULL;
631
632         g_assert(detail != NULL);
633         g_assert(detail->object != NULL);
634         g_assert(detail->invocation != NULL);
635
636 #if 0 /* opening SE doesn't affect card emulation */
637         gdbus_se_prev_type = net_nfc_server_se_get_se_type();
638         gdbus_se_prev_mode = net_nfc_server_se_get_se_mode();
639 #endif
640
641         if (detail->se_type == SECURE_ELEMENT_TYPE_UICC)
642         {
643 #if 0 /* opening SE doesn't affect card emulation */
644                 /*off ESE*/
645                 net_nfc_controller_set_secure_element_mode(SECURE_ELEMENT_TYPE_ESE,
646                                 SECURE_ELEMENT_OFF_MODE, &result);
647
648                 /*Off UICC. UICC SHOULD not be detected by external reader when
649                   being communicated in internal process*/
650                 net_nfc_controller_set_secure_element_mode(SECURE_ELEMENT_TYPE_UICC,
651                                 SECURE_ELEMENT_OFF_MODE, &result);
652
653                 net_nfc_server_se_set_se_type(SECURE_ELEMENT_TYPE_UICC);
654                 net_nfc_server_se_set_se_mode(SECURE_ELEMENT_OFF_MODE);
655 #endif
656                 handle = _se_uicc_open();
657                 if (handle != NULL)
658                 {
659                         result = NET_NFC_OK;
660                 }
661                 else
662                 {
663                         result = NET_NFC_INVALID_STATE;
664                         handle = NULL;
665                 }
666         }
667         else if (detail->se_type == SECURE_ELEMENT_TYPE_ESE)
668         {
669 #if 0 /* opening SE doesn't affect card emulation */
670                 /*off UICC*/
671                 net_nfc_controller_set_secure_element_mode(SECURE_ELEMENT_TYPE_UICC,
672                                 SECURE_ELEMENT_OFF_MODE, &result);
673 #endif
674                 handle = net_nfc_server_se_open_ese();
675                 if (handle != NULL)
676                 {
677                         result = NET_NFC_OK;
678 #if 0 /* opening SE doesn't affect card emulation */
679                         net_nfc_server_se_set_se_type(SECURE_ELEMENT_TYPE_ESE);
680                         net_nfc_server_se_set_se_mode(SECURE_ELEMENT_WIRED_MODE);
681
682                         net_nfc_server_se_set_current_ese_handle(handle);
683 #endif
684                         NFC_DBG("handle [%p]", handle);
685
686                         /* increase client reference count */
687                         net_nfc_server_gdbus_increase_se_count(
688                                         g_dbus_method_invocation_get_sender(detail->invocation));
689                 }
690                 else
691                 {
692                         result = NET_NFC_INVALID_STATE;
693                         handle = NULL;
694                 }
695         }
696         else
697         {
698                 result = NET_NFC_INVALID_PARAM;
699                 handle = NULL;
700         }
701
702         net_nfc_gdbus_secure_element_complete_open_secure_element(detail->object,
703                         detail->invocation, result, (guint)handle);
704
705         g_object_unref(detail->invocation);
706         g_object_unref(detail->object);
707
708         g_free(detail);
709 }
710
711 static gboolean se_handle_open_secure_element(
712                 NetNfcGDbusSecureElement *object,
713                 GDBusMethodInvocation *invocation,
714                 gint arg_type,
715                 GVariant *smack_privilege)
716 {
717         bool ret;
718         gboolean result;
719         SeDataSeType *data;
720
721         NFC_INFO(">>> REQUEST from [%s]", g_dbus_method_invocation_get_sender(invocation));
722
723         /* check privilege and update client context */
724         ret = net_nfc_server_gdbus_check_privilege(invocation, smack_privilege,
725                                 "nfc-manager", "rw");
726         if (false == ret)
727         {
728                 NFC_ERR("permission denied, and finished request");
729
730                 return FALSE;
731         }
732
733         data = g_try_new0(SeDataSeType, 1);
734         if (NULL == data)
735         {
736                 NFC_ERR("Memory allocation failed");
737                 g_dbus_method_invocation_return_dbus_error(invocation,
738                                 "org.tizen.NetNfcService.AllocationError", "Can not allocate memory");
739
740                 return FALSE;
741         }
742
743         data->object = g_object_ref(object);
744         data->invocation = g_object_ref(invocation);
745         data->se_type= arg_type;
746
747         result = net_nfc_server_controller_async_queue_push(
748                         se_open_secure_element_thread_func, data);
749         if (FALSE == result)
750         {
751                 g_dbus_method_invocation_return_dbus_error(invocation,
752                                 "org.tizen.NetNfcService.Se.ThreadError",
753                                 "can not push to controller thread");
754
755                 g_object_unref(data->object);
756                 g_object_unref(data->invocation);
757
758                 g_free(data);
759         }
760
761         return result;
762 }
763
764 static void se_send_apdu_thread_func(gpointer user_data)
765 {
766         data_s *response = NULL;
767         GVariant *rspdata = NULL;
768         SeDataApdu *detail = user_data;
769         data_s apdu_data = { NULL, 0 };
770         net_nfc_error_e result = NET_NFC_OK;
771
772         g_assert(detail != NULL);
773         g_assert(detail->object != NULL);
774         g_assert(detail->invocation != NULL);
775
776         net_nfc_util_gdbus_variant_to_data_s(detail->data, &apdu_data);
777
778         if (_se_is_uicc_handle(detail->handle) == true)
779         {
780                 result = NET_NFC_NOT_SUPPORTED;
781         }
782         else if (net_nfc_server_se_is_ese_handle(detail->handle) == true)
783         {
784                 net_nfc_controller_secure_element_send_apdu(detail->handle,
785                                 &apdu_data, &response, &result);
786         }
787         else
788         {
789                 result = NET_NFC_INVALID_HANDLE;
790         }
791
792         rspdata = net_nfc_util_gdbus_data_to_variant(response);
793
794         net_nfc_gdbus_secure_element_complete_send_apdu(detail->object, detail->invocation,
795                         result, rspdata);
796
797         if (response != NULL)
798         {
799                 net_nfc_util_free_data(response);
800                 g_free(response);
801         }
802
803         net_nfc_util_free_data(&apdu_data);
804
805         g_variant_unref(detail->data);
806
807         g_object_unref(detail->invocation);
808         g_object_unref(detail->object);
809
810         g_free(detail);
811 }
812
813 static gboolean se_handle_send_apdu(
814                 NetNfcGDbusSecureElement *object,
815                 GDBusMethodInvocation *invocation,
816                 guint arg_handle,
817                 GVariant *apdudata,
818                 GVariant *smack_privilege)
819 {
820         bool ret;
821         gboolean result;
822         SeDataApdu *data;
823
824         NFC_INFO(">>> REQUEST from [%s]", g_dbus_method_invocation_get_sender(invocation));
825
826         /* check privilege and update client context */
827         ret = net_nfc_server_gdbus_check_privilege(invocation, smack_privilege,
828                                 "nfc-manager", "rw");
829         if (false == ret)
830         {
831                 NFC_ERR("permission denied, and finished request");
832
833                 return FALSE;
834         }
835
836         data = g_try_new0(SeDataApdu, 1);
837         if (NULL == data)
838         {
839                 NFC_ERR("Memory allocation failed");
840                 g_dbus_method_invocation_return_dbus_error(invocation,
841                                 "org.tizen.NetNfcService.AllocationError", "Can not allocate memory");
842
843                 return FALSE;
844         }
845
846         data->object = g_object_ref(object);
847         data->invocation = g_object_ref(invocation);
848         data->handle = GUINT_TO_POINTER(arg_handle);
849         data->data = g_variant_ref(apdudata);
850
851         result = net_nfc_server_controller_async_queue_push(se_send_apdu_thread_func, data);
852         if (FALSE == result)
853         {
854                 g_dbus_method_invocation_return_dbus_error(invocation,
855                                 "org.tizen.NetNfcService.Se.ThreadError",
856                                 "can not push to controller thread");
857
858                 g_variant_unref(data->data);
859
860                 g_object_unref(data->object);
861                 g_object_unref(data->invocation);
862
863                 g_free(data);
864         }
865
866         return result;
867 }
868
869 static void _se_set_card_emulation_thread_func(gpointer user_data)
870 {
871         SeSetCardEmul *data = user_data;
872         net_nfc_error_e result = NET_NFC_OK;
873
874         g_assert(data != NULL);
875         g_assert(data->object != NULL);
876         g_assert(data->invocation != NULL);
877
878         if (data->mode == NET_NFC_CARD_EMELATION_ENABLE)
879         {
880                 net_nfc_controller_set_secure_element_mode(net_nfc_server_se_get_se_mode(),
881                                 SECURE_ELEMENT_VIRTUAL_MODE, &result);
882
883                 if (NET_NFC_OK == result)
884                 {
885                         NFC_DBG("changed to CARD EMULATION ON");
886
887                         net_nfc_server_se_set_se_mode(SECURE_ELEMENT_VIRTUAL_MODE);
888                 }
889                 else
890                 {
891                         NFC_ERR("CARD EMULATION ON fail [%d]", result);
892                 }
893         }
894         else if (data->mode == NET_NFC_CARD_EMULATION_DISABLE)
895         {
896                 net_nfc_controller_set_secure_element_mode(net_nfc_server_se_get_se_mode(),
897                                 SECURE_ELEMENT_OFF_MODE, &result);
898                 if (NET_NFC_OK == result)
899                 {
900                         NFC_DBG("changed to CARD EMULATION OFF");
901
902                         net_nfc_server_se_set_se_mode(SECURE_ELEMENT_OFF_MODE);
903                 }
904                 else
905                 {
906                         NFC_ERR("CARD EMULATION OFF fail [%d]", result);
907                 }
908         }
909         else
910         {
911                 result = NET_NFC_INVALID_PARAM;
912         }
913
914         net_nfc_gdbus_secure_element_complete_set_card_emulation(data->object,
915                         data->invocation, result);
916
917         g_object_unref(data->invocation);
918         g_object_unref(data->object);
919
920         g_free(data);
921 }
922
923 static gboolean _se_handle_set_card_emulation(
924                 NetNfcGDbusSecureElement *object,
925                 GDBusMethodInvocation *invocation,
926                 gint arg_mode,
927                 GVariant *smack_privilege)
928 {
929         bool ret;
930         gboolean result;
931         SeSetCardEmul *data;
932
933         NFC_INFO(">>> REQUEST from [%s]", g_dbus_method_invocation_get_sender(invocation));
934
935         /* check privilege and update client context */
936         ret = net_nfc_server_gdbus_check_privilege(invocation, smack_privilege,
937                                 "nfc-manager", "w");
938         if (false == ret)
939         {
940                 NFC_ERR("permission denied, and finished request");
941
942                 return FALSE;
943         }
944
945         data = g_try_new0(SeSetCardEmul, 1);
946         if (NULL == data)
947         {
948                 NFC_ERR("Memory allocation failed");
949                 g_dbus_method_invocation_return_dbus_error(invocation,
950                                 "org.tizen.NetNfcService.AllocationError", "Can not allocate memory");
951
952                 return FALSE;
953         }
954
955         data->object = g_object_ref(object);
956         data->invocation = g_object_ref(invocation);
957         data->mode = arg_mode;
958
959         result = net_nfc_server_controller_async_queue_push(
960                         _se_set_card_emulation_thread_func, data);
961         if (FALSE == result)
962         {
963                 g_dbus_method_invocation_return_dbus_error(invocation,
964                                 "org.tizen.NetNfcService.Se.ThreadError",
965                                 "can not push to controller thread");
966
967                 g_object_unref(data->object);
968                 g_object_unref(data->invocation);
969
970                 g_free(data);
971         }
972
973         return result;
974 }
975
976 static void se_set_data_thread_func(gpointer user_data)
977 {
978         SeDataSeType *data = user_data;
979         gboolean isTypeChanged = FALSE;
980         net_nfc_error_e result = NET_NFC_OK;
981
982         g_assert(data != NULL);
983         g_assert(data->object != NULL);
984         g_assert(data->invocation != NULL);
985
986         if (data->se_type != net_nfc_server_se_get_se_type())
987         {
988                 result = net_nfc_server_se_change_se(data->se_type);
989                 isTypeChanged = TRUE;
990         }
991
992         net_nfc_gdbus_secure_element_complete_set(data->object, data->invocation, result);
993
994         if (isTypeChanged)
995                 net_nfc_gdbus_secure_element_emit_se_type_changed(data->object, data->se_type);
996
997         g_object_unref(data->invocation);
998         g_object_unref(data->object);
999
1000         g_free(data);
1001 }
1002
1003 static gboolean se_handle_set(NetNfcGDbusSecureElement *object,
1004                 GDBusMethodInvocation *invocation, gint arg_type, GVariant *smack_privilege)
1005 {
1006         bool ret;
1007         gboolean result;
1008         SeDataSeType *data;
1009
1010         NFC_INFO(">>> REQUEST from [%s]", g_dbus_method_invocation_get_sender(invocation));
1011
1012         /* check privilege and update client context */
1013         ret = net_nfc_server_gdbus_check_privilege(invocation, smack_privilege,
1014                                 "nfc-manager", "w");
1015         if (false == ret)
1016         {
1017                 NFC_ERR("permission denied, and finished request");
1018
1019                 return FALSE;
1020         }
1021
1022         data = g_try_new0(SeDataSeType, 1);
1023         if (NULL == data)
1024         {
1025                 NFC_ERR("Memory allocation failed");
1026                 g_dbus_method_invocation_return_dbus_error(invocation,
1027                                 "org.tizen.NetNfcService.AllocationError", "Can not allocate memory");
1028
1029                 return FALSE;
1030         }
1031
1032         data->object = g_object_ref(object);
1033         data->invocation = g_object_ref(invocation);
1034         data->se_type = arg_type;
1035
1036         result = net_nfc_server_controller_async_queue_push(se_set_data_thread_func, data);
1037
1038         if (FALSE == result)
1039         {
1040                 g_dbus_method_invocation_return_dbus_error(invocation,
1041                                 "org.tizen.NetNfcService.Se.ThreadError",
1042                                 "can not push to controller thread");
1043
1044                 g_object_unref(data->object);
1045                 g_object_unref(data->invocation);
1046
1047                 g_free(data);
1048         }
1049
1050         return result;
1051 }
1052
1053 static void se_get_data_thread_func(gpointer user_data)
1054 {
1055         SeDataSeType *data = user_data;
1056         net_nfc_error_e result = NET_NFC_OK;
1057
1058         g_assert(data != NULL);
1059         g_assert(data->object != NULL);
1060         g_assert(data->invocation != NULL);
1061
1062         net_nfc_gdbus_secure_element_complete_get(data->object, data->invocation,
1063                         net_nfc_server_se_get_se_type(), result);
1064
1065         g_object_unref(data->invocation);
1066         g_object_unref(data->object);
1067
1068         g_free(data);
1069 }
1070
1071 static gboolean se_handle_get(NetNfcGDbusSecureElement *object,
1072                 GDBusMethodInvocation *invocation, GVariant *smack_privilege)
1073 {
1074         bool ret;
1075         gboolean result;
1076         SeDataSeType *data;
1077
1078         NFC_INFO(">>> REQUEST from [%s]", g_dbus_method_invocation_get_sender(invocation));
1079
1080         /* check privilege and update client context */
1081         ret = net_nfc_server_gdbus_check_privilege(invocation, smack_privilege,
1082                                 "nfc-manager", "r");
1083         if (false == ret)
1084         {
1085                 NFC_ERR("permission denied, and finished request");
1086
1087                 return FALSE;
1088         }
1089
1090         data = g_try_new0(SeDataSeType, 1);
1091         if (NULL == data)
1092         {
1093                 NFC_ERR("Memory allocation failed");
1094                 g_dbus_method_invocation_return_dbus_error(invocation,
1095                                 "org.tizen.NetNfcService.AllocationError", "Can not allocate memory");
1096
1097                 return FALSE;
1098         }
1099
1100         data->object = g_object_ref(object);
1101         data->invocation = g_object_ref(invocation);
1102
1103         result = net_nfc_server_controller_async_queue_push(se_get_data_thread_func, data);
1104         if (FALSE == result)
1105         {
1106                 g_dbus_method_invocation_return_dbus_error(invocation,
1107                                 "org.tizen.NetNfcService.Se.ThreadError",
1108                                 "can not push to controller thread");
1109
1110                 g_object_unref(data->object);
1111                 g_object_unref(data->invocation);
1112
1113                 g_free(data);
1114         }
1115
1116         return result;
1117 }
1118
1119 static void _se_change_card_emulation_mode_thread_func(gpointer user_data)
1120 {
1121         bool isChanged = false;
1122         net_nfc_error_e result = NET_NFC_OK;
1123         uint8_t current_mode, return_mode;
1124         ChangeCardEmulMode *data = (ChangeCardEmulMode *)user_data;
1125
1126         g_assert(data != NULL);
1127         g_assert(data->object != NULL);
1128         g_assert(data->invocation != NULL);
1129
1130         current_mode = net_nfc_server_se_get_se_mode();
1131
1132         if(data->mode == SECURE_ELEMENT_ACTIVE_STATE
1133                         && current_mode == SECURE_ELEMENT_TYPE_INVALID)
1134         {
1135                 return_mode = net_nfc_server_se_get_return_se_mode();
1136                 result = net_nfc_server_se_change_se(return_mode);
1137                 isChanged = true;
1138         }
1139         else if(data->mode == SECURE_ELEMENT_INACTIVE_STATE
1140                         && current_mode != SECURE_ELEMENT_TYPE_INVALID)
1141         {
1142                 result = net_nfc_server_se_disable_card_emulation();
1143                 isChanged = true;
1144         }
1145
1146         net_nfc_gdbus_secure_element_complete_change_card_emulation_mode(data->object,
1147                         data->invocation, result);
1148
1149         if(isChanged)
1150         {
1151                 net_nfc_gdbus_secure_element_emit_card_emulation_mode_changed(data->object,
1152                         data->mode);
1153         }
1154
1155         g_object_unref(data->invocation);
1156         g_object_unref(data->object);
1157
1158         g_free(data);
1159 }
1160
1161
1162 static gboolean se_handle_change_card_emulation_mode(
1163                 NetNfcGDbusSecureElement *object,
1164                 GDBusMethodInvocation *invocation,
1165                 gint arg_mode,
1166                 GVariant *smack_privilege)
1167 {
1168         bool ret;
1169         gboolean result;
1170         SeSetCardEmul *data;
1171
1172         NFC_DBG(">>> REQUEST from [%s]", g_dbus_method_invocation_get_sender(invocation));
1173
1174         /* check privilege and update client context */
1175         ret = net_nfc_server_gdbus_check_privilege(invocation, smack_privilege,
1176                                 "nfc-manager", "w");
1177         if (false == ret)
1178         {
1179                 NFC_ERR("permission denied, and finished request");
1180
1181                 return FALSE;
1182         }
1183
1184         data = g_try_new0(ChangeCardEmulMode, 1);
1185         if (NULL == data)
1186         {
1187                 NFC_ERR("Memory allocation failed");
1188                 g_dbus_method_invocation_return_dbus_error(invocation,
1189                                 "org.tizen.NetNfcService.AllocationError",
1190                                 "Can not allocate memory");
1191
1192                 return FALSE;
1193         }
1194
1195         data->object = g_object_ref(object);
1196         data->invocation = g_object_ref(invocation);
1197         data->mode = arg_mode;
1198
1199         result = net_nfc_server_controller_async_queue_push(
1200                         _se_change_card_emulation_mode_thread_func, data);
1201         if (FALSE == result)
1202         {
1203                 g_dbus_method_invocation_return_dbus_error(invocation,
1204                                 "org.tizen.NetNfcService.Se.ThreadError",
1205                                 "can not push to controller thread");
1206
1207                 g_object_unref(data->object);
1208                 g_object_unref(data->invocation);
1209
1210                 g_free(data);
1211         }
1212
1213         return result;
1214 }
1215
1216 gboolean net_nfc_server_se_init(GDBusConnection *connection)
1217 {
1218         gboolean result;
1219         GError *error = NULL;
1220
1221         if (se_skeleton)
1222                 g_object_unref(se_skeleton);
1223
1224         /* initialize UICC */
1225         _se_uicc_init();
1226
1227         se_skeleton = net_nfc_gdbus_secure_element_skeleton_new();
1228
1229         g_signal_connect(se_skeleton, "handle-set", G_CALLBACK(se_handle_set), NULL);
1230
1231         g_signal_connect(se_skeleton, "handle-get", G_CALLBACK(se_handle_get), NULL);
1232
1233         g_signal_connect(se_skeleton, "handle-set-card-emulation",
1234                         G_CALLBACK(_se_handle_set_card_emulation), NULL);
1235
1236         g_signal_connect(se_skeleton, "handle-open-secure-element",
1237                         G_CALLBACK(se_handle_open_secure_element), NULL);
1238
1239         g_signal_connect(se_skeleton, "handle-close-secure-element",
1240                         G_CALLBACK(se_handle_close_secure_element), NULL);
1241
1242         g_signal_connect(se_skeleton,   "handle-get-atr", G_CALLBACK(se_handle_get_atr), NULL);
1243
1244         g_signal_connect(se_skeleton, "handle-send-apdu",
1245                         G_CALLBACK(se_handle_send_apdu), NULL);
1246
1247         g_signal_connect(se_skeleton, "handle-change-card-emulation-mode",
1248                         G_CALLBACK(se_handle_change_card_emulation_mode), NULL);
1249
1250         result = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(se_skeleton),
1251                         connection, "/org/tizen/NetNfcService/SecureElement", &error);
1252         if (FALSE == result)
1253         {
1254                 NFC_ERR("can not skeleton_export %s", error->message);
1255
1256                 g_error_free(error);
1257
1258                 net_nfc_server_se_deinit();
1259         }
1260
1261         return result;
1262 }
1263
1264 void net_nfc_server_se_deinit(void)
1265 {
1266         if (se_skeleton)
1267         {
1268                 g_object_unref(se_skeleton);
1269                 se_skeleton = NULL;
1270
1271                 /* de-initialize UICC */
1272                 _se_uicc_deinit();
1273         }
1274 }
1275
1276 static void se_detected_thread_func(gpointer user_data)
1277 {
1278         uint32_t devType = 0;
1279         GVariant *data = NULL;
1280         net_nfc_error_e result = NET_NFC_OK;
1281         net_nfc_target_handle_s *handle = NULL;
1282
1283         g_assert(user_data != NULL);
1284
1285         if (NULL == se_skeleton)
1286         {
1287                 NFC_ERR("se skeleton is not initialized");
1288
1289                 g_variant_unref((GVariant *)user_data);
1290
1291                 return;
1292         }
1293
1294         g_variant_get((GVariant *)user_data, "uu@a(y)", (guint *)&handle, &devType, &data);
1295
1296         net_nfc_server_se_set_current_ese_handle(handle);
1297
1298         NFC_DBG("trying to connect to ESE = [0x%p]", handle);
1299
1300         if (!net_nfc_controller_connect(handle, &result))
1301                 NFC_DBG("connect failed = [%d]", result);
1302
1303         net_nfc_gdbus_secure_element_emit_ese_detected(se_skeleton, GPOINTER_TO_UINT(handle),
1304                         devType, data);
1305
1306         g_variant_unref((GVariant *)user_data);
1307 }
1308
1309 static void se_transcation_thread_func(gpointer user_data)
1310 {
1311         bool fg_dispatch;
1312         pid_t focus_app_pid;
1313         ServerSeData *detail = user_data;
1314
1315
1316         g_assert(user_data != NULL);
1317
1318         if (detail->event == NET_NFC_MESSAGE_SE_START_TRANSACTION)
1319         {
1320                 GVariant *aid = NULL;
1321                 GVariant *param = NULL;
1322                 uint8_t se_type;
1323
1324                 NFC_DBG("launch se app");
1325
1326                 aid = net_nfc_util_gdbus_data_to_variant(&(detail->aid));
1327                 param = net_nfc_util_gdbus_data_to_variant(&(detail->param));
1328                 se_type = net_nfc_server_se_get_se_type();
1329                 focus_app_pid = net_nfc_app_util_get_focus_app_pid();
1330                 fg_dispatch = net_nfc_app_util_check_launch_state();
1331
1332                 /* TODO : check access control */
1333                 net_nfc_gdbus_secure_element_emit_transaction_event (
1334                                 se_skeleton,
1335                                 se_type,
1336                                 aid,
1337                                 param,
1338                                 fg_dispatch,
1339                                 focus_app_pid);
1340
1341                 net_nfc_app_util_launch_se_transaction_app(
1342                                 se_type,
1343                                 detail->aid.buffer,
1344                                 detail->aid.length,
1345                                 detail->param.buffer,
1346                                 detail->param.length);
1347
1348                 NFC_DBG("launch se app end");
1349         }
1350
1351         net_nfc_util_free_data(&detail->param);
1352         net_nfc_util_free_data(&detail->aid);
1353
1354         g_free(detail);
1355 }
1356
1357 void net_nfc_server_se_detected(void *info)
1358 {
1359         gboolean ret;
1360         GVariant *data;
1361         GVariant *parameter;
1362         net_nfc_request_target_detected_t *se_target =
1363                 (net_nfc_request_target_detected_t *)info;
1364
1365         data = net_nfc_util_gdbus_buffer_to_variant(se_target->target_info_values.buffer,
1366                         se_target->target_info_values.length);
1367
1368         parameter = g_variant_new("uu@a(y)", GPOINTER_TO_UINT(se_target->handle),
1369                         se_target->devType, data);
1370         if (parameter != NULL)
1371         {
1372                 ret = net_nfc_server_controller_async_queue_push(se_detected_thread_func,
1373                                         parameter);
1374                 if (FALSE == ret)
1375                 {
1376                         NFC_ERR("can not push to controller thread");
1377
1378                         g_variant_unref(parameter);
1379                 }
1380         }
1381         else
1382         {
1383                 NFC_ERR("g_variant_new failed");
1384         }
1385
1386         /* FIXME : should be removed when plugins would be fixed*/
1387         _net_nfc_util_free_mem(info);
1388 }
1389
1390 void net_nfc_server_se_transaction_received(void *info)
1391 {
1392         gboolean ret;
1393         ServerSeData *detail;
1394         net_nfc_request_se_event_t *se_event = (net_nfc_request_se_event_t *)info;
1395
1396         detail = g_try_new0(ServerSeData, 1);
1397         if (detail != NULL)
1398         {
1399                 detail->event = se_event->request_type;
1400
1401                 if (se_event->aid.buffer != NULL && se_event->aid.length > 0)
1402                 {
1403                         if (net_nfc_util_alloc_data(&detail->aid, se_event->aid.length) == true)
1404                                 memcpy(detail->aid.buffer, se_event->aid.buffer, se_event->aid.length);
1405                 }
1406
1407                 if (se_event->param.buffer != NULL && se_event->param.length > 0)
1408                 {
1409                         if (net_nfc_util_alloc_data(&detail->param, se_event->param.length) == true)
1410                                 memcpy(detail->param.buffer, se_event->param.buffer, se_event->param.length);
1411                 }
1412
1413                 ret = net_nfc_server_controller_async_queue_push(
1414                                         se_transcation_thread_func, detail);
1415                 if (FALSE == ret)
1416                 {
1417                         NFC_ERR("can not push to controller thread");
1418
1419                         net_nfc_util_free_data(&detail->param);
1420                         net_nfc_util_free_data(&detail->aid);
1421
1422                         g_free(detail);
1423                 }
1424         }
1425         else
1426         {
1427                 NFC_ERR("g_new0 failed");
1428         }
1429
1430         /* FIXME : should be removed when plugins would be fixed*/
1431         net_nfc_util_free_data(&se_event->param);
1432         net_nfc_util_free_data(&se_event->aid);
1433
1434         _net_nfc_util_free_mem(info);
1435 }