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