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 */
90 ClientIPC::getInstance().sendMessage(&msg);
93 rv = waitTimedCondition(0);
98 SCARD_DEBUG_ERR("time over");
104 SCARD_DEBUG_ERR("unavailable session");
110 int Session::getATR(getATRCallback callback, void *userData)
114 if (getReader()->isSecureElementPresent() == true)
118 /* request channel handle from server */
119 msg.message = Message::MSG_REQUEST_GET_ATR;
120 msg.param1 = (unsigned int)handle;
121 msg.error = (unsigned int)context; /* using error to context */
122 msg.caller = (void *)this;
123 msg.callback = (void *)callback;
124 msg.userParam = userData;
126 ClientIPC::getInstance().sendMessage(&msg);
132 SCARD_DEBUG_ERR("unavailable session");
138 void Session::closeSync()
143 #ifdef CLIENT_IPC_THREAD
144 if (isClosed() == false)
149 /* request channel handle from server */
150 msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
151 msg.param1 = (unsigned int)handle;
152 msg.error = (unsigned int)context; /* using error to context */
153 msg.caller = (void *)this;
154 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
156 ClientIPC::getInstance().sendMessage(&msg);
159 rv = waitTimedCondition(0);
164 SCARD_DEBUG_ERR("time over");
170 int Session::close(closeSessionCallback callback, void *userData)
174 if (isClosed() == false)
179 /* request channel handle from server */
180 msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
181 msg.param1 = (unsigned int)handle;
182 msg.error = (unsigned int)context; /* using error to context */
183 msg.caller = (void *)this;
184 msg.callback = (void *)callback;
185 msg.userParam = userData;
187 ClientIPC::getInstance().sendMessage(&msg);
193 unsigned int Session::getChannelCountSync()
197 if (getReader()->isSecureElementPresent() == true)
202 #ifdef CLIENT_IPC_THREAD
203 /* request channel handle from server */
204 msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
205 msg.param1 = (unsigned int)handle;
206 msg.error = (unsigned int)context; /* using error to context */
207 msg.caller = (void *)this;
208 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
210 ClientIPC::getInstance().sendMessage(&msg);
213 rv = waitTimedCondition(0);
218 SCARD_DEBUG_ERR("time over");
226 SCARD_DEBUG_ERR("unavailable session");
232 int Session::getChannelCount(getChannelCountCallback callback, void *userData)
236 if (getReader()->isSecureElementPresent() == true)
240 msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
241 msg.param1 = (unsigned int)handle;
242 msg.error = (unsigned int)context; /* using error to context */
243 msg.caller = (void *)this;
244 msg.callback = (void *)callback;
245 msg.userParam = userData;
247 ClientIPC::getInstance().sendMessage(&msg);
253 SCARD_DEBUG_ERR("unavailable session");
259 Channel *Session::openChannelSync(int id, ByteArray aid)
261 openedChannel = NULL;
263 if (getReader()->isSecureElementPresent() == true)
268 #ifdef CLIENT_IPC_THREAD
269 /* request channel handle from server */
270 msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
272 msg.param2 = (unsigned int)handle;
274 msg.error = (unsigned int)context; /* using error to context */
275 msg.caller = (void *)this;
276 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
278 ClientIPC::getInstance().sendMessage(&msg);
281 rv = waitTimedCondition(0);
286 SCARD_DEBUG_ERR("time over");
292 SCARD_DEBUG_ERR("unavailable session");
295 return (Channel *)openedChannel;
298 int Session::openChannel(int id, ByteArray aid, openChannelCallback callback, void *userData)
302 if (getReader()->isSecureElementPresent() == true)
306 /* request channel handle from server */
307 msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
309 msg.param2 = (unsigned int)handle;
311 msg.error = (unsigned int)context; /* using error to context */
312 msg.caller = (void *)this;
313 msg.callback = (void *)callback;
314 msg.userParam = userData;
316 ClientIPC::getInstance().sendMessage(&msg);
322 SCARD_DEBUG_ERR("unavailable session");
328 Channel *Session::openBasicChannelSync(ByteArray aid)
330 return openChannelSync(0, aid);
333 Channel *Session::openBasicChannelSync(unsigned char *aid, unsigned int length)
335 return openBasicChannelSync(ByteArray(aid, length));
338 int Session::openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData)
340 return openChannel(0, aid, callback, userData);
343 int Session::openBasicChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData)
345 return openBasicChannel(ByteArray(aid, length), callback, userData);
348 Channel *Session::openLogicalChannelSync(ByteArray aid)
350 return openChannelSync(1, aid);
353 Channel *Session::openLogicalChannelSync(unsigned char *aid, unsigned int length)
355 return openLogicalChannelSync(ByteArray(aid, length));
358 int Session::openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData)
360 return openChannel(1, aid, callback, userData);
363 int Session::openLogicalChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData)
365 return openLogicalChannel(ByteArray(aid, length), callback, userData);
368 bool Session::dispatcherCallback(void *message)
370 Message *msg = (Message *)message;
371 Session *session = NULL;
376 SCARD_DEBUG_ERR("message is null");
380 session = (Session *)msg->caller;
382 switch (msg->message)
384 case Message::MSG_REQUEST_OPEN_CHANNEL :
386 Channel *channel = NULL;
388 SCARD_DEBUG("MSG_REQUEST_OPEN_CHANNEL");
390 if (msg->param1 != 0)
392 /* create new instance of channel */
393 channel = new ClientChannel(session->context, session, msg->param2, msg->data, (void *)msg->param1);
396 session->channels.push_back(channel);
400 SCARD_DEBUG_ERR("alloc failed");
406 if (msg->isSynchronousCall() == true) /* synchronized call */
412 session->error = msg->error;
413 session->openedChannel = channel;
415 session->signalCondition();
416 session->syncUnlock();
418 else if (msg->callback != NULL)
420 openChannelCallback cb = (openChannelCallback)msg->callback;
423 cb(channel, msg->error, msg->userParam);
428 case Message::MSG_REQUEST_GET_ATR :
430 SCARD_DEBUG("MSG_REQUEST_GET_ATR");
432 if (msg->isSynchronousCall() == true) /* synchronized call */
437 session->error = msg->error;
438 session->atr = msg->data;
440 session->signalCondition();
441 session->syncUnlock();
443 else if (msg->callback != NULL)
445 getATRCallback cb = (getATRCallback)msg->callback;
448 cb(msg->data.getBuffer(), msg->data.getLength(), msg->error, msg->userParam);
453 case Message::MSG_REQUEST_CLOSE_SESSION :
455 SCARD_DEBUG("MSG_REQUEST_CLOSE_SESSION");
457 if (msg->isSynchronousCall() == true) /* synchronized call */
462 session->error = msg->error;
464 session->signalCondition();
465 session->syncUnlock();
467 else if (msg->callback != NULL)
469 closeSessionCallback cb = (closeSessionCallback)msg->callback;
472 cb(msg->error, msg->userParam);
477 case Message::MSG_REQUEST_GET_CHANNEL_COUNT :
479 SCARD_DEBUG("MSG_REQUEST_GET_CHANNEL_COUNT");
481 if (msg->isSynchronousCall() == true) /* synchronized call */
486 session->error = msg->error;
487 session->channelCount = msg->param1;
489 session->signalCondition();
490 session->syncUnlock();
492 else if (msg->callback != NULL)
494 getChannelCountCallback cb = (getChannelCountCallback)msg->callback;
497 cb(msg->param1, msg->error, msg->userParam);
503 SCARD_DEBUG("unknown message : %s", msg->toString());
511 } /* namespace smartcard_service_api */
514 #define SESSION_EXTERN_BEGIN \
515 if (handle != NULL) \
517 Session *session = (Session *)handle;
519 #define SESSION_EXTERN_END \
523 SCARD_DEBUG_ERR("Invalid param"); \
526 using namespace smartcard_service_api;
528 EXTERN_API reader_h session_get_reader(session_h handle)
530 reader_h reader = NULL;
532 SESSION_EXTERN_BEGIN;
533 reader = session->getReader();
539 EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
543 SESSION_EXTERN_BEGIN;
544 result = session->getATR((getATRCallback)callback, userData);
550 EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
554 SESSION_EXTERN_BEGIN;
555 result = session->close((closeSessionCallback)callback, userData);
561 EXTERN_API bool session_is_closed(session_h handle)
565 SESSION_EXTERN_BEGIN;
566 result = session->isClosed();
572 EXTERN_API void session_close_channels(session_h handle)
574 SESSION_EXTERN_BEGIN;
575 session->closeChannels();
579 EXTERN_API int session_open_basic_channel(session_h handle, unsigned char *aid, unsigned int length, session_open_channel_cb callback, void *userData)
583 SESSION_EXTERN_BEGIN;
584 result = session->openBasicChannel(aid, length, (openChannelCallback)callback, userData);
590 EXTERN_API int session_open_logical_channel(session_h handle, unsigned char *aid, unsigned int length, session_open_channel_cb callback, void *userData)
594 SESSION_EXTERN_BEGIN;
595 result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
601 EXTERN_API int session_get_channel_count(session_h handle, session_get_channel_count_cb callback, void * userData)
605 SESSION_EXTERN_BEGIN;
606 result = session->getChannelCount((getChannelCountCallback)callback, userData);
612 EXTERN_API void session_destroy_instance(session_h handle)
614 SESSION_EXTERN_BEGIN;
619 EXTERN_API int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length)
624 #ifdef CLIENT_IPC_THREAD
625 if (buffer == NULL || length == NULL)
628 SESSION_EXTERN_BEGIN;
629 temp = session->getATRSync();
630 if (temp.getLength() > 0)
632 *length = temp.getLength();
633 *buffer = (unsigned char *)calloc(1, *length);
634 memcpy(*buffer, temp.getBuffer(), *length);
644 EXTERN_API void session_close_sync(session_h handle)
646 #ifdef CLIENT_IPC_THREAD
647 SESSION_EXTERN_BEGIN;
648 session->closeSync();
653 EXTERN_API channel_h session_open_basic_channel_sync(session_h handle, unsigned char *aid, unsigned int length)
655 channel_h result = NULL;
657 #ifdef CLIENT_IPC_THREAD
658 SESSION_EXTERN_BEGIN;
659 result = session->openBasicChannelSync(aid, length);
666 EXTERN_API channel_h session_open_logical_channel_sync(session_h handle, unsigned char *aid, unsigned int length)
668 channel_h result = NULL;
670 #ifdef CLIENT_IPC_THREAD
671 SESSION_EXTERN_BEGIN;
672 result = session->openBasicChannelSync(aid, length);
679 EXTERN_API unsigned int session_get_channel_count_sync(session_h handle)
681 unsigned int result = 0;
683 #ifdef CLIENT_IPC_THREAD
684 SESSION_EXTERN_BEGIN;
685 result = session->getChannelCountSync();