2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
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.
18 /* standard library header */
24 /* SLP library header */
30 #include "ClientChannel.h"
31 #include "ClientIPC.h"
34 #define EXTERN_API __attribute__((visibility("default")))
37 namespace smartcard_service_api
39 Session::Session(void *context, Reader *reader, void *handle):SessionHelper(reader)
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()
73 for (i = 0; i < channels.size(); i++)
75 channels[i]->closeSync();
79 ByteArray Session::getATRSync()
83 if (getReader()->isSecureElementPresent() == true)
88 #ifdef CLIENT_IPC_THREAD
89 /* request channel handle from server */
90 msg.message = Message::MSG_REQUEST_GET_ATR;
91 msg.param1 = (unsigned int)handle;
92 msg.error = (unsigned int)context; /* using error to context */
93 msg.caller = (void *)this;
94 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
97 if (ClientIPC::getInstance().sendMessage(&msg) == true)
99 rv = waitTimedCondition(0);
102 SCARD_DEBUG_ERR("time over");
107 SCARD_DEBUG_ERR("sendMessage failed");
114 SCARD_DEBUG_ERR("unavailable session");
120 int Session::getATR(getATRCallback callback, void *userData)
124 if (getReader()->isSecureElementPresent() == true)
128 /* request channel handle from server */
129 msg.message = Message::MSG_REQUEST_GET_ATR;
130 msg.param1 = (unsigned int)handle;
131 msg.error = (unsigned int)context; /* using error to context */
132 msg.caller = (void *)this;
133 msg.callback = (void *)callback;
134 msg.userParam = userData;
136 if (ClientIPC::getInstance().sendMessage(&msg) == true)
143 SCARD_DEBUG_ERR("unavailable session");
149 void Session::closeSync()
154 #ifdef CLIENT_IPC_THREAD
155 if (isClosed() == false)
160 /* request channel handle from server */
161 msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
162 msg.param1 = (unsigned int)handle;
163 msg.error = (unsigned int)context; /* using error to context */
164 msg.caller = (void *)this;
165 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
168 if (ClientIPC::getInstance().sendMessage(&msg) == true)
170 rv = waitTimedCondition(0);
174 SCARD_DEBUG_ERR("time over");
179 SCARD_DEBUG_ERR("sendMessage failed");
186 int Session::close(closeSessionCallback callback, void *userData)
191 if (isClosed() == false)
196 /* request channel handle from server */
197 msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
198 msg.param1 = (unsigned int)handle;
199 msg.error = (unsigned int)context; /* using error to context */
200 msg.caller = (void *)this;
201 msg.callback = (void *)callback;
202 msg.userParam = userData;
204 if (ClientIPC::getInstance().sendMessage(&msg) == true)
213 unsigned int Session::getChannelCountSync()
217 if (getReader()->isSecureElementPresent() == true)
222 #ifdef CLIENT_IPC_THREAD
223 /* request channel handle from server */
224 msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
225 msg.param1 = (unsigned int)handle;
226 msg.error = (unsigned int)context; /* using error to context */
227 msg.caller = (void *)this;
228 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
233 if (ClientIPC::getInstance().sendMessage(&msg) == true)
235 rv = waitTimedCondition(0);
238 SCARD_DEBUG_ERR("time over");
243 SCARD_DEBUG_ERR("sendMessage failed");
250 SCARD_DEBUG_ERR("unavailable session");
256 int Session::getChannelCount(getChannelCountCallback callback, void *userData)
260 if (getReader()->isSecureElementPresent() == true)
264 msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
265 msg.param1 = (unsigned int)handle;
266 msg.error = (unsigned int)context; /* using error to context */
267 msg.caller = (void *)this;
268 msg.callback = (void *)callback;
269 msg.userParam = userData;
271 if (ClientIPC::getInstance().sendMessage(&msg) == true)
278 SCARD_DEBUG_ERR("unavailable session");
284 Channel *Session::openChannelSync(int id, ByteArray aid)
286 openedChannel = NULL;
288 if (getReader()->isSecureElementPresent() == true)
293 #ifdef CLIENT_IPC_THREAD
294 /* request channel handle from server */
295 msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
297 msg.param2 = (unsigned int)handle;
299 msg.error = (unsigned int)context; /* using error to context */
300 msg.caller = (void *)this;
301 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
304 if (ClientIPC::getInstance().sendMessage(&msg) == true)
306 rv = waitTimedCondition(0);
309 SCARD_DEBUG_ERR("time over");
314 SCARD_DEBUG_ERR("sendMessage failed");
321 SCARD_DEBUG_ERR("unavailable session");
324 return (Channel *)openedChannel;
327 int Session::openChannel(int id, ByteArray aid, openChannelCallback callback, void *userData)
331 if (getReader()->isSecureElementPresent() == true)
335 /* request channel handle from server */
336 msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
338 msg.param2 = (unsigned int)handle;
340 msg.error = (unsigned int)context; /* using error to context */
341 msg.caller = (void *)this;
342 msg.callback = (void *)callback;
343 msg.userParam = userData;
345 if (ClientIPC::getInstance().sendMessage(&msg) == true)
352 SCARD_DEBUG_ERR("unavailable session");
358 Channel *Session::openBasicChannelSync(ByteArray aid)
360 return openChannelSync(0, aid);
363 Channel *Session::openBasicChannelSync(unsigned char *aid, unsigned int length)
365 return openBasicChannelSync(ByteArray(aid, length));
368 int Session::openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData)
370 return openChannel(0, aid, callback, userData);
373 int Session::openBasicChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData)
375 return openBasicChannel(ByteArray(aid, length), callback, userData);
378 Channel *Session::openLogicalChannelSync(ByteArray aid)
380 return openChannelSync(1, aid);
383 Channel *Session::openLogicalChannelSync(unsigned char *aid, unsigned int length)
385 return openLogicalChannelSync(ByteArray(aid, length));
388 int Session::openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData)
390 return openChannel(1, aid, callback, userData);
393 int Session::openLogicalChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData)
395 return openLogicalChannel(ByteArray(aid, length), callback, userData);
398 bool Session::dispatcherCallback(void *message)
400 Message *msg = (Message *)message;
401 Session *session = NULL;
406 SCARD_DEBUG_ERR("message is null");
410 session = (Session *)msg->caller;
412 switch (msg->message)
414 case Message::MSG_REQUEST_OPEN_CHANNEL :
416 Channel *channel = NULL;
418 SCARD_DEBUG("MSG_REQUEST_OPEN_CHANNEL");
420 if (msg->param1 != 0)
422 /* create new instance of channel */
423 channel = new ClientChannel(session->context, session, msg->param2, msg->data, (void *)msg->param1);
426 session->channels.push_back(channel);
430 SCARD_DEBUG_ERR("alloc failed");
436 if (msg->isSynchronousCall() == true) /* synchronized call */
442 session->error = msg->error;
443 session->openedChannel = channel;
445 session->signalCondition();
446 session->syncUnlock();
448 else if (msg->callback != NULL)
450 openChannelCallback cb = (openChannelCallback)msg->callback;
453 cb(channel, msg->error, msg->userParam);
458 case Message::MSG_REQUEST_GET_ATR :
460 SCARD_DEBUG("MSG_REQUEST_GET_ATR");
462 if (msg->isSynchronousCall() == true) /* synchronized call */
467 session->error = msg->error;
468 session->atr = msg->data;
470 session->signalCondition();
471 session->syncUnlock();
473 else if (msg->callback != NULL)
475 getATRCallback cb = (getATRCallback)msg->callback;
478 cb(msg->data.getBuffer(), msg->data.getLength(), msg->error, msg->userParam);
483 case Message::MSG_REQUEST_CLOSE_SESSION :
485 SCARD_DEBUG("MSG_REQUEST_CLOSE_SESSION");
487 if (msg->isSynchronousCall() == true) /* synchronized call */
492 session->error = msg->error;
494 session->signalCondition();
495 session->syncUnlock();
497 else if (msg->callback != NULL)
499 closeSessionCallback cb = (closeSessionCallback)msg->callback;
502 cb(msg->error, msg->userParam);
507 case Message::MSG_REQUEST_GET_CHANNEL_COUNT :
509 SCARD_DEBUG("MSG_REQUEST_GET_CHANNEL_COUNT");
511 if (msg->isSynchronousCall() == true) /* synchronized call */
516 session->error = msg->error;
517 session->channelCount = msg->param1;
519 session->signalCondition();
520 session->syncUnlock();
522 else if (msg->callback != NULL)
524 getChannelCountCallback cb = (getChannelCountCallback)msg->callback;
527 cb(msg->param1, msg->error, msg->userParam);
533 SCARD_DEBUG("unknown message : %s", msg->toString());
539 } /* namespace smartcard_service_api */
542 #define SESSION_EXTERN_BEGIN \
543 if (handle != NULL) \
545 Session *session = (Session *)handle;
547 #define SESSION_EXTERN_END \
551 SCARD_DEBUG_ERR("Invalid param"); \
554 using namespace smartcard_service_api;
556 EXTERN_API reader_h session_get_reader(session_h handle)
558 reader_h reader = NULL;
560 SESSION_EXTERN_BEGIN;
561 reader = session->getReader();
567 EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
571 SESSION_EXTERN_BEGIN;
572 result = session->getATR((getATRCallback)callback, userData);
578 EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
582 SESSION_EXTERN_BEGIN;
583 result = session->close((closeSessionCallback)callback, userData);
589 EXTERN_API bool session_is_closed(session_h handle)
593 SESSION_EXTERN_BEGIN;
594 result = session->isClosed();
600 EXTERN_API void session_close_channels(session_h handle)
602 SESSION_EXTERN_BEGIN;
603 session->closeChannels();
607 EXTERN_API int session_open_basic_channel(session_h handle, unsigned char *aid, unsigned int length, session_open_channel_cb callback, void *userData)
611 SESSION_EXTERN_BEGIN;
612 result = session->openBasicChannel(aid, length, (openChannelCallback)callback, userData);
618 EXTERN_API int session_open_logical_channel(session_h handle, unsigned char *aid, unsigned int length, session_open_channel_cb callback, void *userData)
622 SESSION_EXTERN_BEGIN;
623 result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
629 EXTERN_API int session_get_channel_count(session_h handle, session_get_channel_count_cb callback, void * userData)
633 SESSION_EXTERN_BEGIN;
634 result = session->getChannelCount((getChannelCountCallback)callback, userData);
640 EXTERN_API void session_destroy_instance(session_h handle)
642 SESSION_EXTERN_BEGIN;
647 EXTERN_API int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length)
652 #ifdef CLIENT_IPC_THREAD
653 if (buffer == NULL || length == NULL)
656 SESSION_EXTERN_BEGIN;
657 temp = session->getATRSync();
658 if (temp.getLength() > 0)
660 *length = temp.getLength();
661 *buffer = (unsigned char *)calloc(1, *length);
662 memcpy(*buffer, temp.getBuffer(), *length);
672 EXTERN_API void session_close_sync(session_h handle)
674 #ifdef CLIENT_IPC_THREAD
675 SESSION_EXTERN_BEGIN;
676 session->closeSync();
681 EXTERN_API channel_h session_open_basic_channel_sync(session_h handle, unsigned char *aid, unsigned int length)
683 channel_h result = NULL;
685 #ifdef CLIENT_IPC_THREAD
686 SESSION_EXTERN_BEGIN;
687 result = session->openBasicChannelSync(aid, length);
694 EXTERN_API channel_h session_open_logical_channel_sync(session_h handle, unsigned char *aid, unsigned int length)
696 channel_h result = NULL;
698 #ifdef CLIENT_IPC_THREAD
699 SESSION_EXTERN_BEGIN;
700 result = session->openLogicalChannelSync(aid, length);
707 EXTERN_API unsigned int session_get_channel_count_sync(session_h handle)
709 unsigned int result = 0;
711 #ifdef CLIENT_IPC_THREAD
712 SESSION_EXTERN_BEGIN;
713 result = session->getChannelCountSync();