Smartcard structure refactoring : capi layer
[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, (void *)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                 {
251                         if (atr.isEmpty() == true)
252                         {
253                                 gint ret;
254                                 GVariant *var_atr = NULL;
255                                 GError *error = NULL;
256
257                                 if (smartcard_service_session_call_get_atr_sync(
258                                         (SmartcardServiceSession *)proxy,
259                                         GPOINTER_TO_UINT(context),
260                                         GPOINTER_TO_UINT(handle),
261                                         &ret, &var_atr, NULL, &error) == true) {
262                                         if (ret == SCARD_ERROR_OK) {
263                                                 GDBusHelper::convertVariantToByteArray(var_atr, result);
264
265                                                 atr = result;
266                                         } else {
267                                                 _ERR("smartcard_service_session_call_get_atr_sync failed, [%d]", ret);
268
269                                                 THROW_ERROR(ret);
270                                         }
271                                 } else {
272                                         _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
273                                         g_error_free(error);
274
275                                         THROW_ERROR(SCARD_ERROR_IPC_FAILED);
276                                 }
277                         }
278
279                         result = atr;
280                 }
281                 else
282                 {
283                         _ERR("unavailable session");
284                         throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
285                 }
286
287                 return result;
288         }
289
290         int Session::getATR(getATRCallback callback, void *userData)
291         {
292                 int result;
293
294                 if (getReader()->isSecureElementPresent() == true)
295                 {
296                         if (atr.isEmpty() == true)
297                         {
298                                 CallbackParam *param = new CallbackParam();
299
300                                 param->instance = this;
301                                 param->callback = (void *)callback;
302                                 param->user_param = userData;
303
304                                 smartcard_service_session_call_get_atr(
305                                         (SmartcardServiceSession *)proxy,
306                                         GPOINTER_TO_UINT(context),
307                                         GPOINTER_TO_UINT(handle), NULL,
308                                         &Session::session_get_atr_cb, param);
309
310                                 result = SCARD_ERROR_OK;
311                         }
312                         else
313                         {
314                                 result = SCARD_ERROR_OK;
315
316                                 /* TODO : invoke callback directly */
317                                 callback(atr.getBuffer(),
318                                         atr.size(), 0, userData);
319                         }
320                 }
321                 else
322                 {
323                         _ERR("unavailable session");
324                         result = SCARD_ERROR_ILLEGAL_STATE;
325                 }
326
327                 return result;
328         }
329
330         void Session::closeSync()
331                 throw (ExceptionBase &, ErrorIO &, ErrorSecurity &,
332                         ErrorIllegalState &, ErrorIllegalParameter &)
333         {
334                 if (isClosed() == false)
335                 {
336                         closed = true;
337                         closeChannels();
338
339                         gint ret;
340                         GError *error = NULL;
341
342                         if (smartcard_service_session_call_close_session_sync(
343                                 (SmartcardServiceSession *)proxy,
344                                 GPOINTER_TO_UINT(context),
345                                 GPOINTER_TO_UINT(handle),
346                                 &ret, NULL, &error) == true) {
347                                 if (ret == SCARD_ERROR_OK) {
348                                         closed = true;
349                                 } else {
350                                         _ERR("smartcard_service_session_call_close_session_sync failed, [%d]", ret);
351
352                                         THROW_ERROR(ret);
353                                 }
354                         } else {
355                                 _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
356                                 g_error_free(error);
357
358                                 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
359                         }
360                 }
361         }
362
363         int Session::close(closeSessionCallback callback, void *userData)
364         {
365                 int result = SCARD_ERROR_OK;
366
367                 if (isClosed() == false)
368                 {
369                         closed = true;
370                         closeChannels();
371
372                         CallbackParam *param = new CallbackParam();
373
374                         param->instance = this;
375                         param->callback = (void *)callback;
376                         param->user_param = userData;
377
378                         smartcard_service_session_call_close_session(
379                                 (SmartcardServiceSession *)proxy,
380                                 GPOINTER_TO_UINT(context),
381                                 GPOINTER_TO_UINT(handle), NULL,
382                                 &Session::session_close_cb, param);
383                 }
384
385                 return result;
386         }
387
388         size_t Session::getChannelCount() const
389         {
390                 size_t count = 0;
391
392                 if (getReader()->isSecureElementPresent() == true)
393                 {
394                         count = channels.size();
395                 }
396                 else
397                 {
398                         _ERR("unavailable session");
399                         throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
400                 }
401
402                 return count;
403         }
404         Channel *Session::openChannelSync(int id, const ByteArray &aid)
405                 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
406                         ErrorIllegalParameter &, ErrorSecurity &)
407         {
408                 return openChannelSync(id, aid, 0x00);
409         }
410
411         Channel *Session::openChannelSync(int id, const ByteArray &aid, unsigned char P2)
412                 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
413                         ErrorIllegalParameter &, ErrorSecurity &)
414         {
415                 Channel *channel = NULL;
416
417                 if (getReader()->isSecureElementPresent() == true)
418                 {
419                         gint ret;
420                         GVariant *var_aid = NULL, *var_response = NULL;
421                         guint channel_id;
422                         gint channel_number;
423                         GError *error = NULL;
424
425                         var_aid = GDBusHelper::convertByteArrayToVariant(aid);
426
427                         if (smartcard_service_session_call_open_channel_sync(
428                                 (SmartcardServiceSession *)proxy,
429                                 GPOINTER_TO_UINT(context),
430                                 GPOINTER_TO_UINT(handle),
431                                 (guint)id, var_aid, (guint8)P2, &ret, &channel_id, &channel_number,
432                                 &var_response, NULL, &error) == true) {
433                                 if (ret == SCARD_ERROR_OK && channel_id != 0) {
434                                         ByteArray response;
435
436                                         GDBusHelper::convertVariantToByteArray(
437                                                 var_response, response);
438
439                                         /* create new instance of channel */
440                                         channel = new ClientChannel(context,
441                                                 this, channel_number,
442                                                 response, (void *)channel_id);
443                                         if (channel != NULL)
444                                         {
445                                                 channels.push_back(channel);
446                                         }
447                                         else
448                                         {
449                                                 _ERR("alloc failed");
450
451                                                 THROW_ERROR(SCARD_ERROR_OUT_OF_MEMORY);
452                                         }
453                                 } else {
454                                         _ERR("smartcard_service_session_call_open_channel_sync failed, [%d]", ret);
455
456                                         THROW_ERROR(ret);
457                                 }
458                         } else {
459                                 _ERR("smartcard_service_session_call_open_channel_sync failed, [%s]", error->message);
460                                 g_error_free(error);
461
462                                 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
463                         }
464                 }
465                 else
466                 {
467                         _ERR("unavailable session");
468
469                         throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
470                 }
471
472                 return (Channel *)channel;
473         }
474
475         int Session::openChannel(int id, const ByteArray &aid, openChannelCallback callback, void *userData)
476         {
477                 int result;
478
479                 if (getReader()->isSecureElementPresent() == true)
480                 {
481                         GVariant *var_aid;
482
483                         CallbackParam *param = new CallbackParam();
484
485                         param->instance = this;
486                         param->callback = (void *)callback;
487                         param->user_param = userData;
488
489                         var_aid = GDBusHelper::convertByteArrayToVariant(aid);
490
491                         smartcard_service_session_call_open_channel(
492                                 (SmartcardServiceSession *)proxy,
493                                 GPOINTER_TO_UINT(context),
494                                 GPOINTER_TO_UINT(handle),
495                                 (guint)id, var_aid, 0, NULL,
496                                 &Session::session_open_channel_cb, param);
497
498                         result = SCARD_ERROR_OK;
499                 }
500                 else
501                 {
502                         _ERR("unavailable session");
503                         result = SCARD_ERROR_ILLEGAL_STATE;
504                 }
505
506                 return result;
507         }
508
509         Channel *Session::openBasicChannelSync(const ByteArray &aid)
510                 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
511                         ErrorIllegalParameter &, ErrorSecurity &)
512         {
513                 return openChannelSync(0, aid, 0x00);
514         }
515
516         Channel *Session::openBasicChannelSync(const ByteArray &aid, unsigned char P2)
517                 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
518                         ErrorIllegalParameter &, ErrorSecurity &)
519         {
520                 return openChannelSync(0, aid, P2);
521         }
522
523         Channel *Session::openBasicChannelSync(const unsigned char *aid, unsigned int length)
524                 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
525                         ErrorIllegalParameter &, ErrorSecurity &)
526         {
527                 ByteArray temp(aid, length);
528
529                 return openBasicChannelSync(temp, 0x00);
530         }
531
532         Channel *Session::openBasicChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
533                 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
534                         ErrorIllegalParameter &, ErrorSecurity &)
535         {
536                 ByteArray temp(aid, length);
537
538                 return openBasicChannelSync(temp, P2);
539         }
540
541         int Session::openBasicChannel(const ByteArray &aid, openChannelCallback callback, void *userData)
542         {
543                 return openChannel(0, aid, callback, userData);
544         }
545
546         int Session::openBasicChannel(const unsigned char *aid, unsigned int length,
547                 openChannelCallback callback, void *userData)
548         {
549                 ByteArray temp(aid, length);
550
551                 return openBasicChannel(temp, callback, userData);
552         }
553
554         Channel *Session::openLogicalChannelSync(const ByteArray &aid)
555                 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
556                         ErrorIllegalParameter &, ErrorSecurity &)
557         {
558                 return openChannelSync(1, aid, 0x00);
559         }
560
561         Channel *Session::openLogicalChannelSync(const ByteArray &aid, unsigned char P2)
562                 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
563                         ErrorIllegalParameter &, ErrorSecurity &)
564         {
565                 return openChannelSync(1, aid, P2);
566         }
567
568         Channel *Session::openLogicalChannelSync(const unsigned char *aid, unsigned int length)
569                 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
570                         ErrorIllegalParameter &, ErrorSecurity &)
571         {
572                 ByteArray temp(aid, length);
573
574                 return openLogicalChannelSync(temp, 0x00);
575         }
576
577         Channel *Session::openLogicalChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
578                 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
579                         ErrorIllegalParameter &, ErrorSecurity &)
580         {
581                 ByteArray temp(aid, length);
582
583                 return openLogicalChannelSync(temp, P2);
584         }
585
586         int Session::openLogicalChannel(const ByteArray &aid, openChannelCallback callback, void *userData)
587         {
588                 return openChannel(1, aid, callback, userData);
589         }
590
591         int Session::openLogicalChannel(const unsigned char *aid, unsigned int length,
592                 openChannelCallback callback, void *userData)
593         {
594                 ByteArray temp(aid, length);
595
596                 return openLogicalChannel(temp, callback, userData);
597         }
598 } /* namespace smartcard_service_api */
599
600 /* export C API */
601 #define SESSION_EXTERN_BEGIN \
602         if (handle != NULL) \
603         { \
604                 Session *session = (Session *)handle;
605
606 #define SESSION_EXTERN_END \
607         } \
608         else \
609         { \
610                 _ERR("Invalid param"); \
611         }
612
613 using namespace smartcard_service_api;
614
615 EXTERN_API int session_get_reader(session_h handle, int* reader_handle)
616 {
617         int result = SCARD_ERROR_OK;
618         reader_h reader = NULL;
619
620         SESSION_EXTERN_BEGIN;
621
622         try
623         {
624                 reader = session->getReader();
625                 *reader_handle = (long)reader;
626         }
627         catch (ExceptionBase &e)
628         {
629                 _ERR("Error occur : %s\n", e.what());
630                 result = e.getErrorCode();
631                 *reader_handle = 0;
632         }
633         catch (...)
634         {
635                 _ERR("Error occur : unknown error\n");
636                 result = SCARD_ERROR_UNKNOWN;
637                 *reader_handle = 0;
638         }
639
640         SESSION_EXTERN_END;
641
642         return result;
643 }
644
645 EXTERN_API int session_is_closed(session_h handle, bool* is_closed)
646 {
647         int result = SCARD_ERROR_OK;
648
649         SESSION_EXTERN_BEGIN;
650
651         try
652         {
653                 *is_closed = session->isClosed();
654         }
655         catch (ExceptionBase &e)
656         {
657                 _ERR("Error occur : %s\n", e.what());
658                 result = e.getErrorCode();
659         }
660         catch (...)
661         {
662                 _ERR("Error occur : unknown error\n");
663                 result = SCARD_ERROR_UNKNOWN;
664         }
665
666         SESSION_EXTERN_END;
667
668         return result;
669 }
670
671 EXTERN_API int session_close_channels(session_h handle)
672 {
673         int result = SCARD_ERROR_OK;
674
675         SESSION_EXTERN_BEGIN;
676
677         try
678         {
679                 session->closeChannels();
680         }
681         catch (ExceptionBase &e)
682         {
683                 _ERR("Error occur : %s\n", e.what());
684                 result = e.getErrorCode();
685         }
686         catch (...)
687         {
688                 _ERR("Error occur : unknown error\n");
689                 result = SCARD_ERROR_UNKNOWN;
690         }
691
692         SESSION_EXTERN_END;
693
694         return result;
695 }
696
697 EXTERN_API int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length)
698 {
699         ByteArray temp;
700         int result = SCARD_ERROR_OK;
701
702         SESSION_EXTERN_BEGIN;
703
704         try
705         {
706                 temp = session->getATRSync();
707
708                 if (temp.size() > 0)
709                 {
710                         *buffer = (unsigned char *)calloc(temp.size(), sizeof(char));
711                         *length = temp.size();
712
713                         memcpy(*buffer, temp.getBuffer(), *length);
714                 }
715         }
716         catch (ErrorIllegalState &e)
717         {
718                 _ERR("Error occur : %s\n", e.what());
719                 result = e.getErrorCode();
720
721                 if(result == SCARD_ERROR_OPERATION_NOT_SUPPORTED)
722                 {
723                         *length = 0;
724                         result = SCARD_ERROR_OK;
725                 }
726         }
727         catch (ExceptionBase &e)
728         {
729                 _ERR("Error occur : %s\n", e.what());
730                 result = e.getErrorCode();
731                 *length = 0;
732         }
733         catch (...)
734         {
735                 _ERR("Error occur : unknown error\n");
736                 result = SCARD_ERROR_UNKNOWN;
737                 *length = 0;
738         }
739
740         SESSION_EXTERN_END;
741
742         return result;
743 }
744
745 EXTERN_API int session_close_sync(session_h handle)
746 {
747         int result = SCARD_ERROR_OK;
748
749         SESSION_EXTERN_BEGIN;
750
751         try
752         {
753                 session->closeSync();
754         }
755         catch (ExceptionBase &e)
756         {
757                 _ERR("Error occur : %s\n", e.what());
758                 result = e.getErrorCode();
759         }
760         catch (...)
761         {
762                 _ERR("Error occur : unknown error\n");
763                 result = SCARD_ERROR_UNKNOWN;
764         }
765
766         SESSION_EXTERN_END;
767
768         return result;
769 }
770
771 EXTERN_API int session_open_basic_channel_sync(session_h handle, unsigned char *aid,
772         unsigned int length, unsigned char P2, int* channel_handle)
773 {
774         int result = SCARD_ERROR_OK;
775
776         SESSION_EXTERN_BEGIN;
777
778         try
779         {
780                 *channel_handle = (long)session->openBasicChannelSync(aid, length, P2);
781         }
782         catch (ExceptionBase &e)
783         {
784                 _ERR("Error occur : %s\n", e.what());
785                 result = e.getErrorCode();
786                 *channel_handle = 0;
787         }
788         catch (...)
789         {
790                 _ERR("Error occur : unknown error\n");
791                 result = SCARD_ERROR_UNKNOWN;
792                 *channel_handle = 0;
793         }
794
795         SESSION_EXTERN_END;
796
797         return result;
798 }
799
800 EXTERN_API  int session_open_logical_channel_sync(session_h handle, unsigned char *aid,
801         unsigned int length, unsigned char P2, int* channel_handle)
802 {
803         int result = SCARD_ERROR_OK;
804
805         SESSION_EXTERN_BEGIN;
806
807         try
808         {
809                 *channel_handle = (long)session->openLogicalChannelSync(aid, length, P2);
810         }
811         catch (ExceptionBase &e)
812         {
813                 _ERR("Error occur : %s\n", e.what());
814                 result = e.getErrorCode();
815                 *channel_handle = 0;
816         }
817         catch (...)
818         {
819                 _ERR("Error occur : unknown error\n");
820                 result = SCARD_ERROR_UNKNOWN;
821                 *channel_handle = 0;
822         }
823
824         SESSION_EXTERN_END;
825
826         return result;
827 }
828
829 EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
830 {
831         int result = -1;
832
833         SESSION_EXTERN_BEGIN;
834                 result = session->getATR((getATRCallback)callback, userData);
835         SESSION_EXTERN_END;
836
837         return result;
838 }
839
840 EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
841 {
842         int result = -1;
843
844         SESSION_EXTERN_BEGIN;
845                 result = session->close((closeSessionCallback)callback, userData);
846         SESSION_EXTERN_END;
847
848         return result;
849 }
850
851 EXTERN_API int session_open_basic_channel(session_h handle, unsigned char *aid,
852         unsigned int length, session_open_channel_cb callback, void *userData)
853 {
854         int result = -1;
855
856         SESSION_EXTERN_BEGIN;
857                 result = session->openBasicChannel(aid, length, (openChannelCallback)callback, userData);
858         SESSION_EXTERN_END;
859
860         return result;
861 }
862
863 EXTERN_API int session_open_logical_channel(session_h handle, unsigned char *aid,
864         unsigned int length, session_open_channel_cb callback, void *userData)
865 {
866         int result = -1;
867
868         SESSION_EXTERN_BEGIN;
869                 result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
870         SESSION_EXTERN_END;
871
872         return result;
873 }
874
875 EXTERN_API size_t session_get_channel_count(session_h handle)
876 {
877         size_t result = 0;
878
879         SESSION_EXTERN_BEGIN;
880                 result = session->getChannelCount();
881         SESSION_EXTERN_END;
882
883         return result;
884 }
885
886 EXTERN_API void session_destroy_instance(session_h handle)
887 {
888 }
889