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 */
29 #include "ClientChannel.h"
30 #include "ClientGDBus.h"
33 #define EXTERN_API __attribute__((visibility("default")))
36 namespace smartcard_service_api
38 Session::Session(void *context, Reader *reader, void *handle) :
43 if (context == NULL || handle == NULL)
45 _ERR("handle is null");
50 this->context = context;
51 this->handle = handle;
53 /* init default context */
56 proxy = smartcard_service_session_proxy_new_for_bus_sync(
57 G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
58 "org.tizen.SmartcardService",
59 "/org/tizen/SmartcardService/Session",
63 _ERR("Can not create proxy : %s", error->message);
77 for (i = 0; i < channels.size(); i++)
79 delete (ClientChannel *)channels[i];
85 void Session::closeChannels() throw(ErrorIO &, ErrorIllegalState &)
89 for (i = 0; i < channels.size(); i++)
91 channels[i]->closeSync();
95 void Session::session_get_atr_cb(GObject *source_object,
96 GAsyncResult *res, gpointer user_data)
98 CallbackParam *param = (CallbackParam *)user_data;
100 getATRCallback callback;
103 GError *error = NULL;
106 _INFO("MSG_REQUEST_GET_ATR");
109 _ERR("null parameter!!!");
113 session = (Session *)param->instance;
114 callback = (getATRCallback)param->callback;
116 if (smartcard_service_session_call_get_atr_finish(
117 SMARTCARD_SERVICE_SESSION(source_object),
118 &result, &var_atr, res, &error) == true) {
119 if (result == SCARD_ERROR_OK) {
120 GDBusHelper::convertVariantToByteArray(var_atr, atr);
124 _ERR("smartcard_service_session_call_get_atr failed, [%d]", result);
127 _ERR("smartcard_service_session_call_get_atr failed, [%s]", error->message);
130 result = SCARD_ERROR_IPC_FAILED;
133 if (callback != NULL) {
134 callback(atr.getBuffer(),
135 atr.size(), result, param->user_param);
141 void Session::session_open_channel_cb(GObject *source_object,
142 GAsyncResult *res, gpointer user_data)
144 CallbackParam *param = (CallbackParam *)user_data;
146 openChannelCallback callback;
147 gint result = SCARD_ERROR_UNKNOWN;
150 GVariant *var_response;
151 GError *error = NULL;
152 Channel *channel = NULL;
154 _INFO("MSG_REQUEST_OPEN_CHANNEL");
157 _ERR("null parameter!!!");
161 session = (Session *)param->instance;
162 callback = (openChannelCallback)param->callback;
164 if (smartcard_service_session_call_open_channel_finish(
165 SMARTCARD_SERVICE_SESSION(source_object),
166 &result, &channel_id, &channel_number, &var_response,
167 res, &error) == true) {
168 if (result == SCARD_ERROR_OK) {
171 GDBusHelper::convertVariantToByteArray(
172 var_response, response);
174 /* create new instance of channel */
175 channel = new ClientChannel(session->context,
177 response, GUINT_TO_POINTER(channel_id));
178 if (channel != NULL) {
179 session->channels.push_back(channel);
181 _ERR("alloc failed");
183 result = SCARD_ERROR_OUT_OF_MEMORY;
186 _ERR("smartcard_service_session_call_open_channel failed, [%d]", result);
189 _ERR("smartcard_service_session_call_open_channel failed, [%s]", error->message);
192 result = SCARD_ERROR_IPC_FAILED;
195 if (callback != NULL) {
196 callback(channel, result, param->user_param);
202 void Session::session_close_cb(GObject *source_object,
203 GAsyncResult *res, gpointer user_data)
205 CallbackParam *param = (CallbackParam *)user_data;
207 closeSessionCallback callback;
209 GError *error = NULL;
211 _INFO("MSG_REQUEST_CLOSE_SESSION");
214 _ERR("null parameter!!!");
218 session = (Session *)param->instance;
219 callback = (closeSessionCallback)param->callback;
221 if (smartcard_service_session_call_close_session_finish(
222 SMARTCARD_SERVICE_SESSION(source_object),
223 &result, res, &error) == true) {
224 if (result == SCARD_ERROR_OK) {
225 session->closed = true;
227 _ERR("smartcard_service_session_call_close_session failed, [%d]", result);
230 _ERR("smartcard_service_session_call_close_session failed, [%s]", error->message);
233 result = SCARD_ERROR_IPC_FAILED;
236 if (callback != NULL) {
237 callback(result, param->user_param);
243 const ByteArray Session::getATRSync()
244 throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
245 ErrorIllegalState &, ErrorIllegalParameter &)
249 if (getReader()->isSecureElementPresent() == true) {
250 if (atr.isEmpty() == true)
253 GVariant *var_atr = NULL;
254 GError *error = NULL;
256 if (smartcard_service_session_call_get_atr_sync(
257 (SmartcardServiceSession *)proxy,
258 GPOINTER_TO_UINT(context),
259 GPOINTER_TO_UINT(handle),
260 &ret, &var_atr, NULL, &error) == true) {
261 if (ret == SCARD_ERROR_OK) {
262 GDBusHelper::convertVariantToByteArray(var_atr, result);
266 _ERR("smartcard_service_session_call_get_atr_sync failed, [%d]", ret);
271 _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
274 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
280 _ERR("unavailable session");
281 throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
287 int Session::getATR(getATRCallback callback, void *userData)
291 if (getReader()->isSecureElementPresent() == true) {
292 if (atr.isEmpty() == true) {
293 CallbackParam *param = new CallbackParam();
295 param->instance = this;
296 param->callback = (void *)callback;
297 param->user_param = userData;
299 smartcard_service_session_call_get_atr(
300 (SmartcardServiceSession *)proxy,
301 GPOINTER_TO_UINT(context),
302 GPOINTER_TO_UINT(handle), NULL,
303 &Session::session_get_atr_cb, param);
305 result = SCARD_ERROR_OK;
307 result = SCARD_ERROR_OK;
309 /* TODO : invoke callback directly */
310 callback(atr.getBuffer(),
311 atr.size(), 0, userData);
314 _ERR("unavailable session");
315 result = SCARD_ERROR_ILLEGAL_STATE;
321 void Session::closeSync()
322 throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
323 ErrorIllegalState &, ErrorIllegalParameter &)
325 if (isClosed() == false)
331 GError *error = NULL;
333 if (smartcard_service_session_call_close_session_sync(
334 (SmartcardServiceSession *)proxy,
335 GPOINTER_TO_UINT(context),
336 GPOINTER_TO_UINT(handle),
337 &ret, NULL, &error) == true) {
338 if (ret == SCARD_ERROR_OK) {
341 _ERR("smartcard_service_session_call_close_session_sync failed, [%d]", ret);
346 _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
349 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
354 int Session::close(closeSessionCallback callback, void *userData)
356 int result = SCARD_ERROR_OK;
358 if (isClosed() == false)
363 CallbackParam *param = new CallbackParam();
365 param->instance = this;
366 param->callback = (void *)callback;
367 param->user_param = userData;
369 smartcard_service_session_call_close_session(
370 (SmartcardServiceSession *)proxy,
371 GPOINTER_TO_UINT(context),
372 GPOINTER_TO_UINT(handle), NULL,
373 &Session::session_close_cb, param);
379 size_t Session::getChannelCount() const
383 if (getReader()->isSecureElementPresent() == true) {
384 count = channels.size();
386 _ERR("unavailable session");
387 throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
392 Channel *Session::openChannelSync(int id, const ByteArray &aid)
393 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
394 ErrorIllegalParameter &, ErrorSecurity &)
396 return openChannelSync(id, aid, 0x00);
399 Channel *Session::openChannelSync(int id, const ByteArray &aid, unsigned char P2)
400 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
401 ErrorIllegalParameter &, ErrorSecurity &)
403 Channel *channel = NULL;
405 if (getReader()->isSecureElementPresent() == true) {
407 GVariant *var_aid = NULL, *var_response = NULL;
410 GError *error = NULL;
412 var_aid = GDBusHelper::convertByteArrayToVariant(aid);
414 if (smartcard_service_session_call_open_channel_sync(
415 (SmartcardServiceSession *)proxy,
416 GPOINTER_TO_UINT(context),
417 GPOINTER_TO_UINT(handle),
418 (guint)id, var_aid, (guint8)P2, &ret, &channel_id, &channel_number,
419 &var_response, NULL, &error) == true) {
420 if (ret == SCARD_ERROR_OK && channel_id != 0) {
423 GDBusHelper::convertVariantToByteArray(
424 var_response, response);
426 /* create new instance of channel */
427 channel = new ClientChannel(context,
428 this, channel_number,
429 response, GUINT_TO_POINTER(channel_id));
430 if (channel != NULL) {
431 channels.push_back(channel);
433 _ERR("alloc failed");
435 THROW_ERROR(SCARD_ERROR_OUT_OF_MEMORY);
438 _ERR("smartcard_service_session_call_open_channel_sync failed, [%d]", ret);
443 _ERR("smartcard_service_session_call_open_channel_sync failed, [%s]", error->message);
446 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
449 _ERR("unavailable session");
451 throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
454 return (Channel *)channel;
457 int Session::openChannel(int id, const ByteArray &aid, openChannelCallback callback, void *userData)
461 if (getReader()->isSecureElementPresent() == true) {
464 CallbackParam *param = new CallbackParam();
466 param->instance = this;
467 param->callback = (void *)callback;
468 param->user_param = userData;
470 var_aid = GDBusHelper::convertByteArrayToVariant(aid);
472 smartcard_service_session_call_open_channel(
473 (SmartcardServiceSession *)proxy,
474 GPOINTER_TO_UINT(context),
475 GPOINTER_TO_UINT(handle),
476 (guint)id, var_aid, 0, NULL,
477 &Session::session_open_channel_cb, param);
479 result = SCARD_ERROR_OK;
481 _ERR("unavailable session");
482 result = SCARD_ERROR_ILLEGAL_STATE;
488 Channel *Session::openBasicChannelSync(const ByteArray &aid)
489 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
490 ErrorIllegalParameter &, ErrorSecurity &)
492 return openChannelSync(0, aid, 0x00);
495 Channel *Session::openBasicChannelSync(const ByteArray &aid, unsigned char P2)
496 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
497 ErrorIllegalParameter &, ErrorSecurity &)
499 return openChannelSync(0, aid, P2);
502 Channel *Session::openBasicChannelSync(const unsigned char *aid, unsigned int length)
503 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
504 ErrorIllegalParameter &, ErrorSecurity &)
506 ByteArray temp(aid, length);
508 return openBasicChannelSync(temp, 0x00);
511 Channel *Session::openBasicChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
512 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
513 ErrorIllegalParameter &, ErrorSecurity &)
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)
534 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
535 ErrorIllegalParameter &, ErrorSecurity &)
537 return openChannelSync(1, aid, 0x00);
540 Channel *Session::openLogicalChannelSync(const ByteArray &aid, unsigned char P2)
541 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
542 ErrorIllegalParameter &, ErrorSecurity &)
544 return openChannelSync(1, aid, P2);
547 Channel *Session::openLogicalChannelSync(const unsigned char *aid, unsigned int length)
548 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
549 ErrorIllegalParameter &, ErrorSecurity &)
551 ByteArray temp(aid, length);
553 return openLogicalChannelSync(temp, 0x00);
556 Channel *Session::openLogicalChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
557 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
558 ErrorIllegalParameter &, ErrorSecurity &)
560 ByteArray temp(aid, length);
562 return openLogicalChannelSync(temp, P2);
565 int Session::openLogicalChannel(const ByteArray &aid, openChannelCallback callback, void *userData)
567 return openChannel(1, aid, callback, userData);
570 int Session::openLogicalChannel(const unsigned char *aid, unsigned int length,
571 openChannelCallback callback, void *userData)
573 ByteArray temp(aid, length);
575 return openLogicalChannel(temp, callback, userData);
577 } /* namespace smartcard_service_api */
580 #define SESSION_EXTERN_BEGIN \
581 if (handle != NULL) \
583 Session *session = (Session *)handle;
585 #define SESSION_EXTERN_END \
589 _ERR("Invalid param"); \
592 using namespace smartcard_service_api;
594 EXTERN_API int session_get_reader(session_h handle, int* reader_handle)
596 int result = SCARD_ERROR_OK;
597 reader_h reader = NULL;
599 SESSION_EXTERN_BEGIN;
603 reader = session->getReader();
604 *reader_handle = (long)reader;
606 catch (ExceptionBase &e)
608 _ERR("Error occur : %s\n", e.what());
609 result = e.getErrorCode();
614 _ERR("Error occur : unknown error\n");
615 result = SCARD_ERROR_UNKNOWN;
624 EXTERN_API int session_is_closed(session_h handle, bool* is_closed)
626 int result = SCARD_ERROR_OK;
628 SESSION_EXTERN_BEGIN;
632 *is_closed = session->isClosed();
634 catch (ExceptionBase &e)
636 _ERR("Error occur : %s\n", e.what());
637 result = e.getErrorCode();
641 _ERR("Error occur : unknown error\n");
642 result = SCARD_ERROR_UNKNOWN;
650 EXTERN_API int session_close_channels(session_h handle)
652 int result = SCARD_ERROR_OK;
654 SESSION_EXTERN_BEGIN;
658 session->closeChannels();
660 catch (ExceptionBase &e)
662 _ERR("Error occur : %s\n", e.what());
663 result = e.getErrorCode();
667 _ERR("Error occur : unknown error\n");
668 result = SCARD_ERROR_UNKNOWN;
676 EXTERN_API int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length)
679 int result = SCARD_ERROR_OK;
681 SESSION_EXTERN_BEGIN;
685 temp = session->getATRSync();
689 *buffer = (unsigned char *)calloc(temp.size(), sizeof(char));
690 *length = temp.size();
692 memcpy(*buffer, temp.getBuffer(), *length);
695 catch (ErrorIllegalState &e)
697 _ERR("Error occur : %s\n", e.what());
698 result = e.getErrorCode();
700 if(result == SCARD_ERROR_OPERATION_NOT_SUPPORTED)
703 result = SCARD_ERROR_OK;
706 catch (ExceptionBase &e)
708 _ERR("Error occur : %s\n", e.what());
709 result = e.getErrorCode();
714 _ERR("Error occur : unknown error\n");
715 result = SCARD_ERROR_UNKNOWN;
724 EXTERN_API int session_close_sync(session_h handle)
726 int result = SCARD_ERROR_OK;
728 SESSION_EXTERN_BEGIN;
732 session->closeSync();
734 catch (ExceptionBase &e)
736 _ERR("Error occur : %s\n", e.what());
737 result = e.getErrorCode();
741 _ERR("Error occur : unknown error\n");
742 result = SCARD_ERROR_UNKNOWN;
750 EXTERN_API int session_open_basic_channel_sync(session_h handle, unsigned char *aid,
751 unsigned int length, unsigned char P2, int* channel_handle)
753 int result = SCARD_ERROR_OK;
755 SESSION_EXTERN_BEGIN;
759 *channel_handle = (long)session->openBasicChannelSync(aid, length, P2);
761 catch (ExceptionBase &e)
763 _ERR("Error occur : %s\n", e.what());
764 result = e.getErrorCode();
769 _ERR("Error occur : unknown error\n");
770 result = SCARD_ERROR_UNKNOWN;
779 EXTERN_API int session_open_logical_channel_sync(session_h handle, unsigned char *aid,
780 unsigned int length, unsigned char P2, int* channel_handle)
782 int result = SCARD_ERROR_OK;
784 SESSION_EXTERN_BEGIN;
788 *channel_handle = (long)session->openLogicalChannelSync(aid, length, P2);
790 catch (ExceptionBase &e)
792 _ERR("Error occur : %s\n", e.what());
793 result = e.getErrorCode();
798 _ERR("Error occur : unknown error\n");
799 result = SCARD_ERROR_UNKNOWN;
808 EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
812 SESSION_EXTERN_BEGIN;
813 result = session->getATR((getATRCallback)callback, userData);
819 EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
823 SESSION_EXTERN_BEGIN;
824 result = session->close((closeSessionCallback)callback, userData);
830 EXTERN_API int session_open_basic_channel(session_h handle, unsigned char *aid,
831 unsigned int length, session_open_channel_cb callback, void *userData)
835 SESSION_EXTERN_BEGIN;
836 result = session->openBasicChannel(aid, length, (openChannelCallback)callback, userData);
842 EXTERN_API int session_open_logical_channel(session_h handle, unsigned char *aid,
843 unsigned int length, session_open_channel_cb callback, void *userData)
847 SESSION_EXTERN_BEGIN;
848 result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
854 EXTERN_API size_t session_get_channel_count(session_h handle)
858 SESSION_EXTERN_BEGIN;
859 result = session->getChannelCount();
865 EXTERN_API void session_destroy_instance(session_h handle)