Change some indent for Tizen 3.0 Coding rule
[platform/core/api/smartcard.git] / src / Session.cpp
1 /*
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /* standard library header */
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <string.h>
22
23 /* SLP library header */
24
25 /* local header */
26 #include "Debug.h"
27 #include "Session.h"
28 #include "Reader.h"
29 #include "ClientChannel.h"
30 #include "ClientGDBus.h"
31
32 #ifndef EXTERN_API
33 #define EXTERN_API __attribute__((visibility("default")))
34 #endif
35
36 namespace smartcard_service_api
37 {
38         Session::Session(void *context, Reader *reader, void *handle) :
39                 SessionHelper(reader)
40         {
41                 this->context = NULL;
42
43                 if (context == NULL || handle == NULL)
44                 {
45                         _ERR("handle is null");
46
47                         return;
48                 }
49
50                 this->context = context;
51                 this->handle = handle;
52
53                 /* init default context */
54                 GError *error = NULL;
55
56                 proxy = smartcard_service_session_proxy_new_for_bus_sync(
57                         G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
58                         "org.tizen.SmartcardService",
59                         "/org/tizen/SmartcardService/Session",
60                         NULL, &error);
61                 if (proxy == NULL)
62                 {
63                         _ERR("Can not create proxy : %s", error->message);
64                         g_error_free(error);
65                         return;
66                 }
67
68                 closed = false;
69         }
70
71         Session::~Session()
72         {
73                 size_t i;
74
75                 closeSync();
76
77                 for (i = 0; i < channels.size(); i++)
78                 {
79                         delete (ClientChannel *)channels[i];
80                 }
81
82                 channels.clear();
83         }
84
85         void Session::closeChannels() throw(ErrorIO &, ErrorIllegalState &)
86         {
87                 size_t i;
88
89                 for (i = 0; i < channels.size(); i++)
90                 {
91                         channels[i]->closeSync();
92                 }
93         }
94
95         void Session::session_get_atr_cb(GObject *source_object,
96                 GAsyncResult *res, gpointer user_data)
97         {
98                 CallbackParam *param = (CallbackParam *)user_data;
99                 Session *session;
100                 getATRCallback callback;
101                 gint result;
102                 GVariant *var_atr;
103                 GError *error = NULL;
104                 ByteArray atr;
105
106                 _INFO("MSG_REQUEST_GET_ATR");
107
108                 if (param == NULL) {
109                         _ERR("null parameter!!!");
110                         return;
111                 }
112
113                 session = (Session *)param->instance;
114                 callback = (getATRCallback)param->callback;
115
116                 if (smartcard_service_session_call_get_atr_finish(
117                         SMARTCARD_SERVICE_SESSION(source_object),
118                         &result, &var_atr, res, &error) == true) {
119                         if (result == SCARD_ERROR_OK) {
120                                 GDBusHelper::convertVariantToByteArray(var_atr, atr);
121
122                                 session->atr = atr;
123                         } else {
124                                 _ERR("smartcard_service_session_call_get_atr failed, [%d]", result);
125                         }
126                 } else {
127                         _ERR("smartcard_service_session_call_get_atr failed, [%s]", error->message);
128                         g_error_free(error);
129
130                         result = SCARD_ERROR_IPC_FAILED;
131                 }
132
133                 if (callback != NULL) {
134                         callback(atr.getBuffer(),
135                                 atr.size(), result, param->user_param);
136                 }
137
138                 delete param;
139         }
140
141         void Session::session_open_channel_cb(GObject *source_object,
142                 GAsyncResult *res, gpointer user_data)
143         {
144                 CallbackParam *param = (CallbackParam *)user_data;
145                 Session *session;
146                 openChannelCallback callback;
147                 gint result = SCARD_ERROR_UNKNOWN;
148                 gint channel_number;
149                 guint channel_id;
150                 GVariant *var_response;
151                 GError *error = NULL;
152                 Channel *channel = NULL;
153
154                 _INFO("MSG_REQUEST_OPEN_CHANNEL");
155
156                 if (param == NULL) {
157                         _ERR("null parameter!!!");
158                         return;
159                 }
160
161                 session = (Session *)param->instance;
162                 callback = (openChannelCallback)param->callback;
163
164                 if (smartcard_service_session_call_open_channel_finish(
165                         SMARTCARD_SERVICE_SESSION(source_object),
166                         &result, &channel_id, &channel_number, &var_response,
167                         res, &error) == true) {
168                         if (result == SCARD_ERROR_OK) {
169                                 ByteArray response;
170
171                                 GDBusHelper::convertVariantToByteArray(
172                                         var_response, response);
173
174                                 /* create new instance of channel */
175                                 channel = new ClientChannel(session->context,
176                                         session, channel_id,
177                                         response, GUINT_TO_POINTER(channel_id));
178                                 if (channel != NULL) {
179                                         session->channels.push_back(channel);
180                                 } else {
181                                         _ERR("alloc failed");
182
183                                         result = SCARD_ERROR_OUT_OF_MEMORY;
184                                 }
185                         } else {
186                                 _ERR("smartcard_service_session_call_open_channel failed, [%d]", result);
187                         }
188                 } else {
189                         _ERR("smartcard_service_session_call_open_channel failed, [%s]", error->message);
190                         g_error_free(error);
191
192                         result = SCARD_ERROR_IPC_FAILED;
193                 }
194
195                 if (callback != NULL) {
196                         callback(channel, result, param->user_param);
197                 }
198
199                 delete param;
200         }
201
202         void Session::session_close_cb(GObject *source_object,
203                 GAsyncResult *res, gpointer user_data)
204         {
205                 CallbackParam *param = (CallbackParam *)user_data;
206                 Session *session;
207                 closeSessionCallback callback;
208                 gint result;
209                 GError *error = NULL;
210
211                 _INFO("MSG_REQUEST_CLOSE_SESSION");
212
213                 if (param == NULL) {
214                         _ERR("null parameter!!!");
215                         return;
216                 }
217
218                 session = (Session *)param->instance;
219                 callback = (closeSessionCallback)param->callback;
220
221                 if (smartcard_service_session_call_close_session_finish(
222                         SMARTCARD_SERVICE_SESSION(source_object),
223                         &result, res, &error) == true) {
224                         if (result == SCARD_ERROR_OK) {
225                                 session->closed = true;
226                         } else {
227                                 _ERR("smartcard_service_session_call_close_session failed, [%d]", result);
228                         }
229                 } else {
230                         _ERR("smartcard_service_session_call_close_session failed, [%s]", error->message);
231                         g_error_free(error);
232
233                         result = SCARD_ERROR_IPC_FAILED;
234                 }
235
236                 if (callback != NULL) {
237                         callback(result, param->user_param);
238                 }
239
240                 delete param;
241         }
242
243         const ByteArray Session::getATRSync()
244                 throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
245                         ErrorIllegalState &, ErrorIllegalParameter &)
246         {
247                 ByteArray result;
248
249                 if (getReader()->isSecureElementPresent() == true) {
250                         if (atr.isEmpty() == true)
251                         {
252                                 gint ret;
253                                 GVariant *var_atr = NULL;
254                                 GError *error = NULL;
255
256                                 if (smartcard_service_session_call_get_atr_sync(
257                                         (SmartcardServiceSession *)proxy,
258                                         GPOINTER_TO_UINT(context),
259                                         GPOINTER_TO_UINT(handle),
260                                         &ret, &var_atr, NULL, &error) == true) {
261                                         if (ret == SCARD_ERROR_OK) {
262                                                 GDBusHelper::convertVariantToByteArray(var_atr, result);
263
264                                                 atr = result;
265                                         } else {
266                                                 _ERR("smartcard_service_session_call_get_atr_sync failed, [%d]", ret);
267
268                                                 THROW_ERROR(ret);
269                                         }
270                                 } else {
271                                         _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
272                                         g_error_free(error);
273
274                                         THROW_ERROR(SCARD_ERROR_IPC_FAILED);
275                                 }
276                         }
277
278                         result = atr;
279                 } else {
280                         _ERR("unavailable session");
281                         throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
282                 }
283
284                 return result;
285         }
286
287         int Session::getATR(getATRCallback callback, void *userData)
288         {
289                 int result;
290
291                 if (getReader()->isSecureElementPresent() == true) {
292                         if (atr.isEmpty() == true) {
293                                 CallbackParam *param = new CallbackParam();
294
295                                 param->instance = this;
296                                 param->callback = (void *)callback;
297                                 param->user_param = userData;
298
299                                 smartcard_service_session_call_get_atr(
300                                         (SmartcardServiceSession *)proxy,
301                                         GPOINTER_TO_UINT(context),
302                                         GPOINTER_TO_UINT(handle), NULL,
303                                         &Session::session_get_atr_cb, param);
304
305                                 result = SCARD_ERROR_OK;
306                         } else {
307                                 result = SCARD_ERROR_OK;
308
309                                 /* TODO : invoke callback directly */
310                                 callback(atr.getBuffer(),
311                                         atr.size(), 0, userData);
312                         }
313                 } else {
314                         _ERR("unavailable session");
315                         result = SCARD_ERROR_ILLEGAL_STATE;
316                 }
317
318                 return result;
319         }
320
321         void Session::closeSync()
322                 throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
323                         ErrorIllegalState &, ErrorIllegalParameter &)
324         {
325                 if (isClosed() == false)
326                 {
327                         closed = true;
328                         closeChannels();
329
330                         gint ret;
331                         GError *error = NULL;
332
333                         if (smartcard_service_session_call_close_session_sync(
334                                 (SmartcardServiceSession *)proxy,
335                                 GPOINTER_TO_UINT(context),
336                                 GPOINTER_TO_UINT(handle),
337                                 &ret, NULL, &error) == true) {
338                                 if (ret == SCARD_ERROR_OK) {
339                                         closed = true;
340                                 } else {
341                                         _ERR("smartcard_service_session_call_close_session_sync failed, [%d]", ret);
342
343                                         THROW_ERROR(ret);
344                                 }
345                         } else {
346                                 _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
347                                 g_error_free(error);
348
349                                 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
350                         }
351                 }
352         }
353
354         int Session::close(closeSessionCallback callback, void *userData)
355         {
356                 int result = SCARD_ERROR_OK;
357
358                 if (isClosed() == false)
359                 {
360                         closed = true;
361                         closeChannels();
362
363                         CallbackParam *param = new CallbackParam();
364
365                         param->instance = this;
366                         param->callback = (void *)callback;
367                         param->user_param = userData;
368
369                         smartcard_service_session_call_close_session(
370                                 (SmartcardServiceSession *)proxy,
371                                 GPOINTER_TO_UINT(context),
372                                 GPOINTER_TO_UINT(handle), NULL,
373                                 &Session::session_close_cb, param);
374                 }
375
376                 return result;
377         }
378
379         size_t Session::getChannelCount() const
380         {
381                 size_t count = 0;
382
383                 if (getReader()->isSecureElementPresent() == true) {
384                         count = channels.size();
385                 } else {
386                         _ERR("unavailable session");
387                         throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
388                 }
389
390                 return count;
391         }
392         Channel *Session::openChannelSync(int id, const ByteArray &aid)
393                 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
394                         ErrorIllegalParameter &, ErrorSecurity &)
395         {
396                 return openChannelSync(id, aid, 0x00);
397         }
398
399         Channel *Session::openChannelSync(int id, const ByteArray &aid, unsigned char P2)
400                 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
401                         ErrorIllegalParameter &, ErrorSecurity &)
402         {
403                 Channel *channel = NULL;
404
405                 if (getReader()->isSecureElementPresent() == true) {
406                         gint ret;
407                         GVariant *var_aid = NULL, *var_response = NULL;
408                         guint channel_id;
409                         gint channel_number;
410                         GError *error = NULL;
411
412                         var_aid = GDBusHelper::convertByteArrayToVariant(aid);
413
414                         if (smartcard_service_session_call_open_channel_sync(
415                                 (SmartcardServiceSession *)proxy,
416                                 GPOINTER_TO_UINT(context),
417                                 GPOINTER_TO_UINT(handle),
418                                 (guint)id, var_aid, (guint8)P2, &ret, &channel_id, &channel_number,
419                                 &var_response, NULL, &error) == true) {
420                                 if (ret == SCARD_ERROR_OK && channel_id != 0) {
421                                         ByteArray response;
422
423                                         GDBusHelper::convertVariantToByteArray(
424                                                 var_response, response);
425
426                                         /* create new instance of channel */
427                                         channel = new ClientChannel(context,
428                                                 this, channel_number,
429                                                 response, GUINT_TO_POINTER(channel_id));
430                                         if (channel != NULL) {
431                                                 channels.push_back(channel);
432                                         } else {
433                                                 _ERR("alloc failed");
434
435                                                 THROW_ERROR(SCARD_ERROR_OUT_OF_MEMORY);
436                                         }
437                                 } else {
438                                         _ERR("smartcard_service_session_call_open_channel_sync failed, [%d]", ret);
439
440                                         THROW_ERROR(ret);
441                                 }
442                         } else {
443                                 _ERR("smartcard_service_session_call_open_channel_sync failed, [%s]", error->message);
444                                 g_error_free(error);
445
446                                 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
447                         }
448                 } else {
449                         _ERR("unavailable session");
450
451                         throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
452                 }
453
454                 return (Channel *)channel;
455         }
456
457         int Session::openChannel(int id, const ByteArray &aid, openChannelCallback callback, void *userData)
458         {
459                 int result;
460
461                 if (getReader()->isSecureElementPresent() == true) {
462                         GVariant *var_aid;
463
464                         CallbackParam *param = new CallbackParam();
465
466                         param->instance = this;
467                         param->callback = (void *)callback;
468                         param->user_param = userData;
469
470                         var_aid = GDBusHelper::convertByteArrayToVariant(aid);
471
472                         smartcard_service_session_call_open_channel(
473                                 (SmartcardServiceSession *)proxy,
474                                 GPOINTER_TO_UINT(context),
475                                 GPOINTER_TO_UINT(handle),
476                                 (guint)id, var_aid, 0, NULL,
477                                 &Session::session_open_channel_cb, param);
478
479                         result = SCARD_ERROR_OK;
480                 } else {
481                         _ERR("unavailable session");
482                         result = SCARD_ERROR_ILLEGAL_STATE;
483                 }
484
485                 return result;
486         }
487
488         Channel *Session::openBasicChannelSync(const ByteArray &aid)
489                 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
490                         ErrorIllegalParameter &, ErrorSecurity &)
491         {
492                 return openChannelSync(0, aid, 0x00);
493         }
494
495         Channel *Session::openBasicChannelSync(const ByteArray &aid, unsigned char P2)
496                 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
497                         ErrorIllegalParameter &, ErrorSecurity &)
498         {
499                 return openChannelSync(0, aid, P2);
500         }
501
502         Channel *Session::openBasicChannelSync(const unsigned char *aid, unsigned int length)
503                 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
504                         ErrorIllegalParameter &, ErrorSecurity &)
505         {
506                 ByteArray temp(aid, length);
507
508                 return openBasicChannelSync(temp, 0x00);
509         }
510
511         Channel *Session::openBasicChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
512                 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
513                         ErrorIllegalParameter &, ErrorSecurity &)
514         {
515                 ByteArray temp(aid, length);
516
517                 return openBasicChannelSync(temp, P2);
518         }
519
520         int Session::openBasicChannel(const ByteArray &aid, openChannelCallback callback, void *userData)
521         {
522                 return openChannel(0, aid, callback, userData);
523         }
524
525         int Session::openBasicChannel(const unsigned char *aid, unsigned int length,
526                 openChannelCallback callback, void *userData)
527         {
528                 ByteArray temp(aid, length);
529
530                 return openBasicChannel(temp, callback, userData);
531         }
532
533         Channel *Session::openLogicalChannelSync(const ByteArray &aid)
534                 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
535                         ErrorIllegalParameter &, ErrorSecurity &)
536         {
537                 return openChannelSync(1, aid, 0x00);
538         }
539
540         Channel *Session::openLogicalChannelSync(const ByteArray &aid, unsigned char P2)
541                 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
542                         ErrorIllegalParameter &, ErrorSecurity &)
543         {
544                 return openChannelSync(1, aid, P2);
545         }
546
547         Channel *Session::openLogicalChannelSync(const unsigned char *aid, unsigned int length)
548                 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
549                         ErrorIllegalParameter &, ErrorSecurity &)
550         {
551                 ByteArray temp(aid, length);
552
553                 return openLogicalChannelSync(temp, 0x00);
554         }
555
556         Channel *Session::openLogicalChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
557                 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
558                         ErrorIllegalParameter &, ErrorSecurity &)
559         {
560                 ByteArray temp(aid, length);
561
562                 return openLogicalChannelSync(temp, P2);
563         }
564
565         int Session::openLogicalChannel(const ByteArray &aid, openChannelCallback callback, void *userData)
566         {
567                 return openChannel(1, aid, callback, userData);
568         }
569
570         int Session::openLogicalChannel(const unsigned char *aid, unsigned int length,
571                 openChannelCallback callback, void *userData)
572         {
573                 ByteArray temp(aid, length);
574
575                 return openLogicalChannel(temp, callback, userData);
576         }
577 } /* namespace smartcard_service_api */
578
579 /* export C API */
580 #define SESSION_EXTERN_BEGIN \
581         if (handle != NULL) \
582         { \
583                 Session *session = (Session *)handle;
584
585 #define SESSION_EXTERN_END \
586         } \
587         else \
588         { \
589                 _ERR("Invalid param"); \
590         }
591
592 using namespace smartcard_service_api;
593
594 EXTERN_API int session_get_reader(session_h handle, int* reader_handle)
595 {
596         int result = SCARD_ERROR_OK;
597         reader_h reader = NULL;
598
599         SESSION_EXTERN_BEGIN;
600
601         try
602         {
603                 reader = session->getReader();
604                 *reader_handle = (long)reader;
605         }
606         catch (ExceptionBase &e)
607         {
608                 _ERR("Error occur : %s\n", e.what());
609                 result = e.getErrorCode();
610                 *reader_handle = 0;
611         }
612         catch (...)
613         {
614                 _ERR("Error occur : unknown error\n");
615                 result = SCARD_ERROR_UNKNOWN;
616                 *reader_handle = 0;
617         }
618
619         SESSION_EXTERN_END;
620
621         return result;
622 }
623
624 EXTERN_API int session_is_closed(session_h handle, bool* is_closed)
625 {
626         int result = SCARD_ERROR_OK;
627
628         SESSION_EXTERN_BEGIN;
629
630         try
631         {
632                 *is_closed = session->isClosed();
633         }
634         catch (ExceptionBase &e)
635         {
636                 _ERR("Error occur : %s\n", e.what());
637                 result = e.getErrorCode();
638         }
639         catch (...)
640         {
641                 _ERR("Error occur : unknown error\n");
642                 result = SCARD_ERROR_UNKNOWN;
643         }
644
645         SESSION_EXTERN_END;
646
647         return result;
648 }
649
650 EXTERN_API int session_close_channels(session_h handle)
651 {
652         int result = SCARD_ERROR_OK;
653
654         SESSION_EXTERN_BEGIN;
655
656         try
657         {
658                 session->closeChannels();
659         }
660         catch (ExceptionBase &e)
661         {
662                 _ERR("Error occur : %s\n", e.what());
663                 result = e.getErrorCode();
664         }
665         catch (...)
666         {
667                 _ERR("Error occur : unknown error\n");
668                 result = SCARD_ERROR_UNKNOWN;
669         }
670
671         SESSION_EXTERN_END;
672
673         return result;
674 }
675
676 EXTERN_API int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length)
677 {
678         ByteArray temp;
679         int result = SCARD_ERROR_OK;
680
681         SESSION_EXTERN_BEGIN;
682
683         try
684         {
685                 temp = session->getATRSync();
686
687                 if (temp.size() > 0)
688                 {
689                         *buffer = (unsigned char *)calloc(temp.size(), sizeof(char));
690                         *length = temp.size();
691
692                         memcpy(*buffer, temp.getBuffer(), *length);
693                 }
694         }
695         catch (ErrorIllegalState &e)
696         {
697                 _ERR("Error occur : %s\n", e.what());
698                 result = e.getErrorCode();
699
700                 if(result == SCARD_ERROR_OPERATION_NOT_SUPPORTED)
701                 {
702                         *length = 0;
703                         result = SCARD_ERROR_OK;
704                 }
705         }
706         catch (ExceptionBase &e)
707         {
708                 _ERR("Error occur : %s\n", e.what());
709                 result = e.getErrorCode();
710                 *length = 0;
711         }
712         catch (...)
713         {
714                 _ERR("Error occur : unknown error\n");
715                 result = SCARD_ERROR_UNKNOWN;
716                 *length = 0;
717         }
718
719         SESSION_EXTERN_END;
720
721         return result;
722 }
723
724 EXTERN_API int session_close_sync(session_h handle)
725 {
726         int result = SCARD_ERROR_OK;
727
728         SESSION_EXTERN_BEGIN;
729
730         try
731         {
732                 session->closeSync();
733         }
734         catch (ExceptionBase &e)
735         {
736                 _ERR("Error occur : %s\n", e.what());
737                 result = e.getErrorCode();
738         }
739         catch (...)
740         {
741                 _ERR("Error occur : unknown error\n");
742                 result = SCARD_ERROR_UNKNOWN;
743         }
744
745         SESSION_EXTERN_END;
746
747         return result;
748 }
749
750 EXTERN_API int session_open_basic_channel_sync(session_h handle, unsigned char *aid,
751         unsigned int length, unsigned char P2, int* channel_handle)
752 {
753         int result = SCARD_ERROR_OK;
754
755         SESSION_EXTERN_BEGIN;
756
757         try
758         {
759                 *channel_handle = (long)session->openBasicChannelSync(aid, length, P2);
760         }
761         catch (ExceptionBase &e)
762         {
763                 _ERR("Error occur : %s\n", e.what());
764                 result = e.getErrorCode();
765                 *channel_handle = 0;
766         }
767         catch (...)
768         {
769                 _ERR("Error occur : unknown error\n");
770                 result = SCARD_ERROR_UNKNOWN;
771                 *channel_handle = 0;
772         }
773
774         SESSION_EXTERN_END;
775
776         return result;
777 }
778
779 EXTERN_API  int session_open_logical_channel_sync(session_h handle, unsigned char *aid,
780         unsigned int length, unsigned char P2, int* channel_handle)
781 {
782         int result = SCARD_ERROR_OK;
783
784         SESSION_EXTERN_BEGIN;
785
786         try
787         {
788                 *channel_handle = (long)session->openLogicalChannelSync(aid, length, P2);
789         }
790         catch (ExceptionBase &e)
791         {
792                 _ERR("Error occur : %s\n", e.what());
793                 result = e.getErrorCode();
794                 *channel_handle = 0;
795         }
796         catch (...)
797         {
798                 _ERR("Error occur : unknown error\n");
799                 result = SCARD_ERROR_UNKNOWN;
800                 *channel_handle = 0;
801         }
802
803         SESSION_EXTERN_END;
804
805         return result;
806 }
807
808 EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
809 {
810         int result = -1;
811
812         SESSION_EXTERN_BEGIN;
813                 result = session->getATR((getATRCallback)callback, userData);
814         SESSION_EXTERN_END;
815
816         return result;
817 }
818
819 EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
820 {
821         int result = -1;
822
823         SESSION_EXTERN_BEGIN;
824                 result = session->close((closeSessionCallback)callback, userData);
825         SESSION_EXTERN_END;
826
827         return result;
828 }
829
830 EXTERN_API int session_open_basic_channel(session_h handle, unsigned char *aid,
831         unsigned int length, session_open_channel_cb callback, void *userData)
832 {
833         int result = -1;
834
835         SESSION_EXTERN_BEGIN;
836                 result = session->openBasicChannel(aid, length, (openChannelCallback)callback, userData);
837         SESSION_EXTERN_END;
838
839         return result;
840 }
841
842 EXTERN_API int session_open_logical_channel(session_h handle, unsigned char *aid,
843         unsigned int length, session_open_channel_cb callback, void *userData)
844 {
845         int result = -1;
846
847         SESSION_EXTERN_BEGIN;
848                 result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
849         SESSION_EXTERN_END;
850
851         return result;
852 }
853
854 EXTERN_API size_t session_get_channel_count(session_h handle)
855 {
856         size_t result = 0;
857
858         SESSION_EXTERN_BEGIN;
859                 result = session->getChannelCount();
860         SESSION_EXTERN_END;
861
862         return result;
863 }
864
865 EXTERN_API void session_destroy_instance(session_h handle)
866 {
867 }
868