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