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 */
22 /* SLP library header */
28 #include "ClientChannel.h"
29 #include "ClientIPC.h"
32 #define EXTERN_API __attribute__((visibility("default")))
35 namespace smartcard_service_api
37 Session::Session(void *context, Reader *reader, void *handle):SessionHelper(reader)
41 if (context == NULL || handle == NULL)
43 SCARD_DEBUG_ERR("handle is null");
48 this->context = context;
49 this->handle = handle;
58 void Session::closeChannels()
62 for (i = 0; i < channels.size(); i++)
64 channels[i]->close(NULL, this);
70 ByteArray Session::getATRSync()
75 /* request channel handle from server */
76 msg.message = Message::MSG_REQUEST_GET_ATR;
77 msg.param1 = (unsigned int)handle;
78 msg.error = (unsigned int)context; /* using error to context */
79 msg.caller = (void *)this;
80 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
82 ClientIPC::getInstance().sendMessage(&msg);
85 rv = waitTimedCondition(0);
90 SCARD_DEBUG_ERR("time over");
98 int Session::getATR(getATRCallback callback, void *userData)
102 /* request channel handle from server */
103 msg.message = Message::MSG_REQUEST_GET_ATR;
104 msg.param1 = (unsigned int)handle;
105 msg.error = (unsigned int)context; /* using error to context */
106 msg.caller = (void *)this;
107 msg.callback = (void *)callback;
108 msg.userParam = userData;
110 ClientIPC::getInstance().sendMessage(&msg);
115 void Session::closeSync()
120 if (isClosed() == false)
125 /* request channel handle from server */
126 msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
127 msg.param1 = (unsigned int)handle;
128 msg.error = (unsigned int)context; /* using error to context */
129 msg.caller = (void *)this;
130 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
132 ClientIPC::getInstance().sendMessage(&msg);
135 rv = waitTimedCondition(0);
140 SCARD_DEBUG_ERR("time over");
145 int Session::close(closeSessionCallback callback, void *userData)
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 *)callback;
160 msg.userParam = userData;
162 ClientIPC::getInstance().sendMessage(&msg);
168 unsigned int Session::getChannelCount(getChannelCountCallback callback, void *userData)
172 msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
173 msg.param1 = (unsigned int)handle;
174 msg.error = (unsigned int)context; /* using error to context */
175 msg.caller = (void *)this;
176 msg.callback = (void *)callback;
177 msg.userParam = userData;
179 ClientIPC::getInstance().sendMessage(&msg);
184 unsigned int Session::getChannelCountSync()
189 /* request channel handle from server */
190 msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
191 msg.param1 = (unsigned int)handle;
192 msg.error = (unsigned int)context; /* using error to context */
193 msg.caller = (void *)this;
194 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
196 ClientIPC::getInstance().sendMessage(&msg);
199 rv = waitTimedCondition(0);
204 SCARD_DEBUG_ERR("time over");
212 Channel *Session::openChannelSync(int id, ByteArray aid)
217 /* request channel handle from server */
218 msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
220 msg.param2 = (unsigned int)handle;
222 msg.error = (unsigned int)context; /* using error to context */
223 msg.caller = (void *)this;
224 msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
226 ClientIPC::getInstance().sendMessage(&msg);
229 rv = waitTimedCondition(0);
234 SCARD_DEBUG_ERR("time over");
239 return (Channel *)openedChannel;
242 int Session::openChannel(int id, ByteArray aid, openChannelCallback callback, void *userData)
246 /* request channel handle from server */
247 msg.message = Message::MSG_REQUEST_OPEN_CHANNEL;
249 msg.param2 = (unsigned int)handle;
251 msg.error = (unsigned int)context; /* using error to context */
252 msg.caller = (void *)this;
253 msg.callback = (void *)callback;
254 msg.userParam = userData;
256 ClientIPC::getInstance().sendMessage(&msg);
261 Channel *Session::openBasicChannelSync(ByteArray aid)
263 return openChannelSync(0, aid);
266 Channel *Session::openBasicChannelSync(unsigned char *aid, unsigned int length)
268 return openBasicChannelSync(ByteArray(aid, length));
271 int Session::openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData)
273 return openChannel(0, aid, callback, userData);
276 int Session::openBasicChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData)
278 return openBasicChannel(ByteArray(aid, length), callback, userData);
281 Channel *Session::openLogicalChannelSync(ByteArray aid)
283 return openChannelSync(1, aid);
286 Channel *Session::openLogicalChannelSync(unsigned char *aid, unsigned int length)
288 return openLogicalChannelSync(ByteArray(aid, length));
291 int Session::openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData)
293 return openChannel(1, aid, callback, userData);
296 int Session::openLogicalChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData)
298 return openLogicalChannel(ByteArray(aid, length), callback, userData);
301 bool Session::dispatcherCallback(void *message)
303 Message *msg = (Message *)message;
304 Session *session = NULL;
309 SCARD_DEBUG_ERR("message is null");
313 session = (Session *)msg->caller;
315 switch (msg->message)
317 case Message::MSG_REQUEST_OPEN_CHANNEL :
319 Channel *channel = NULL;
321 SCARD_DEBUG("MSG_REQUEST_OPEN_CHANNEL");
323 if (msg->param1 != 0)
325 /* create new instance of channel */
326 channel = new ClientChannel(session->context, session, msg->param2, msg->data, (void *)msg->param1);
329 session->channels.push_back(channel);
333 SCARD_DEBUG_ERR("alloc failed");
339 if (msg->callback == (void *)session) /* synchronized call */
345 session->error = msg->error;
346 session->openedChannel = channel;
348 session->signalCondition();
349 session->syncUnlock();
351 else if (msg->callback != NULL)
353 openChannelCallback cb = (openChannelCallback)msg->callback;
356 cb(channel, msg->error, msg->userParam);
361 case Message::MSG_REQUEST_GET_ATR :
363 SCARD_DEBUG("MSG_REQUEST_GET_ATR");
365 if (msg->callback == (void *)session) /* synchronized call */
370 session->error = msg->error;
371 session->atr = msg->data;
373 session->signalCondition();
374 session->syncUnlock();
376 else if (msg->callback != NULL)
378 getATRCallback cb = (getATRCallback)msg->callback;
381 cb(msg->data.getBuffer(), msg->data.getLength(), msg->error, msg->userParam);
386 case Message::MSG_REQUEST_CLOSE_SESSION :
388 SCARD_DEBUG("MSG_REQUEST_CLOSE_SESSION");
390 if (msg->callback == (void *)session) /* synchronized call */
395 session->error = msg->error;
397 session->signalCondition();
398 session->syncUnlock();
400 else if (msg->callback != NULL)
402 closeSessionCallback cb = (closeSessionCallback)msg->callback;
405 cb(msg->error, msg->userParam);
410 case Message::MSG_REQUEST_GET_CHANNEL_COUNT :
412 SCARD_DEBUG("MSG_REQUEST_GET_CHANNEL_COUNT");
414 if (msg->callback == (void *)session) /* synchronized call */
419 session->error = msg->error;
420 session->channelCount = msg->param1;
422 session->signalCondition();
423 session->syncUnlock();
425 else if (msg->callback != NULL)
427 getChannelCountCallback cb = (getChannelCountCallback)msg->callback;
430 cb(msg->param1, msg->error, msg->userParam);
436 SCARD_DEBUG("unknown message : %s", msg->toString());
444 } /* namespace smartcard_service_api */
447 #define SESSION_EXTERN_BEGIN \
448 if (handle != NULL) \
450 Session *session = (Session *)handle;
452 #define SESSION_EXTERN_END \
456 SCARD_DEBUG_ERR("Invalid param"); \
459 using namespace smartcard_service_api;
461 EXTERN_API reader_h session_get_reader(session_h handle)
463 reader_h reader = NULL;
465 SESSION_EXTERN_BEGIN;
466 reader = session->getReader();
472 EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
476 SESSION_EXTERN_BEGIN;
477 result = session->getATR((getATRCallback)callback, userData);
483 EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
487 SESSION_EXTERN_BEGIN;
488 result = session->close((closeSessionCallback)callback, userData);
494 EXTERN_API bool session_is_closed(session_h handle)
498 SESSION_EXTERN_BEGIN;
499 result = session->isClosed();
505 EXTERN_API void session_close_channels(session_h handle)
507 SESSION_EXTERN_BEGIN;
508 session->closeChannels();
512 EXTERN_API int session_open_basic_channel(session_h handle, unsigned char *aid, unsigned int length, session_open_channel_cb callback, void *userData)
516 SESSION_EXTERN_BEGIN;
517 result = session->openBasicChannel(aid, length, (openChannelCallback)callback, userData);
523 EXTERN_API int session_open_logical_channel(session_h handle, unsigned char *aid, unsigned int length, session_open_channel_cb callback, void *userData)
527 SESSION_EXTERN_BEGIN;
528 result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
534 EXTERN_API unsigned int session_get_channel_count(session_h handle, session_get_channel_count_cb callback, void * userData)
536 unsigned int result = 0;
538 SESSION_EXTERN_BEGIN;
539 result = session->getChannelCount((getChannelCountCallback)callback, userData);
545 EXTERN_API void session_destroy_instance(session_h handle)
547 SESSION_EXTERN_BEGIN;