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 &)
83 if (getReader()->isSecureElementPresent() == true)
85 if (atr.isEmpty() == true)
90 #ifdef CLIENT_IPC_THREAD
91 /* request channel handle from server */
92 msg.message = Message::MSG_REQUEST_GET_ATR;
93 msg.param1 = (unsigned int)handle;
94 msg.error = (unsigned int)context; /* using error to context */
95 msg.caller = (void *)this;
96 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
99 if (ClientIPC::getInstance().sendMessage(&msg) == true)
101 rv = waitTimedCondition(0);
104 SCARD_DEBUG_ERR("time over");
109 SCARD_DEBUG_ERR("sendMessage failed");
119 SCARD_DEBUG_ERR("unavailable session");
125 int Session::getATR(getATRCallback callback, void *userData)
129 if (getReader()->isSecureElementPresent() == true)
131 if (atr.isEmpty() == true)
135 /* request channel handle from server */
136 msg.message = Message::MSG_REQUEST_GET_ATR;
137 msg.param1 = (unsigned int)handle;
138 msg.error = (unsigned int)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 int)handle;
176 msg.error = (unsigned int)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 int)handle;
212 msg.error = (unsigned int)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)
235 #ifdef CLIENT_IPC_THREAD
236 /* request channel handle from server */
237 msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
238 msg.param1 = (unsigned int)handle;
239 msg.error = (unsigned int)context; /* using error to context */
240 msg.caller = (void *)this;
241 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
246 if (ClientIPC::getInstance().sendMessage(&msg) == true)
248 rv = waitTimedCondition(0);
251 SCARD_DEBUG_ERR("time over");
256 SCARD_DEBUG_ERR("sendMessage failed");
263 SCARD_DEBUG_ERR("unavailable session");
269 int Session::getChannelCount(getChannelCountCallback callback, void *userData)
273 if (getReader()->isSecureElementPresent() == true)
277 msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
278 msg.param1 = (unsigned int)handle;
279 msg.error = (unsigned int)context; /* using error to context */
280 msg.caller = (void *)this;
281 msg.callback = (void *)callback;
282 msg.userParam = userData;
284 if (ClientIPC::getInstance().sendMessage(&msg) == true)
291 SCARD_DEBUG_ERR("unavailable session");
297 Channel *Session::openChannelSync(int id, ByteArray aid)
298 throw (ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
300 openedChannel = NULL;
302 if (getReader()->isSecureElementPresent() == true)
307 #ifdef CLIENT_IPC_THREAD
308 /* request channel handle from server */
309 msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
311 msg.param2 = (unsigned int)handle;
313 msg.error = (unsigned int)context; /* using error to context */
314 msg.caller = (void *)this;
315 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
318 if (ClientIPC::getInstance().sendMessage(&msg) == true)
320 rv = waitTimedCondition(0);
323 SCARD_DEBUG_ERR("time over");
328 SCARD_DEBUG_ERR("sendMessage failed");
335 SCARD_DEBUG_ERR("unavailable session");
338 return (Channel *)openedChannel;
341 int Session::openChannel(int id, ByteArray aid, openChannelCallback callback, void *userData)
345 if (getReader()->isSecureElementPresent() == true)
349 /* request channel handle from server */
350 msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
352 msg.param2 = (unsigned int)handle;
354 msg.error = (unsigned int)context; /* using error to context */
355 msg.caller = (void *)this;
356 msg.callback = (void *)callback;
357 msg.userParam = userData;
359 if (ClientIPC::getInstance().sendMessage(&msg) == true)
366 SCARD_DEBUG_ERR("unavailable session");
372 Channel *Session::openBasicChannelSync(ByteArray aid)
373 throw (ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
375 return openChannelSync(0, aid);
378 Channel *Session::openBasicChannelSync(unsigned char *aid, unsigned int length)
379 throw (ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
381 return openBasicChannelSync(ByteArray(aid, length));
384 int Session::openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData)
386 return openChannel(0, aid, callback, userData);
389 int Session::openBasicChannel(unsigned char *aid, unsigned int length,
390 openChannelCallback callback, void *userData)
392 return openBasicChannel(ByteArray(aid, length), callback, userData);
395 Channel *Session::openLogicalChannelSync(ByteArray aid)
396 throw (ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
398 return openChannelSync(1, aid);
401 Channel *Session::openLogicalChannelSync(unsigned char *aid, unsigned int length)
402 throw (ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
404 return openLogicalChannelSync(ByteArray(aid, length));
407 int Session::openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData)
409 return openChannel(1, aid, callback, userData);
412 int Session::openLogicalChannel(unsigned char *aid, unsigned int length,
413 openChannelCallback callback, void *userData)
415 return openLogicalChannel(ByteArray(aid, length), callback, userData);
418 bool Session::dispatcherCallback(void *message)
420 Message *msg = (Message *)message;
421 Session *session = NULL;
426 SCARD_DEBUG_ERR("message is null");
430 session = (Session *)msg->caller;
432 switch (msg->message)
434 case Message::MSG_REQUEST_OPEN_CHANNEL :
436 Channel *channel = NULL;
438 SCARD_DEBUG("MSG_REQUEST_OPEN_CHANNEL");
440 if (msg->param1 != 0)
442 /* create new instance of channel */
443 channel = new ClientChannel(session->context,
444 session, msg->param2, msg->data, (void *)msg->param1);
447 session->channels.push_back(channel);
451 SCARD_DEBUG_ERR("alloc failed");
457 if (msg->isSynchronousCall() == true) /* synchronized call */
463 session->error = msg->error;
464 session->openedChannel = channel;
466 session->signalCondition();
467 session->syncUnlock();
469 else if (msg->callback != NULL)
471 openChannelCallback cb = (openChannelCallback)msg->callback;
474 cb(channel, msg->error, msg->userParam);
479 case Message::MSG_REQUEST_GET_ATR :
481 SCARD_DEBUG("MSG_REQUEST_GET_ATR");
483 if (msg->isSynchronousCall() == true) /* synchronized call */
488 session->error = msg->error;
489 session->atr = msg->data;
491 session->signalCondition();
492 session->syncUnlock();
494 else if (msg->callback != NULL)
496 getATRCallback cb = (getATRCallback)msg->callback;
499 cb(msg->data.getBuffer(), msg->data.getLength(), msg->error, msg->userParam);
504 case Message::MSG_REQUEST_CLOSE_SESSION :
506 SCARD_DEBUG("MSG_REQUEST_CLOSE_SESSION");
508 if (msg->isSynchronousCall() == true) /* synchronized call */
513 session->error = msg->error;
515 session->signalCondition();
516 session->syncUnlock();
518 else if (msg->callback != NULL)
520 closeSessionCallback cb = (closeSessionCallback)msg->callback;
523 cb(msg->error, msg->userParam);
528 case Message::MSG_REQUEST_GET_CHANNEL_COUNT :
530 SCARD_DEBUG("MSG_REQUEST_GET_CHANNEL_COUNT");
532 if (msg->isSynchronousCall() == true) /* synchronized call */
537 session->error = msg->error;
538 session->channelCount = msg->param1;
540 session->signalCondition();
541 session->syncUnlock();
543 else if (msg->callback != NULL)
545 getChannelCountCallback cb = (getChannelCountCallback)msg->callback;
548 cb(msg->param1, msg->error, msg->userParam);
554 SCARD_DEBUG("unknown message : %s", msg->toString());
560 } /* namespace smartcard_service_api */
563 #define SESSION_EXTERN_BEGIN \
564 if (handle != NULL) \
566 Session *session = (Session *)handle;
568 #define SESSION_EXTERN_END \
572 SCARD_DEBUG_ERR("Invalid param"); \
575 using namespace smartcard_service_api;
577 EXTERN_API reader_h session_get_reader(session_h handle)
579 reader_h reader = NULL;
581 SESSION_EXTERN_BEGIN;
582 reader = session->getReader();
588 EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
592 SESSION_EXTERN_BEGIN;
593 result = session->getATR((getATRCallback)callback, userData);
599 EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
603 SESSION_EXTERN_BEGIN;
604 result = session->close((closeSessionCallback)callback, userData);
610 EXTERN_API bool session_is_closed(session_h handle)
614 SESSION_EXTERN_BEGIN;
615 result = session->isClosed();
621 EXTERN_API void session_close_channels(session_h handle)
623 SESSION_EXTERN_BEGIN;
624 session->closeChannels();
628 EXTERN_API int session_open_basic_channel(session_h handle, unsigned char *aid,
629 unsigned int length, session_open_channel_cb callback, void *userData)
633 SESSION_EXTERN_BEGIN;
634 result = session->openBasicChannel(aid, length, (openChannelCallback)callback, userData);
640 EXTERN_API int session_open_logical_channel(session_h handle, unsigned char *aid,
641 unsigned int length, session_open_channel_cb callback, void *userData)
645 SESSION_EXTERN_BEGIN;
646 result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
652 EXTERN_API int session_get_channel_count(session_h handle, session_get_channel_count_cb callback, void * userData)
656 SESSION_EXTERN_BEGIN;
657 result = session->getChannelCount((getChannelCountCallback)callback, userData);
663 EXTERN_API void session_destroy_instance(session_h handle)
667 EXTERN_API int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length)
672 #ifdef CLIENT_IPC_THREAD
673 if (buffer == NULL || length == NULL)
676 SESSION_EXTERN_BEGIN;
677 temp = session->getATRSync();
678 if (temp.getLength() > 0)
680 *length = temp.getLength();
681 *buffer = (unsigned char *)calloc(1, *length);
682 memcpy(*buffer, temp.getBuffer(), *length);
692 EXTERN_API void session_close_sync(session_h handle)
694 #ifdef CLIENT_IPC_THREAD
695 SESSION_EXTERN_BEGIN;
696 session->closeSync();
701 EXTERN_API channel_h session_open_basic_channel_sync(session_h handle, unsigned char *aid, unsigned int length)
703 channel_h result = NULL;
705 #ifdef CLIENT_IPC_THREAD
706 SESSION_EXTERN_BEGIN;
707 result = session->openBasicChannelSync(aid, length);
714 EXTERN_API channel_h session_open_logical_channel_sync(session_h handle, unsigned char *aid, unsigned int length)
716 channel_h result = NULL;
718 #ifdef CLIENT_IPC_THREAD
719 SESSION_EXTERN_BEGIN;
720 result = session->openLogicalChannelSync(aid, length);
727 EXTERN_API unsigned int session_get_channel_count_sync(session_h handle)
729 unsigned int result = 0;
731 #ifdef CLIENT_IPC_THREAD
732 SESSION_EXTERN_BEGIN;
733 result = session->getChannelCountSync();