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()
78 #ifdef CLIENT_IPC_THREAD
79 /* request channel handle from server */
80 msg.message = Message::MSG_REQUEST_GET_ATR;
81 msg.param1 = (unsigned int)handle;
82 msg.error = (unsigned int)context; /* using error to context */
83 msg.caller = (void *)this;
84 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
86 ClientIPC::getInstance().sendMessage(&msg);
89 rv = waitTimedCondition(0);
94 SCARD_DEBUG_ERR("time over");
103 int Session::getATR(getATRCallback callback, void *userData)
107 /* request channel handle from server */
108 msg.message = Message::MSG_REQUEST_GET_ATR;
109 msg.param1 = (unsigned int)handle;
110 msg.error = (unsigned int)context; /* using error to context */
111 msg.caller = (void *)this;
112 msg.callback = (void *)callback;
113 msg.userParam = userData;
115 ClientIPC::getInstance().sendMessage(&msg);
120 void Session::closeSync()
125 #ifdef CLIENT_IPC_THREAD
126 if (isClosed() == false)
131 /* request channel handle from server */
132 msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
133 msg.param1 = (unsigned int)handle;
134 msg.error = (unsigned int)context; /* using error to context */
135 msg.caller = (void *)this;
136 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
138 ClientIPC::getInstance().sendMessage(&msg);
141 rv = waitTimedCondition(0);
146 SCARD_DEBUG_ERR("time over");
152 int Session::close(closeSessionCallback callback, void *userData)
156 if (isClosed() == false)
161 /* request channel handle from server */
162 msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
163 msg.param1 = (unsigned int)handle;
164 msg.error = (unsigned int)context; /* using error to context */
165 msg.caller = (void *)this;
166 msg.callback = (void *)callback;
167 msg.userParam = userData;
169 ClientIPC::getInstance().sendMessage(&msg);
175 unsigned int Session::getChannelCountSync()
180 #ifdef CLIENT_IPC_THREAD
181 /* request channel handle from server */
182 msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
183 msg.param1 = (unsigned int)handle;
184 msg.error = (unsigned int)context; /* using error to context */
185 msg.caller = (void *)this;
186 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
188 ClientIPC::getInstance().sendMessage(&msg);
191 rv = waitTimedCondition(0);
196 SCARD_DEBUG_ERR("time over");
205 int Session::getChannelCount(getChannelCountCallback callback, void *userData)
209 msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
210 msg.param1 = (unsigned int)handle;
211 msg.error = (unsigned int)context; /* using error to context */
212 msg.caller = (void *)this;
213 msg.callback = (void *)callback;
214 msg.userParam = userData;
216 ClientIPC::getInstance().sendMessage(&msg);
221 Channel *Session::openChannelSync(int id, ByteArray aid)
226 #ifdef CLIENT_IPC_THREAD
227 /* request channel handle from server */
228 msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
230 msg.param2 = (unsigned int)handle;
232 msg.error = (unsigned int)context; /* using error to context */
233 msg.caller = (void *)this;
234 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
236 ClientIPC::getInstance().sendMessage(&msg);
239 rv = waitTimedCondition(0);
244 SCARD_DEBUG_ERR("time over");
246 openedChannel = NULL;
250 return (Channel *)openedChannel;
253 int Session::openChannel(int id, ByteArray aid, openChannelCallback callback, void *userData)
257 /* request channel handle from server */
258 msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
260 msg.param2 = (unsigned int)handle;
262 msg.error = (unsigned int)context; /* using error to context */
263 msg.caller = (void *)this;
264 msg.callback = (void *)callback;
265 msg.userParam = userData;
267 ClientIPC::getInstance().sendMessage(&msg);
272 Channel *Session::openBasicChannelSync(ByteArray aid)
274 return openChannelSync(0, aid);
277 Channel *Session::openBasicChannelSync(unsigned char *aid, unsigned int length)
279 return openBasicChannelSync(ByteArray(aid, length));
282 int Session::openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData)
284 return openChannel(0, aid, callback, userData);
287 int Session::openBasicChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData)
289 return openBasicChannel(ByteArray(aid, length), callback, userData);
292 Channel *Session::openLogicalChannelSync(ByteArray aid)
294 return openChannelSync(1, aid);
297 Channel *Session::openLogicalChannelSync(unsigned char *aid, unsigned int length)
299 return openLogicalChannelSync(ByteArray(aid, length));
302 int Session::openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData)
304 return openChannel(1, aid, callback, userData);
307 int Session::openLogicalChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData)
309 return openLogicalChannel(ByteArray(aid, length), callback, userData);
312 bool Session::dispatcherCallback(void *message)
314 Message *msg = (Message *)message;
315 Session *session = NULL;
320 SCARD_DEBUG_ERR("message is null");
324 session = (Session *)msg->caller;
326 switch (msg->message)
328 case Message::MSG_REQUEST_OPEN_CHANNEL :
330 Channel *channel = NULL;
332 SCARD_DEBUG("MSG_REQUEST_OPEN_CHANNEL");
334 if (msg->param1 != 0)
336 /* create new instance of channel */
337 channel = new ClientChannel(session->context, session, msg->param2, msg->data, (void *)msg->param1);
340 session->channels.push_back(channel);
344 SCARD_DEBUG_ERR("alloc failed");
350 if (msg->callback == (void *)session) /* synchronized call */
356 session->error = msg->error;
357 session->openedChannel = channel;
359 session->signalCondition();
360 session->syncUnlock();
362 else if (msg->callback != NULL)
364 openChannelCallback cb = (openChannelCallback)msg->callback;
367 cb(channel, msg->error, msg->userParam);
372 case Message::MSG_REQUEST_GET_ATR :
374 SCARD_DEBUG("MSG_REQUEST_GET_ATR");
376 if (msg->callback == (void *)session) /* synchronized call */
381 session->error = msg->error;
382 session->atr = msg->data;
384 session->signalCondition();
385 session->syncUnlock();
387 else if (msg->callback != NULL)
389 getATRCallback cb = (getATRCallback)msg->callback;
392 cb(msg->data.getBuffer(), msg->data.getLength(), msg->error, msg->userParam);
397 case Message::MSG_REQUEST_CLOSE_SESSION :
399 SCARD_DEBUG("MSG_REQUEST_CLOSE_SESSION");
401 if (msg->callback == (void *)session) /* synchronized call */
406 session->error = msg->error;
408 session->signalCondition();
409 session->syncUnlock();
411 else if (msg->callback != NULL)
413 closeSessionCallback cb = (closeSessionCallback)msg->callback;
416 cb(msg->error, msg->userParam);
421 case Message::MSG_REQUEST_GET_CHANNEL_COUNT :
423 SCARD_DEBUG("MSG_REQUEST_GET_CHANNEL_COUNT");
425 if (msg->callback == (void *)session) /* synchronized call */
430 session->error = msg->error;
431 session->channelCount = msg->param1;
433 session->signalCondition();
434 session->syncUnlock();
436 else if (msg->callback != NULL)
438 getChannelCountCallback cb = (getChannelCountCallback)msg->callback;
441 cb(msg->param1, msg->error, msg->userParam);
447 SCARD_DEBUG("unknown message : %s", msg->toString());
455 } /* namespace smartcard_service_api */
458 #define SESSION_EXTERN_BEGIN \
459 if (handle != NULL) \
461 Session *session = (Session *)handle;
463 #define SESSION_EXTERN_END \
467 SCARD_DEBUG_ERR("Invalid param"); \
470 using namespace smartcard_service_api;
472 EXTERN_API reader_h session_get_reader(session_h handle)
474 reader_h reader = NULL;
476 SESSION_EXTERN_BEGIN;
477 reader = session->getReader();
483 EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
487 SESSION_EXTERN_BEGIN;
488 result = session->getATR((getATRCallback)callback, userData);
494 EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
498 SESSION_EXTERN_BEGIN;
499 result = session->close((closeSessionCallback)callback, userData);
505 EXTERN_API bool session_is_closed(session_h handle)
509 SESSION_EXTERN_BEGIN;
510 result = session->isClosed();
516 EXTERN_API void session_close_channels(session_h handle)
518 SESSION_EXTERN_BEGIN;
519 session->closeChannels();
523 EXTERN_API int session_open_basic_channel(session_h handle, unsigned char *aid, unsigned int length, session_open_channel_cb callback, void *userData)
527 SESSION_EXTERN_BEGIN;
528 result = session->openBasicChannel(aid, length, (openChannelCallback)callback, userData);
534 EXTERN_API int session_open_logical_channel(session_h handle, unsigned char *aid, unsigned int length, session_open_channel_cb callback, void *userData)
538 SESSION_EXTERN_BEGIN;
539 result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
545 EXTERN_API int session_get_channel_count(session_h handle, session_get_channel_count_cb callback, void * userData)
549 SESSION_EXTERN_BEGIN;
550 result = session->getChannelCount((getChannelCountCallback)callback, userData);
556 EXTERN_API void session_destroy_instance(session_h handle)
558 SESSION_EXTERN_BEGIN;
563 EXTERN_API int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length)
568 #ifdef CLIENT_IPC_THREAD
569 if (buffer == NULL || length == NULL)
572 SESSION_EXTERN_BEGIN;
573 temp = session->getATRSync();
574 if (temp.getLength() > 0)
576 *length = temp.getLength();
577 *buffer = (unsigned char *)calloc(1, *length);
578 memcpy(*buffer, temp.getBuffer(), *length);
588 EXTERN_API void session_close_sync(session_h handle)
590 #ifdef CLIENT_IPC_THREAD
591 SESSION_EXTERN_BEGIN;
592 session->closeSync();
597 EXTERN_API channel_h session_open_basic_channel_sync(session_h handle, unsigned char *aid, unsigned int length)
599 channel_h result = NULL;
601 #ifdef CLIENT_IPC_THREAD
602 SESSION_EXTERN_BEGIN;
603 result = session->openBasicChannelSync(aid, length);
610 EXTERN_API channel_h session_open_logical_channel_sync(session_h handle, unsigned char *aid, unsigned int length)
612 channel_h result = NULL;
614 #ifdef CLIENT_IPC_THREAD
615 SESSION_EXTERN_BEGIN;
616 result = session->openBasicChannelSync(aid, length);
623 EXTERN_API unsigned int session_get_channel_count_sync(session_h handle)
625 unsigned int result = 0;
627 #ifdef CLIENT_IPC_THREAD
628 SESSION_EXTERN_BEGIN;
629 result = session->getChannelCountSync();