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.
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;
60 void Session::closeChannels()
64 for (i = 0; i < channels.size(); i++)
66 channels[i]->closeSync();
67 delete (ClientChannel *)channels[i];
73 ByteArray Session::getATRSync()
77 if (getReader()->isSecureElementPresent() == true)
82 #ifdef CLIENT_IPC_THREAD
83 /* request channel handle from server */
84 msg.message = Message::MSG_REQUEST_GET_ATR;
85 msg.param1 = (unsigned int)handle;
86 msg.error = (unsigned int)context; /* using error to context */
87 msg.caller = (void *)this;
88 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
91 if (ClientIPC::getInstance().sendMessage(&msg) == true)
93 rv = waitTimedCondition(0);
96 SCARD_DEBUG_ERR("time over");
101 SCARD_DEBUG_ERR("sendMessage failed");
108 SCARD_DEBUG_ERR("unavailable session");
114 int Session::getATR(getATRCallback callback, void *userData)
118 if (getReader()->isSecureElementPresent() == true)
122 /* request channel handle from server */
123 msg.message = Message::MSG_REQUEST_GET_ATR;
124 msg.param1 = (unsigned int)handle;
125 msg.error = (unsigned int)context; /* using error to context */
126 msg.caller = (void *)this;
127 msg.callback = (void *)callback;
128 msg.userParam = userData;
130 if (ClientIPC::getInstance().sendMessage(&msg) == true)
137 SCARD_DEBUG_ERR("unavailable session");
143 void Session::closeSync()
148 #ifdef CLIENT_IPC_THREAD
149 if (isClosed() == false)
154 /* request channel handle from server */
155 msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
156 msg.param1 = (unsigned int)handle;
157 msg.error = (unsigned int)context; /* using error to context */
158 msg.caller = (void *)this;
159 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
162 if (ClientIPC::getInstance().sendMessage(&msg) == true)
164 rv = waitTimedCondition(0);
168 SCARD_DEBUG_ERR("time over");
173 SCARD_DEBUG_ERR("sendMessage failed");
180 int Session::close(closeSessionCallback callback, void *userData)
185 if (isClosed() == false)
190 /* request channel handle from server */
191 msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
192 msg.param1 = (unsigned int)handle;
193 msg.error = (unsigned int)context; /* using error to context */
194 msg.caller = (void *)this;
195 msg.callback = (void *)callback;
196 msg.userParam = userData;
198 if (ClientIPC::getInstance().sendMessage(&msg) == true)
207 unsigned int Session::getChannelCountSync()
211 if (getReader()->isSecureElementPresent() == true)
216 #ifdef CLIENT_IPC_THREAD
217 /* request channel handle from server */
218 msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
219 msg.param1 = (unsigned int)handle;
220 msg.error = (unsigned int)context; /* using error to context */
221 msg.caller = (void *)this;
222 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
227 if (ClientIPC::getInstance().sendMessage(&msg) == true)
229 rv = waitTimedCondition(0);
232 SCARD_DEBUG_ERR("time over");
237 SCARD_DEBUG_ERR("sendMessage failed");
244 SCARD_DEBUG_ERR("unavailable session");
250 int Session::getChannelCount(getChannelCountCallback callback, void *userData)
254 if (getReader()->isSecureElementPresent() == true)
258 msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
259 msg.param1 = (unsigned int)handle;
260 msg.error = (unsigned int)context; /* using error to context */
261 msg.caller = (void *)this;
262 msg.callback = (void *)callback;
263 msg.userParam = userData;
265 if (ClientIPC::getInstance().sendMessage(&msg) == true)
272 SCARD_DEBUG_ERR("unavailable session");
278 Channel *Session::openChannelSync(int id, ByteArray aid)
280 openedChannel = NULL;
282 if (getReader()->isSecureElementPresent() == true)
287 #ifdef CLIENT_IPC_THREAD
288 /* request channel handle from server */
289 msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
291 msg.param2 = (unsigned int)handle;
293 msg.error = (unsigned int)context; /* using error to context */
294 msg.caller = (void *)this;
295 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
298 if (ClientIPC::getInstance().sendMessage(&msg) == true)
300 rv = waitTimedCondition(0);
303 SCARD_DEBUG_ERR("time over");
308 SCARD_DEBUG_ERR("sendMessage failed");
315 SCARD_DEBUG_ERR("unavailable session");
318 return (Channel *)openedChannel;
321 int Session::openChannel(int id, ByteArray aid, openChannelCallback callback, void *userData)
325 if (getReader()->isSecureElementPresent() == true)
329 /* request channel handle from server */
330 msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
332 msg.param2 = (unsigned int)handle;
334 msg.error = (unsigned int)context; /* using error to context */
335 msg.caller = (void *)this;
336 msg.callback = (void *)callback;
337 msg.userParam = userData;
339 if (ClientIPC::getInstance().sendMessage(&msg) == true)
346 SCARD_DEBUG_ERR("unavailable session");
352 Channel *Session::openBasicChannelSync(ByteArray aid)
354 return openChannelSync(0, aid);
357 Channel *Session::openBasicChannelSync(unsigned char *aid, unsigned int length)
359 return openBasicChannelSync(ByteArray(aid, length));
362 int Session::openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData)
364 return openChannel(0, aid, callback, userData);
367 int Session::openBasicChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData)
369 return openBasicChannel(ByteArray(aid, length), callback, userData);
372 Channel *Session::openLogicalChannelSync(ByteArray aid)
374 return openChannelSync(1, aid);
377 Channel *Session::openLogicalChannelSync(unsigned char *aid, unsigned int length)
379 return openLogicalChannelSync(ByteArray(aid, length));
382 int Session::openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData)
384 return openChannel(1, aid, callback, userData);
387 int Session::openLogicalChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData)
389 return openLogicalChannel(ByteArray(aid, length), callback, userData);
392 bool Session::dispatcherCallback(void *message)
394 Message *msg = (Message *)message;
395 Session *session = NULL;
400 SCARD_DEBUG_ERR("message is null");
404 session = (Session *)msg->caller;
406 switch (msg->message)
408 case Message::MSG_REQUEST_OPEN_CHANNEL :
410 Channel *channel = NULL;
412 SCARD_DEBUG("MSG_REQUEST_OPEN_CHANNEL");
414 if (msg->param1 != 0)
416 /* create new instance of channel */
417 channel = new ClientChannel(session->context, session, msg->param2, msg->data, (void *)msg->param1);
420 session->channels.push_back(channel);
424 SCARD_DEBUG_ERR("alloc failed");
430 if (msg->isSynchronousCall() == true) /* synchronized call */
436 session->error = msg->error;
437 session->openedChannel = channel;
439 session->signalCondition();
440 session->syncUnlock();
442 else if (msg->callback != NULL)
444 openChannelCallback cb = (openChannelCallback)msg->callback;
447 cb(channel, msg->error, msg->userParam);
452 case Message::MSG_REQUEST_GET_ATR :
454 SCARD_DEBUG("MSG_REQUEST_GET_ATR");
456 if (msg->isSynchronousCall() == true) /* synchronized call */
461 session->error = msg->error;
462 session->atr = msg->data;
464 session->signalCondition();
465 session->syncUnlock();
467 else if (msg->callback != NULL)
469 getATRCallback cb = (getATRCallback)msg->callback;
472 cb(msg->data.getBuffer(), msg->data.getLength(), msg->error, msg->userParam);
477 case Message::MSG_REQUEST_CLOSE_SESSION :
479 SCARD_DEBUG("MSG_REQUEST_CLOSE_SESSION");
481 if (msg->isSynchronousCall() == true) /* synchronized call */
486 session->error = msg->error;
488 session->signalCondition();
489 session->syncUnlock();
491 else if (msg->callback != NULL)
493 closeSessionCallback cb = (closeSessionCallback)msg->callback;
496 cb(msg->error, msg->userParam);
501 case Message::MSG_REQUEST_GET_CHANNEL_COUNT :
503 SCARD_DEBUG("MSG_REQUEST_GET_CHANNEL_COUNT");
505 if (msg->isSynchronousCall() == true) /* synchronized call */
510 session->error = msg->error;
511 session->channelCount = msg->param1;
513 session->signalCondition();
514 session->syncUnlock();
516 else if (msg->callback != NULL)
518 getChannelCountCallback cb = (getChannelCountCallback)msg->callback;
521 cb(msg->param1, msg->error, msg->userParam);
527 SCARD_DEBUG("unknown message : %s", msg->toString());
533 } /* namespace smartcard_service_api */
536 #define SESSION_EXTERN_BEGIN \
537 if (handle != NULL) \
539 Session *session = (Session *)handle;
541 #define SESSION_EXTERN_END \
545 SCARD_DEBUG_ERR("Invalid param"); \
548 using namespace smartcard_service_api;
550 EXTERN_API reader_h session_get_reader(session_h handle)
552 reader_h reader = NULL;
554 SESSION_EXTERN_BEGIN;
555 reader = session->getReader();
561 EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
565 SESSION_EXTERN_BEGIN;
566 result = session->getATR((getATRCallback)callback, userData);
572 EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
576 SESSION_EXTERN_BEGIN;
577 result = session->close((closeSessionCallback)callback, userData);
583 EXTERN_API bool session_is_closed(session_h handle)
587 SESSION_EXTERN_BEGIN;
588 result = session->isClosed();
594 EXTERN_API void session_close_channels(session_h handle)
596 SESSION_EXTERN_BEGIN;
597 session->closeChannels();
601 EXTERN_API int session_open_basic_channel(session_h handle, unsigned char *aid, unsigned int length, session_open_channel_cb callback, void *userData)
605 SESSION_EXTERN_BEGIN;
606 result = session->openBasicChannel(aid, length, (openChannelCallback)callback, userData);
612 EXTERN_API int session_open_logical_channel(session_h handle, unsigned char *aid, unsigned int length, session_open_channel_cb callback, void *userData)
616 SESSION_EXTERN_BEGIN;
617 result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
623 EXTERN_API int session_get_channel_count(session_h handle, session_get_channel_count_cb callback, void * userData)
627 SESSION_EXTERN_BEGIN;
628 result = session->getChannelCount((getChannelCountCallback)callback, userData);
634 EXTERN_API void session_destroy_instance(session_h handle)
636 SESSION_EXTERN_BEGIN;
641 EXTERN_API int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length)
646 #ifdef CLIENT_IPC_THREAD
647 if (buffer == NULL || length == NULL)
650 SESSION_EXTERN_BEGIN;
651 temp = session->getATRSync();
652 if (temp.getLength() > 0)
654 *length = temp.getLength();
655 *buffer = (unsigned char *)calloc(1, *length);
656 memcpy(*buffer, temp.getBuffer(), *length);
666 EXTERN_API void session_close_sync(session_h handle)
668 #ifdef CLIENT_IPC_THREAD
669 SESSION_EXTERN_BEGIN;
670 session->closeSync();
675 EXTERN_API channel_h session_open_basic_channel_sync(session_h handle, unsigned char *aid, unsigned int length)
677 channel_h result = NULL;
679 #ifdef CLIENT_IPC_THREAD
680 SESSION_EXTERN_BEGIN;
681 result = session->openBasicChannelSync(aid, length);
688 EXTERN_API channel_h session_open_logical_channel_sync(session_h handle, unsigned char *aid, unsigned int length)
690 channel_h result = NULL;
692 #ifdef CLIENT_IPC_THREAD
693 SESSION_EXTERN_BEGIN;
694 result = session->openLogicalChannelSync(aid, length);
701 EXTERN_API unsigned int session_get_channel_count_sync(session_h handle)
703 unsigned int result = 0;
705 #ifdef CLIENT_IPC_THREAD
706 SESSION_EXTERN_BEGIN;
707 result = session->getChannelCountSync();