2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 /* standard library header */
23 /* SLP library header */
29 #include "ClientChannel.h"
30 #include "ClientIPC.h"
33 #define EXTERN_API __attribute__((visibility("default")))
36 namespace smartcard_service_api
38 Session::Session(void *context, Reader *reader, void *handle) :
43 if (context == NULL || handle == NULL)
45 SCARD_DEBUG_ERR("handle is null");
50 this->context = context;
51 this->handle = handle;
61 for (i = 0; i < channels.size(); i++)
63 delete (ClientChannel *)channels[i];
69 void Session::closeChannels() throw (ErrorIO &, ErrorIllegalState &)
73 for (i = 0; i < channels.size(); i++)
75 channels[i]->closeSync();
79 ByteArray Session::getATRSync() throw (ErrorIO &, ErrorIllegalState &)
82 if (getReader()->isSecureElementPresent() == true)
84 if (atr.isEmpty() == true)
89 #ifdef CLIENT_IPC_THREAD
90 /* request channel handle from server */
91 msg.message = Message::MSG_REQUEST_GET_ATR;
92 msg.param1 = (unsigned long)handle;
93 msg.error = (unsigned long)context; /* using error to context */
94 msg.caller = (void *)this;
95 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
98 if (ClientIPC::getInstance().sendMessage(&msg) == true)
100 rv = waitTimedCondition(0);
103 SCARD_DEBUG_ERR("time over");
108 SCARD_DEBUG_ERR("sendMessage failed");
118 SCARD_DEBUG_ERR("unavailable session");
124 int Session::getATR(getATRCallback callback, void *userData)
128 if (getReader()->isSecureElementPresent() == true)
130 if (atr.isEmpty() == true)
135 /* request channel handle from server */
136 msg.message = Message::MSG_REQUEST_GET_ATR;
137 msg.param1 = (unsigned long)handle;
138 msg.error = (unsigned long)context; /* using error to context */
139 msg.caller = (void *)this;
140 msg.callback = (void *)callback;
141 msg.userParam = userData;
143 if (ClientIPC::getInstance().sendMessage(&msg) == true)
150 /* TODO : invoke callback directly */
151 callback(atr.getBuffer(), atr.getLength(), 0, userData);
156 SCARD_DEBUG_ERR("unavailable session");
162 void Session::closeSync() throw (ErrorIO &, ErrorIllegalState &)
167 #ifdef CLIENT_IPC_THREAD
168 if (isClosed() == false)
173 /* request channel handle from server */
174 msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
175 msg.param1 = (unsigned long)handle;
176 msg.error = (unsigned long)context; /* using error to context */
177 msg.caller = (void *)this;
178 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
181 if (ClientIPC::getInstance().sendMessage(&msg) == true)
183 rv = waitTimedCondition(0);
187 SCARD_DEBUG_ERR("time over");
192 SCARD_DEBUG_ERR("sendMessage failed");
199 int Session::close(closeSessionCallback callback, void *userData)
204 if (isClosed() == false)
209 /* request channel handle from server */
210 msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
211 msg.param1 = (unsigned long)handle;
212 msg.error = (unsigned long)context; /* using error to context */
213 msg.caller = (void *)this;
214 msg.callback = (void *)callback;
215 msg.userParam = userData;
217 if (ClientIPC::getInstance().sendMessage(&msg) == true)
226 unsigned int Session::getChannelCountSync()
230 if (getReader()->isSecureElementPresent() == true)
236 #ifdef CLIENT_IPC_THREAD
237 /* request channel handle from server */
238 msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
239 msg.param1 = (unsigned long)handle;
240 msg.error = (unsigned long)context; /* using error to context */
241 msg.caller = (void *)this;
242 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
247 if (ClientIPC::getInstance().sendMessage(&msg) == true)
249 rv = waitTimedCondition(0);
252 SCARD_DEBUG_ERR("time over");
257 SCARD_DEBUG_ERR("sendMessage failed");
264 SCARD_DEBUG_ERR("unavailable session");
270 int Session::getChannelCount(getChannelCountCallback callback, void *userData)
274 if (getReader()->isSecureElementPresent() == true)
279 msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
280 msg.param1 = (unsigned long)handle;
281 msg.error = (unsigned long)context; /* using error to context */
282 msg.caller = (void *)this;
283 msg.callback = (void *)callback;
284 msg.userParam = userData;
286 if (ClientIPC::getInstance().sendMessage(&msg) == true)
293 SCARD_DEBUG_ERR("unavailable session");
299 Channel *Session::openChannelSync(int id, ByteArray aid)
300 throw (ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
302 openedChannel = NULL;
304 if (getReader()->isSecureElementPresent() == true)
309 #ifdef CLIENT_IPC_THREAD
310 /* request channel handle from server */
311 msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
313 msg.param2 = (unsigned long)handle;
315 msg.error = (unsigned long)context; /* using error to context */
316 msg.caller = (void *)this;
317 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
320 if (ClientIPC::getInstance().sendMessage(&msg) == true)
322 rv = waitTimedCondition(0);
325 SCARD_DEBUG_ERR("time over");
330 SCARD_DEBUG_ERR("sendMessage failed");
337 SCARD_DEBUG_ERR("unavailable session");
340 return (Channel *)openedChannel;
343 int Session::openChannel(int id, ByteArray aid, openChannelCallback callback, void *userData)
347 if (getReader()->isSecureElementPresent() == true)
351 /* request channel handle from server */
352 msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
354 msg.param2 = (unsigned long)handle;
356 msg.error = (unsigned long)context; /* using error to context */
357 msg.caller = (void *)this;
358 msg.callback = (void *)callback;
359 msg.userParam = userData;
361 if (ClientIPC::getInstance().sendMessage(&msg) == true)
368 SCARD_DEBUG_ERR("unavailable session");
374 Channel *Session::openBasicChannelSync(ByteArray aid)
375 throw (ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
377 return openChannelSync(0, aid);
380 Channel *Session::openBasicChannelSync(unsigned char *aid, unsigned int length)
381 throw (ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
383 return openBasicChannelSync(ByteArray(aid, length));
386 int Session::openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData)
388 return openChannel(0, aid, callback, userData);
391 int Session::openBasicChannel(unsigned char *aid, unsigned int length,
392 openChannelCallback callback, void *userData)
394 return openBasicChannel(ByteArray(aid, length), callback, userData);
397 Channel *Session::openLogicalChannelSync(ByteArray aid)
398 throw (ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
400 return openChannelSync(1, aid);
403 Channel *Session::openLogicalChannelSync(unsigned char *aid, unsigned int length)
404 throw (ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
406 return openLogicalChannelSync(ByteArray(aid, length));
409 int Session::openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData)
411 return openChannel(1, aid, callback, userData);
414 int Session::openLogicalChannel(unsigned char *aid, unsigned int length,
415 openChannelCallback callback, void *userData)
417 return openLogicalChannel(ByteArray(aid, length), callback, userData);
420 bool Session::dispatcherCallback(void *message)
422 Message *msg = (Message *)message;
423 Session *session = NULL;
428 SCARD_DEBUG_ERR("message is null");
432 session = (Session *)msg->caller;
434 switch (msg->message)
436 case Message::MSG_REQUEST_OPEN_CHANNEL :
438 Channel *channel = NULL;
440 SCARD_DEBUG("MSG_REQUEST_OPEN_CHANNEL");
442 if (msg->param1 != 0)
444 /* create new instance of channel */
445 channel = new ClientChannel(session->context,
446 session, msg->param2, msg->data, (void *)msg->param1);
449 session->channels.push_back(channel);
453 SCARD_DEBUG_ERR("alloc failed");
459 if (msg->isSynchronousCall() == true) /* synchronized call */
465 session->error = msg->error;
466 session->openedChannel = channel;
468 session->signalCondition();
469 session->syncUnlock();
471 else if (msg->callback != NULL)
473 openChannelCallback cb = (openChannelCallback)msg->callback;
476 cb(channel, msg->error, msg->userParam);
481 case Message::MSG_REQUEST_GET_ATR :
483 SCARD_DEBUG("MSG_REQUEST_GET_ATR");
485 if (msg->isSynchronousCall() == true) /* synchronized call */
490 session->error = msg->error;
491 session->atr = msg->data;
493 session->signalCondition();
494 session->syncUnlock();
496 else if (msg->callback != NULL)
498 getATRCallback cb = (getATRCallback)msg->callback;
501 cb(msg->data.getBuffer(), msg->data.getLength(), msg->error, msg->userParam);
506 case Message::MSG_REQUEST_CLOSE_SESSION :
508 SCARD_DEBUG("MSG_REQUEST_CLOSE_SESSION");
510 if (msg->isSynchronousCall() == true) /* synchronized call */
515 session->error = msg->error;
517 session->signalCondition();
518 session->syncUnlock();
520 else if (msg->callback != NULL)
522 closeSessionCallback cb = (closeSessionCallback)msg->callback;
525 cb(msg->error, msg->userParam);
530 case Message::MSG_REQUEST_GET_CHANNEL_COUNT :
532 SCARD_DEBUG("MSG_REQUEST_GET_CHANNEL_COUNT");
534 if (msg->isSynchronousCall() == true) /* synchronized call */
539 session->error = msg->error;
540 session->channelCount = msg->param1;
542 session->signalCondition();
543 session->syncUnlock();
545 else if (msg->callback != NULL)
547 getChannelCountCallback cb = (getChannelCountCallback)msg->callback;
550 cb(msg->param1, msg->error, msg->userParam);
556 SCARD_DEBUG("unknown message : %s", msg->toString());
562 } /* namespace smartcard_service_api */
565 #define SESSION_EXTERN_BEGIN \
566 if (handle != NULL) \
568 Session *session = (Session *)handle;
570 #define SESSION_EXTERN_END \
574 SCARD_DEBUG_ERR("Invalid param"); \
577 using namespace smartcard_service_api;
579 EXTERN_API reader_h session_get_reader(session_h handle)
581 reader_h reader = NULL;
583 SESSION_EXTERN_BEGIN;
584 reader = session->getReader();
590 EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
594 SESSION_EXTERN_BEGIN;
595 result = session->getATR((getATRCallback)callback, userData);
601 EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
605 SESSION_EXTERN_BEGIN;
606 result = session->close((closeSessionCallback)callback, userData);
612 EXTERN_API bool session_is_closed(session_h handle)
616 SESSION_EXTERN_BEGIN;
617 result = session->isClosed();
623 EXTERN_API void session_close_channels(session_h handle)
625 SESSION_EXTERN_BEGIN;
626 session->closeChannels();
630 EXTERN_API int session_open_basic_channel(session_h handle, unsigned char *aid,
631 unsigned int length, session_open_channel_cb callback, void *userData)
635 SESSION_EXTERN_BEGIN;
636 result = session->openBasicChannel(aid, length, (openChannelCallback)callback, userData);
642 EXTERN_API int session_open_logical_channel(session_h handle, unsigned char *aid,
643 unsigned int length, session_open_channel_cb callback, void *userData)
647 SESSION_EXTERN_BEGIN;
648 result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
654 EXTERN_API int session_get_channel_count(session_h handle, session_get_channel_count_cb callback, void * userData)
658 SESSION_EXTERN_BEGIN;
659 result = session->getChannelCount((getChannelCountCallback)callback, userData);
665 EXTERN_API void session_destroy_instance(session_h handle)
669 EXTERN_API int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length)
674 #ifdef CLIENT_IPC_THREAD
675 if (buffer == NULL || length == NULL)
678 SESSION_EXTERN_BEGIN;
679 temp = session->getATRSync();
680 if (temp.getLength() > 0)
682 *length = temp.getLength();
683 *buffer = (unsigned char *)calloc(1, *length);
684 memcpy(*buffer, temp.getBuffer(), *length);
694 EXTERN_API void session_close_sync(session_h handle)
696 #ifdef CLIENT_IPC_THREAD
697 SESSION_EXTERN_BEGIN;
698 session->closeSync();
703 EXTERN_API channel_h session_open_basic_channel_sync(session_h handle, unsigned char *aid, unsigned int length)
705 channel_h result = NULL;
707 #ifdef CLIENT_IPC_THREAD
708 SESSION_EXTERN_BEGIN;
709 result = session->openBasicChannelSync(aid, length);
716 EXTERN_API channel_h session_open_logical_channel_sync(session_h handle, unsigned char *aid, unsigned int length)
718 channel_h result = NULL;
720 #ifdef CLIENT_IPC_THREAD
721 SESSION_EXTERN_BEGIN;
722 result = session->openLogicalChannelSync(aid, length);
729 EXTERN_API unsigned int session_get_channel_count_sync(session_h handle)
731 unsigned int result = 0;
733 #ifdef CLIENT_IPC_THREAD
734 SESSION_EXTERN_BEGIN;
735 result = session->getChannelCountSync();