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.
17 /* standard library header */
23 /* SLP library header */
26 #include "smartcard_debug.h"
29 #include "ClientChannel.h"
30 #include "ClientGDBus.h"
35 #define EXTERN_API __attribute__((visibility("default")))
38 namespace smartcard_service_api
40 Session::Session(void *context, Reader *reader, void *handle) :
45 if (context == NULL || handle == NULL)
47 _ERR("handle is null");
52 this->context = context;
53 this->handle = handle;
55 /* init default context */
58 proxy = smartcard_service_session_proxy_new_for_bus_sync(
59 G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
60 "org.tizen.SmartcardService",
61 "/org/tizen/SmartcardService/Session",
66 _ERR("Can not create proxy : %s", error->message);
81 for (i = 0; i < channels.size(); i++)
83 delete (ClientChannel *)channels[i];
89 void Session::closeChannels()
93 for (i = 0; i < channels.size(); i++)
95 channels[i]->closeSync();
99 void Session::session_get_atr_cb(GObject *source_object,
100 GAsyncResult *res, gpointer user_data)
102 CallbackParam *param = (CallbackParam *)user_data;
104 getATRCallback callback;
107 GError *error = NULL;
110 _INFO("MSG_REQUEST_GET_ATR");
113 _ERR("null parameter!!!");
117 session = (Session *)param->instance;
118 callback = (getATRCallback)param->callback;
120 if (smartcard_service_session_call_get_atr_finish(
121 SMARTCARD_SERVICE_SESSION(source_object),
122 &result, &var_atr, res, &error) == true) {
123 if (result == SCARD_ERROR_OK) {
124 GDBusHelper::convertVariantToByteArray(var_atr, atr);
128 _ERR("smartcard_service_session_call_get_atr failed, [%d]", result);
132 _ERR("smartcard_service_session_call_get_atr failed, [%s]", error->message);
136 result = SCARD_ERROR_IPC_FAILED;
139 if (callback != NULL) {
140 callback(atr.getBuffer(),
141 atr.size(), result, param->user_param);
147 void Session::session_open_channel_cb(GObject *source_object,
148 GAsyncResult *res, gpointer user_data)
150 CallbackParam *param = (CallbackParam *)user_data;
152 openChannelCallback callback;
153 gint result = SCARD_ERROR_UNKNOWN;
156 GVariant *var_response;
157 GError *error = NULL;
158 Channel *channel = NULL;
160 _INFO("MSG_REQUEST_OPEN_CHANNEL");
163 _ERR("null parameter!!!");
167 session = (Session *)param->instance;
168 callback = (openChannelCallback)param->callback;
170 if (smartcard_service_session_call_open_channel_finish(
171 SMARTCARD_SERVICE_SESSION(source_object),
172 &result, &channel_id, &channel_number, &var_response,
173 res, &error) == true) {
174 if (result == SCARD_ERROR_OK) {
177 GDBusHelper::convertVariantToByteArray(
178 var_response, response);
180 /* create new instance of channel */
181 channel = new (std::nothrow)ClientChannel(session->context,
183 response, GUINT_TO_POINTER(channel_id));
184 if (channel != NULL) {
185 session->channels.push_back(channel);
187 _ERR("alloc failed");
189 result = SCARD_ERROR_OUT_OF_MEMORY;
192 _ERR("smartcard_service_session_call_open_channel failed, [%d]", result);
196 _ERR("smartcard_service_session_call_open_channel failed, [%s]", error->message);
200 result = SCARD_ERROR_IPC_FAILED;
203 if (callback != NULL) {
204 callback(channel, result, param->user_param);
210 void Session::session_close_cb(GObject *source_object,
211 GAsyncResult *res, gpointer user_data)
213 CallbackParam *param = (CallbackParam *)user_data;
215 closeSessionCallback callback;
217 GError *error = NULL;
219 _INFO("MSG_REQUEST_CLOSE_SESSION");
222 _ERR("null parameter!!!");
226 session = (Session *)param->instance;
227 callback = (closeSessionCallback)param->callback;
229 if (smartcard_service_session_call_close_session_finish(
230 SMARTCARD_SERVICE_SESSION(source_object),
231 &result, res, &error) == true) {
232 if (result == SCARD_ERROR_OK) {
233 session->closed = true;
235 _ERR("smartcard_service_session_call_close_session failed, [%d]", result);
239 _ERR("smartcard_service_session_call_close_session failed, [%s]", error->message);
243 result = SCARD_ERROR_IPC_FAILED;
246 if (callback != NULL) {
247 callback(result, param->user_param);
253 const ByteArray Session::getATRSync()
257 if (getReader()->isSecureElementPresent() == true) {
258 if (atr.isEmpty() == true)
261 GVariant *var_atr = NULL;
262 GError *error = NULL;
264 if (smartcard_service_session_call_get_atr_sync(
265 (SmartcardServiceSession *)proxy,
266 GPOINTER_TO_UINT(context),
267 GPOINTER_TO_UINT(handle),
268 &ret, &var_atr, NULL, &error) == true) {
269 if (ret == SCARD_ERROR_OK) {
270 GDBusHelper::convertVariantToByteArray(var_atr, result);
274 _ERR("smartcard_service_session_call_get_atr_sync failed, [%d]", ret);
280 _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
284 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
290 _ERR("unavailable session");
291 throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
297 int Session::getATR(getATRCallback callback, void *userData)
301 if (getReader()->isSecureElementPresent() == true) {
302 if (atr.isEmpty() == true) {
303 CallbackParam *param = new (std::nothrow)CallbackParam();
305 param->instance = this;
306 param->callback = (void *)callback;
307 param->user_param = userData;
309 smartcard_service_session_call_get_atr(
310 (SmartcardServiceSession *)proxy,
311 GPOINTER_TO_UINT(context),
312 GPOINTER_TO_UINT(handle), NULL,
313 &Session::session_get_atr_cb, param);
315 result = SCARD_ERROR_OK;
317 result = SCARD_ERROR_OK;
319 /* TODO : invoke callback directly */
320 callback(atr.getBuffer(),
321 atr.size(), 0, userData);
324 _ERR("unavailable session");
325 result = SCARD_ERROR_ILLEGAL_STATE;
331 void Session::closeSync()
333 if (isClosed() == false)
339 GError *error = NULL;
341 if (smartcard_service_session_call_close_session_sync(
342 (SmartcardServiceSession *)proxy,
343 GPOINTER_TO_UINT(context),
344 GPOINTER_TO_UINT(handle),
345 &ret, NULL, &error) == true) {
346 if (ret == SCARD_ERROR_OK) {
349 _ERR("smartcard_service_session_call_close_session_sync failed, [%d]", ret);
355 _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
359 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
364 int Session::close(closeSessionCallback callback, void *userData)
366 int result = SCARD_ERROR_OK;
368 if (isClosed() == false)
373 CallbackParam *param = new (std::nothrow)CallbackParam();
375 param->instance = this;
376 param->callback = (void *)callback;
377 param->user_param = userData;
379 smartcard_service_session_call_close_session(
380 (SmartcardServiceSession *)proxy,
381 GPOINTER_TO_UINT(context),
382 GPOINTER_TO_UINT(handle), NULL,
383 &Session::session_close_cb, param);
389 size_t Session::getChannelCount() const
393 if (getReader()->isSecureElementPresent() == true) {
394 count = channels.size();
396 _ERR("unavailable session");
397 throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
402 Channel *Session::openChannelSync(int id, const ByteArray &aid)
404 return openChannelSync(id, aid, 0x00);
407 Channel *Session::openChannelSync(int id, const ByteArray &aid, unsigned char P2)
409 Channel *channel = NULL;
411 if (getReader()->isSecureElementPresent() == true) {
413 GVariant *var_aid = NULL, *var_response = NULL;
416 GError *error = NULL;
418 var_aid = GDBusHelper::convertByteArrayToVariant(aid);
420 if (smartcard_service_session_call_open_channel_sync(
421 (SmartcardServiceSession *)proxy,
422 GPOINTER_TO_UINT(context),
423 GPOINTER_TO_UINT(handle),
424 (guint)id, var_aid, (guint8)P2, &ret, &channel_id, &channel_number,
425 &var_response, NULL, &error) == true) {
426 if (ret == SCARD_ERROR_OK && channel_id != 0) {
429 GDBusHelper::convertVariantToByteArray(
430 var_response, response);
432 /* create new instance of channel */
433 channel = new (std::nothrow)ClientChannel(context,
434 this, channel_number,
435 response, GUINT_TO_POINTER(channel_id));
436 if (channel != NULL) {
437 channels.push_back(channel);
439 _ERR("alloc failed");
441 THROW_ERROR(SCARD_ERROR_OUT_OF_MEMORY);
444 _ERR("smartcard_service_session_call_open_channel_sync failed, [%d]", ret);
450 _ERR("smartcard_service_session_call_open_channel_sync failed, [%s]", error->message);
454 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
457 _ERR("unavailable session");
459 throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
462 return (Channel *)channel;
465 int Session::openChannel(int id, const ByteArray &aid, openChannelCallback callback, void *userData)
469 if (getReader()->isSecureElementPresent() == true) {
472 CallbackParam *param = new (std::nothrow)CallbackParam();
474 param->instance = this;
475 param->callback = (void *)callback;
476 param->user_param = userData;
478 var_aid = GDBusHelper::convertByteArrayToVariant(aid);
480 smartcard_service_session_call_open_channel(
481 (SmartcardServiceSession *)proxy,
482 GPOINTER_TO_UINT(context),
483 GPOINTER_TO_UINT(handle),
484 (guint)id, var_aid, 0, NULL,
485 &Session::session_open_channel_cb, param);
487 result = SCARD_ERROR_OK;
489 _ERR("unavailable session");
490 result = SCARD_ERROR_ILLEGAL_STATE;
496 Channel *Session::openBasicChannelSync(const ByteArray &aid)
498 return openChannelSync(0, aid, 0x00);
501 Channel *Session::openBasicChannelSync(const ByteArray &aid, unsigned char P2)
503 return openChannelSync(0, aid, P2);
506 Channel *Session::openBasicChannelSync(const unsigned char *aid, unsigned int length)
508 ByteArray temp(aid, length);
510 return openBasicChannelSync(temp, 0x00);
513 Channel *Session::openBasicChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
515 ByteArray temp(aid, length);
517 return openBasicChannelSync(temp, P2);
520 int Session::openBasicChannel(const ByteArray &aid, openChannelCallback callback, void *userData)
522 return openChannel(0, aid, callback, userData);
525 int Session::openBasicChannel(const unsigned char *aid, unsigned int length,
526 openChannelCallback callback, void *userData)
528 ByteArray temp(aid, length);
530 return openBasicChannel(temp, callback, userData);
533 Channel *Session::openLogicalChannelSync(const ByteArray &aid)
535 return openChannelSync(1, aid, 0x00);
538 Channel *Session::openLogicalChannelSync(const ByteArray &aid, unsigned char P2)
540 return openChannelSync(1, aid, P2);
543 Channel *Session::openLogicalChannelSync(const unsigned char *aid, unsigned int length)
545 ByteArray temp(aid, length);
547 return openLogicalChannelSync(temp, 0x00);
550 Channel *Session::openLogicalChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
552 ByteArray temp(aid, length);
554 return openLogicalChannelSync(temp, P2);
557 int Session::openLogicalChannel(const ByteArray &aid, openChannelCallback callback, void *userData)
559 return openChannel(1, aid, callback, userData);
562 int Session::openLogicalChannel(const unsigned char *aid, unsigned int length,
563 openChannelCallback callback, void *userData)
565 ByteArray temp(aid, length);
567 return openLogicalChannel(temp, callback, userData);
569 } /* namespace smartcard_service_api */
572 #define SESSION_EXTERN_BEGIN \
573 if (handle != NULL) \
575 Session *session = (Session *)handle;
577 #define SESSION_EXTERN_END \
581 _ERR("Invalid param"); \
584 using namespace smartcard_service_api;
586 EXTERN_API int session_get_reader(session_h handle, int* reader_handle)
588 int result = SCARD_ERROR_OK;
589 reader_h reader = NULL;
591 SESSION_EXTERN_BEGIN;
595 reader = session->getReader();
596 *reader_handle = (long)reader;
598 catch (ExceptionBase &e)
600 _ERR("Error occur : %s\n", e.what());
601 result = e.getErrorCode();
606 _ERR("Error occur : unknown error\n");
607 result = SCARD_ERROR_UNKNOWN;
616 EXTERN_API int session_is_closed(session_h handle, bool* is_closed)
618 int result = SCARD_ERROR_OK;
620 SESSION_EXTERN_BEGIN;
624 *is_closed = session->isClosed();
626 catch (ExceptionBase &e)
628 _ERR("Error occur : %s\n", e.what());
629 result = e.getErrorCode();
633 _ERR("Error occur : unknown error\n");
634 result = SCARD_ERROR_UNKNOWN;
642 EXTERN_API int session_close_channels(session_h handle)
644 int result = SCARD_ERROR_OK;
646 SESSION_EXTERN_BEGIN;
650 session->closeChannels();
652 catch (ExceptionBase &e)
654 _ERR("Error occur : %s\n", e.what());
655 result = e.getErrorCode();
659 _ERR("Error occur : unknown error\n");
660 result = SCARD_ERROR_UNKNOWN;
668 EXTERN_API int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length)
671 int result = SCARD_ERROR_OK;
673 SESSION_EXTERN_BEGIN;
677 temp = session->getATRSync();
681 *buffer = (unsigned char *)calloc(temp.size(), sizeof(char));
682 *length = temp.size();
684 memcpy(*buffer, temp.getBuffer(), *length);
687 catch (ErrorIllegalState &e)
689 _ERR("Error occur : %s\n", e.what());
690 result = e.getErrorCode();
692 if(result == SCARD_ERROR_OPERATION_NOT_SUPPORTED)
695 result = SCARD_ERROR_OK;
698 catch (ExceptionBase &e)
700 _ERR("Error occur : %s\n", e.what());
701 result = e.getErrorCode();
706 _ERR("Error occur : unknown error\n");
707 result = SCARD_ERROR_UNKNOWN;
716 EXTERN_API int session_close_sync(session_h handle)
718 int result = SCARD_ERROR_OK;
720 SESSION_EXTERN_BEGIN;
724 session->closeSync();
726 catch (ExceptionBase &e)
728 _ERR("Error occur : %s\n", e.what());
729 result = e.getErrorCode();
733 _ERR("Error occur : unknown error\n");
734 result = SCARD_ERROR_UNKNOWN;
742 EXTERN_API int session_open_basic_channel_sync(session_h handle, unsigned char *aid,
743 unsigned int length, unsigned char P2, int* channel_handle)
745 int result = SCARD_ERROR_OK;
747 SESSION_EXTERN_BEGIN;
751 *channel_handle = (long)session->openBasicChannelSync(aid, length, P2);
753 catch (ExceptionBase &e)
755 _ERR("Error occur : %s\n", e.what());
756 result = e.getErrorCode();
761 _ERR("Error occur : unknown error\n");
762 result = SCARD_ERROR_UNKNOWN;
771 EXTERN_API int session_open_logical_channel_sync(session_h handle, unsigned char *aid,
772 unsigned int length, unsigned char P2, int* channel_handle)
774 int result = SCARD_ERROR_OK;
776 SESSION_EXTERN_BEGIN;
780 *channel_handle = (long)session->openLogicalChannelSync(aid, length, P2);
782 catch (ExceptionBase &e)
784 _ERR("Error occur : %s\n", e.what());
785 result = e.getErrorCode();
790 _ERR("Error occur : unknown error\n");
791 result = SCARD_ERROR_UNKNOWN;
800 EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
804 SESSION_EXTERN_BEGIN;
805 result = session->getATR((getATRCallback)callback, userData);
811 EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
815 SESSION_EXTERN_BEGIN;
816 result = session->close((closeSessionCallback)callback, userData);
822 EXTERN_API int session_open_basic_channel(session_h handle, unsigned char *aid,
823 unsigned int length, session_open_channel_cb callback, void *userData)
827 SESSION_EXTERN_BEGIN;
828 result = session->openBasicChannel(aid, length, (openChannelCallback)callback, userData);
834 EXTERN_API int session_open_logical_channel(session_h handle, unsigned char *aid,
835 unsigned int length, session_open_channel_cb callback, void *userData)
839 SESSION_EXTERN_BEGIN;
840 result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
846 EXTERN_API size_t session_get_channel_count(session_h handle)
850 SESSION_EXTERN_BEGIN;
851 result = session->getChannelCount();
857 EXTERN_API void session_destroy_instance(session_h handle)