Fix build warnings for gcc 9
[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 /* 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                         _ERR("Can not create proxy : %s", error->message);
66                         g_error_free(error);
67                         return;
68                 }
69
70                 closed = false;
71         }
72
73         Session::~Session()
74         {
75                 size_t i;
76
77                 closeSync();
78
79                 for (i = 0; i < channels.size(); i++)
80                 {
81                         delete (ClientChannel *)channels[i];
82                 }
83
84                 channels.clear();
85         }
86
87         void Session::closeChannels()
88         {
89                 size_t i;
90
91                 for (i = 0; i < channels.size(); i++)
92                 {
93                         channels[i]->closeSync();
94                 }
95         }
96
97         void Session::session_get_atr_cb(GObject *source_object,
98                 GAsyncResult *res, gpointer user_data)
99         {
100                 CallbackParam *param = (CallbackParam *)user_data;
101                 Session *session;
102                 getATRCallback callback;
103                 gint result;
104                 GVariant *var_atr;
105                 GError *error = NULL;
106                 ByteArray atr;
107
108                 _INFO("MSG_REQUEST_GET_ATR");
109
110                 if (param == NULL) {
111                         _ERR("null parameter!!!");
112                         return;
113                 }
114
115                 session = (Session *)param->instance;
116                 callback = (getATRCallback)param->callback;
117
118                 if (smartcard_service_session_call_get_atr_finish(
119                         SMARTCARD_SERVICE_SESSION(source_object),
120                         &result, &var_atr, res, &error) == true) {
121                         if (result == SCARD_ERROR_OK) {
122                                 GDBusHelper::convertVariantToByteArray(var_atr, atr);
123
124                                 session->atr = atr;
125                         } else {
126                                 _ERR("smartcard_service_session_call_get_atr failed, [%d]", result);
127                         }
128                 } else {
129                         _ERR("smartcard_service_session_call_get_atr failed, [%s]", error->message);
130                         g_error_free(error);
131
132                         result = SCARD_ERROR_IPC_FAILED;
133                 }
134
135                 if (callback != NULL) {
136                         callback(atr.getBuffer(),
137                                 atr.size(), result, param->user_param);
138                 }
139
140                 delete param;
141         }
142
143         void Session::session_open_channel_cb(GObject *source_object,
144                 GAsyncResult *res, gpointer user_data)
145         {
146                 CallbackParam *param = (CallbackParam *)user_data;
147                 Session *session;
148                 openChannelCallback callback;
149                 gint result = SCARD_ERROR_UNKNOWN;
150                 gint channel_number;
151                 guint channel_id;
152                 GVariant *var_response;
153                 GError *error = NULL;
154                 Channel *channel = NULL;
155
156                 _INFO("MSG_REQUEST_OPEN_CHANNEL");
157
158                 if (param == NULL) {
159                         _ERR("null parameter!!!");
160                         return;
161                 }
162
163                 session = (Session *)param->instance;
164                 callback = (openChannelCallback)param->callback;
165
166                 if (smartcard_service_session_call_open_channel_finish(
167                         SMARTCARD_SERVICE_SESSION(source_object),
168                         &result, &channel_id, &channel_number, &var_response,
169                         res, &error) == true) {
170                         if (result == SCARD_ERROR_OK) {
171                                 ByteArray response;
172
173                                 GDBusHelper::convertVariantToByteArray(
174                                         var_response, response);
175
176                                 /* create new instance of channel */
177                                 channel = new (std::nothrow)ClientChannel(session->context,
178                                         session, channel_id,
179                                         response, GUINT_TO_POINTER(channel_id));
180                                 if (channel != NULL) {
181                                         session->channels.push_back(channel);
182                                 } else {
183                                         _ERR("alloc failed");
184
185                                         result = SCARD_ERROR_OUT_OF_MEMORY;
186                                 }
187                         } else {
188                                 _ERR("smartcard_service_session_call_open_channel failed, [%d]", result);
189                         }
190                 } else {
191                         _ERR("smartcard_service_session_call_open_channel failed, [%s]", error->message);
192                         g_error_free(error);
193
194                         result = SCARD_ERROR_IPC_FAILED;
195                 }
196
197                 if (callback != NULL) {
198                         callback(channel, result, param->user_param);
199                 }
200
201                 delete param;
202         }
203
204         void Session::session_close_cb(GObject *source_object,
205                 GAsyncResult *res, gpointer user_data)
206         {
207                 CallbackParam *param = (CallbackParam *)user_data;
208                 Session *session;
209                 closeSessionCallback callback;
210                 gint result;
211                 GError *error = NULL;
212
213                 _INFO("MSG_REQUEST_CLOSE_SESSION");
214
215                 if (param == NULL) {
216                         _ERR("null parameter!!!");
217                         return;
218                 }
219
220                 session = (Session *)param->instance;
221                 callback = (closeSessionCallback)param->callback;
222
223                 if (smartcard_service_session_call_close_session_finish(
224                         SMARTCARD_SERVICE_SESSION(source_object),
225                         &result, res, &error) == true) {
226                         if (result == SCARD_ERROR_OK) {
227                                 session->closed = true;
228                         } else {
229                                 _ERR("smartcard_service_session_call_close_session failed, [%d]", result);
230                         }
231                 } else {
232                         _ERR("smartcard_service_session_call_close_session failed, [%s]", error->message);
233                         g_error_free(error);
234
235                         result = SCARD_ERROR_IPC_FAILED;
236                 }
237
238                 if (callback != NULL) {
239                         callback(result, param->user_param);
240                 }
241
242                 delete param;
243         }
244
245         const ByteArray Session::getATRSync()
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 (std::nothrow)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         {
323                 if (isClosed() == false)
324                 {
325                         closed = true;
326                         closeChannels();
327
328                         gint ret;
329                         GError *error = NULL;
330
331                         if (smartcard_service_session_call_close_session_sync(
332                                 (SmartcardServiceSession *)proxy,
333                                 GPOINTER_TO_UINT(context),
334                                 GPOINTER_TO_UINT(handle),
335                                 &ret, NULL, &error) == true) {
336                                 if (ret == SCARD_ERROR_OK) {
337                                         closed = true;
338                                 } else {
339                                         _ERR("smartcard_service_session_call_close_session_sync failed, [%d]", ret);
340
341                                         THROW_ERROR(ret);
342                                 }
343                         } else {
344                                 _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
345                                 g_error_free(error);
346
347                                 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
348                         }
349                 }
350         }
351
352         int Session::close(closeSessionCallback callback, void *userData)
353         {
354                 int result = SCARD_ERROR_OK;
355
356                 if (isClosed() == false)
357                 {
358                         closed = true;
359                         closeChannels();
360
361                         CallbackParam *param = new (std::nothrow)CallbackParam();
362
363                         param->instance = this;
364                         param->callback = (void *)callback;
365                         param->user_param = userData;
366
367                         smartcard_service_session_call_close_session(
368                                 (SmartcardServiceSession *)proxy,
369                                 GPOINTER_TO_UINT(context),
370                                 GPOINTER_TO_UINT(handle), NULL,
371                                 &Session::session_close_cb, param);
372                 }
373
374                 return result;
375         }
376
377         size_t Session::getChannelCount() const
378         {
379                 size_t count = 0;
380
381                 if (getReader()->isSecureElementPresent() == true) {
382                         count = channels.size();
383                 } else {
384                         _ERR("unavailable session");
385                         throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
386                 }
387
388                 return count;
389         }
390         Channel *Session::openChannelSync(int id, const ByteArray &aid)
391         {
392                 return openChannelSync(id, aid, 0x00);
393         }
394
395         Channel *Session::openChannelSync(int id, const ByteArray &aid, unsigned char P2)
396         {
397                 Channel *channel = NULL;
398
399                 if (getReader()->isSecureElementPresent() == true) {
400                         gint ret;
401                         GVariant *var_aid = NULL, *var_response = NULL;
402                         guint channel_id;
403                         gint channel_number;
404                         GError *error = NULL;
405
406                         var_aid = GDBusHelper::convertByteArrayToVariant(aid);
407
408                         if (smartcard_service_session_call_open_channel_sync(
409                                 (SmartcardServiceSession *)proxy,
410                                 GPOINTER_TO_UINT(context),
411                                 GPOINTER_TO_UINT(handle),
412                                 (guint)id, var_aid, (guint8)P2, &ret, &channel_id, &channel_number,
413                                 &var_response, NULL, &error) == true) {
414                                 if (ret == SCARD_ERROR_OK && channel_id != 0) {
415                                         ByteArray response;
416
417                                         GDBusHelper::convertVariantToByteArray(
418                                                 var_response, response);
419
420                                         /* create new instance of channel */
421                                         channel = new (std::nothrow)ClientChannel(context,
422                                                 this, channel_number,
423                                                 response, GUINT_TO_POINTER(channel_id));
424                                         if (channel != NULL) {
425                                                 channels.push_back(channel);
426                                         } else {
427                                                 _ERR("alloc failed");
428
429                                                 THROW_ERROR(SCARD_ERROR_OUT_OF_MEMORY);
430                                         }
431                                 } else {
432                                         _ERR("smartcard_service_session_call_open_channel_sync failed, [%d]", ret);
433
434                                         THROW_ERROR(ret);
435                                 }
436                         } else {
437                                 _ERR("smartcard_service_session_call_open_channel_sync failed, [%s]", error->message);
438                                 g_error_free(error);
439
440                                 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
441                         }
442                 } else {
443                         _ERR("unavailable session");
444
445                         throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
446                 }
447
448                 return (Channel *)channel;
449         }
450
451         int Session::openChannel(int id, const ByteArray &aid, openChannelCallback callback, void *userData)
452         {
453                 int result;
454
455                 if (getReader()->isSecureElementPresent() == true) {
456                         GVariant *var_aid;
457
458                         CallbackParam *param = new (std::nothrow)CallbackParam();
459
460                         param->instance = this;
461                         param->callback = (void *)callback;
462                         param->user_param = userData;
463
464                         var_aid = GDBusHelper::convertByteArrayToVariant(aid);
465
466                         smartcard_service_session_call_open_channel(
467                                 (SmartcardServiceSession *)proxy,
468                                 GPOINTER_TO_UINT(context),
469                                 GPOINTER_TO_UINT(handle),
470                                 (guint)id, var_aid, 0, NULL,
471                                 &Session::session_open_channel_cb, param);
472
473                         result = SCARD_ERROR_OK;
474                 } else {
475                         _ERR("unavailable session");
476                         result = SCARD_ERROR_ILLEGAL_STATE;
477                 }
478
479                 return result;
480         }
481
482         Channel *Session::openBasicChannelSync(const ByteArray &aid)
483         {
484                 return openChannelSync(0, aid, 0x00);
485         }
486
487         Channel *Session::openBasicChannelSync(const ByteArray &aid, unsigned char P2)
488         {
489                 return openChannelSync(0, aid, P2);
490         }
491
492         Channel *Session::openBasicChannelSync(const unsigned char *aid, unsigned int length)
493         {
494                 ByteArray temp(aid, length);
495
496                 return openBasicChannelSync(temp, 0x00);
497         }
498
499         Channel *Session::openBasicChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
500         {
501                 ByteArray temp(aid, length);
502
503                 return openBasicChannelSync(temp, P2);
504         }
505
506         int Session::openBasicChannel(const ByteArray &aid, openChannelCallback callback, void *userData)
507         {
508                 return openChannel(0, aid, callback, userData);
509         }
510
511         int Session::openBasicChannel(const unsigned char *aid, unsigned int length,
512                 openChannelCallback callback, void *userData)
513         {
514                 ByteArray temp(aid, length);
515
516                 return openBasicChannel(temp, callback, userData);
517         }
518
519         Channel *Session::openLogicalChannelSync(const ByteArray &aid)
520         {
521                 return openChannelSync(1, aid, 0x00);
522         }
523
524         Channel *Session::openLogicalChannelSync(const ByteArray &aid, unsigned char P2)
525         {
526                 return openChannelSync(1, aid, P2);
527         }
528
529         Channel *Session::openLogicalChannelSync(const unsigned char *aid, unsigned int length)
530         {
531                 ByteArray temp(aid, length);
532
533                 return openLogicalChannelSync(temp, 0x00);
534         }
535
536         Channel *Session::openLogicalChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
537         {
538                 ByteArray temp(aid, length);
539
540                 return openLogicalChannelSync(temp, P2);
541         }
542
543         int Session::openLogicalChannel(const ByteArray &aid, openChannelCallback callback, void *userData)
544         {
545                 return openChannel(1, aid, callback, userData);
546         }
547
548         int Session::openLogicalChannel(const unsigned char *aid, unsigned int length,
549                 openChannelCallback callback, void *userData)
550         {
551                 ByteArray temp(aid, length);
552
553                 return openLogicalChannel(temp, callback, userData);
554         }
555 } /* namespace smartcard_service_api */
556
557 /* export C API */
558 #define SESSION_EXTERN_BEGIN \
559         if (handle != NULL) \
560         { \
561                 Session *session = (Session *)handle;
562
563 #define SESSION_EXTERN_END \
564         } \
565         else \
566         { \
567                 _ERR("Invalid param"); \
568         }
569
570 using namespace smartcard_service_api;
571
572 EXTERN_API int session_get_reader(session_h handle, int* reader_handle)
573 {
574         int result = SCARD_ERROR_OK;
575         reader_h reader = NULL;
576
577         SESSION_EXTERN_BEGIN;
578
579         try
580         {
581                 reader = session->getReader();
582                 *reader_handle = (long)reader;
583         }
584         catch (ExceptionBase &e)
585         {
586                 _ERR("Error occur : %s\n", e.what());
587                 result = e.getErrorCode();
588                 *reader_handle = 0;
589         }
590         catch (...)
591         {
592                 _ERR("Error occur : unknown error\n");
593                 result = SCARD_ERROR_UNKNOWN;
594                 *reader_handle = 0;
595         }
596
597         SESSION_EXTERN_END;
598
599         return result;
600 }
601
602 EXTERN_API int session_is_closed(session_h handle, bool* is_closed)
603 {
604         int result = SCARD_ERROR_OK;
605
606         SESSION_EXTERN_BEGIN;
607
608         try
609         {
610                 *is_closed = session->isClosed();
611         }
612         catch (ExceptionBase &e)
613         {
614                 _ERR("Error occur : %s\n", e.what());
615                 result = e.getErrorCode();
616         }
617         catch (...)
618         {
619                 _ERR("Error occur : unknown error\n");
620                 result = SCARD_ERROR_UNKNOWN;
621         }
622
623         SESSION_EXTERN_END;
624
625         return result;
626 }
627
628 EXTERN_API int session_close_channels(session_h handle)
629 {
630         int result = SCARD_ERROR_OK;
631
632         SESSION_EXTERN_BEGIN;
633
634         try
635         {
636                 session->closeChannels();
637         }
638         catch (ExceptionBase &e)
639         {
640                 _ERR("Error occur : %s\n", e.what());
641                 result = e.getErrorCode();
642         }
643         catch (...)
644         {
645                 _ERR("Error occur : unknown error\n");
646                 result = SCARD_ERROR_UNKNOWN;
647         }
648
649         SESSION_EXTERN_END;
650
651         return result;
652 }
653
654 EXTERN_API int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length)
655 {
656         ByteArray temp;
657         int result = SCARD_ERROR_OK;
658
659         SESSION_EXTERN_BEGIN;
660
661         try
662         {
663                 temp = session->getATRSync();
664
665                 if (temp.size() > 0)
666                 {
667                         *buffer = (unsigned char *)calloc(temp.size(), sizeof(char));
668                         *length = temp.size();
669
670                         memcpy(*buffer, temp.getBuffer(), *length);
671                 }
672         }
673         catch (ErrorIllegalState &e)
674         {
675                 _ERR("Error occur : %s\n", e.what());
676                 result = e.getErrorCode();
677
678                 if(result == SCARD_ERROR_OPERATION_NOT_SUPPORTED)
679                 {
680                         *length = 0;
681                         result = SCARD_ERROR_OK;
682                 }
683         }
684         catch (ExceptionBase &e)
685         {
686                 _ERR("Error occur : %s\n", e.what());
687                 result = e.getErrorCode();
688                 *length = 0;
689         }
690         catch (...)
691         {
692                 _ERR("Error occur : unknown error\n");
693                 result = SCARD_ERROR_UNKNOWN;
694                 *length = 0;
695         }
696
697         SESSION_EXTERN_END;
698
699         return result;
700 }
701
702 EXTERN_API int session_close_sync(session_h handle)
703 {
704         int result = SCARD_ERROR_OK;
705
706         SESSION_EXTERN_BEGIN;
707
708         try
709         {
710                 session->closeSync();
711         }
712         catch (ExceptionBase &e)
713         {
714                 _ERR("Error occur : %s\n", e.what());
715                 result = e.getErrorCode();
716         }
717         catch (...)
718         {
719                 _ERR("Error occur : unknown error\n");
720                 result = SCARD_ERROR_UNKNOWN;
721         }
722
723         SESSION_EXTERN_END;
724
725         return result;
726 }
727
728 EXTERN_API int session_open_basic_channel_sync(session_h handle, unsigned char *aid,
729         unsigned int length, unsigned char P2, int* channel_handle)
730 {
731         int result = SCARD_ERROR_OK;
732
733         SESSION_EXTERN_BEGIN;
734
735         try
736         {
737                 *channel_handle = (long)session->openBasicChannelSync(aid, length, P2);
738         }
739         catch (ExceptionBase &e)
740         {
741                 _ERR("Error occur : %s\n", e.what());
742                 result = e.getErrorCode();
743                 *channel_handle = 0;
744         }
745         catch (...)
746         {
747                 _ERR("Error occur : unknown error\n");
748                 result = SCARD_ERROR_UNKNOWN;
749                 *channel_handle = 0;
750         }
751
752         SESSION_EXTERN_END;
753
754         return result;
755 }
756
757 EXTERN_API  int session_open_logical_channel_sync(session_h handle, unsigned char *aid,
758         unsigned int length, unsigned char P2, int* channel_handle)
759 {
760         int result = SCARD_ERROR_OK;
761
762         SESSION_EXTERN_BEGIN;
763
764         try
765         {
766                 *channel_handle = (long)session->openLogicalChannelSync(aid, length, P2);
767         }
768         catch (ExceptionBase &e)
769         {
770                 _ERR("Error occur : %s\n", e.what());
771                 result = e.getErrorCode();
772                 *channel_handle = 0;
773         }
774         catch (...)
775         {
776                 _ERR("Error occur : unknown error\n");
777                 result = SCARD_ERROR_UNKNOWN;
778                 *channel_handle = 0;
779         }
780
781         SESSION_EXTERN_END;
782
783         return result;
784 }
785
786 EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
787 {
788         int result = -1;
789
790         SESSION_EXTERN_BEGIN;
791                 result = session->getATR((getATRCallback)callback, userData);
792         SESSION_EXTERN_END;
793
794         return result;
795 }
796
797 EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
798 {
799         int result = -1;
800
801         SESSION_EXTERN_BEGIN;
802                 result = session->close((closeSessionCallback)callback, userData);
803         SESSION_EXTERN_END;
804
805         return result;
806 }
807
808 EXTERN_API int session_open_basic_channel(session_h handle, unsigned char *aid,
809         unsigned int length, session_open_channel_cb callback, void *userData)
810 {
811         int result = -1;
812
813         SESSION_EXTERN_BEGIN;
814                 result = session->openBasicChannel(aid, length, (openChannelCallback)callback, userData);
815         SESSION_EXTERN_END;
816
817         return result;
818 }
819
820 EXTERN_API int session_open_logical_channel(session_h handle, unsigned char *aid,
821         unsigned int length, session_open_channel_cb callback, void *userData)
822 {
823         int result = -1;
824
825         SESSION_EXTERN_BEGIN;
826                 result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
827         SESSION_EXTERN_END;
828
829         return result;
830 }
831
832 EXTERN_API size_t session_get_channel_count(session_h handle)
833 {
834         size_t result = 0;
835
836         SESSION_EXTERN_BEGIN;
837                 result = session->getChannelCount();
838         SESSION_EXTERN_END;
839
840         return result;
841 }
842
843 EXTERN_API void session_destroy_instance(session_h handle)
844 {
845 }
846
847 /* LCOV_EXCL_STOP */
848