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, (void *)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)
251 if (atr.isEmpty() == true)
254 GVariant *var_atr = NULL;
255 GError *error = NULL;
257 if (smartcard_service_session_call_get_atr_sync(
258 (SmartcardServiceSession *)proxy,
259 GPOINTER_TO_UINT(context),
260 GPOINTER_TO_UINT(handle),
261 &ret, &var_atr, NULL, &error) == true) {
262 if (ret == SCARD_ERROR_OK) {
263 GDBusHelper::convertVariantToByteArray(var_atr, result);
267 _ERR("smartcard_service_session_call_get_atr_sync failed, [%d]", ret);
272 _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
275 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
283 _ERR("unavailable session");
284 throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
290 int Session::getATR(getATRCallback callback, void *userData)
294 if (getReader()->isSecureElementPresent() == true)
296 if (atr.isEmpty() == true)
298 CallbackParam *param = new CallbackParam();
300 param->instance = this;
301 param->callback = (void *)callback;
302 param->user_param = userData;
304 smartcard_service_session_call_get_atr(
305 (SmartcardServiceSession *)proxy,
306 GPOINTER_TO_UINT(context),
307 GPOINTER_TO_UINT(handle), NULL,
308 &Session::session_get_atr_cb, param);
310 result = SCARD_ERROR_OK;
314 result = SCARD_ERROR_OK;
316 /* TODO : invoke callback directly */
317 callback(atr.getBuffer(),
318 atr.size(), 0, userData);
323 _ERR("unavailable session");
324 result = SCARD_ERROR_ILLEGAL_STATE;
330 void Session::closeSync()
331 throw (ExceptionBase &, ErrorIO &, ErrorSecurity &,
332 ErrorIllegalState &, ErrorIllegalParameter &)
334 if (isClosed() == false)
340 GError *error = NULL;
342 if (smartcard_service_session_call_close_session_sync(
343 (SmartcardServiceSession *)proxy,
344 GPOINTER_TO_UINT(context),
345 GPOINTER_TO_UINT(handle),
346 &ret, NULL, &error) == true) {
347 if (ret == SCARD_ERROR_OK) {
350 _ERR("smartcard_service_session_call_close_session_sync failed, [%d]", ret);
355 _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
358 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
363 int Session::close(closeSessionCallback callback, void *userData)
365 int result = SCARD_ERROR_OK;
367 if (isClosed() == false)
372 CallbackParam *param = new CallbackParam();
374 param->instance = this;
375 param->callback = (void *)callback;
376 param->user_param = userData;
378 smartcard_service_session_call_close_session(
379 (SmartcardServiceSession *)proxy,
380 GPOINTER_TO_UINT(context),
381 GPOINTER_TO_UINT(handle), NULL,
382 &Session::session_close_cb, param);
388 size_t Session::getChannelCount() const
392 if (getReader()->isSecureElementPresent() == true)
394 count = channels.size();
398 _ERR("unavailable session");
399 throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
404 Channel *Session::openChannelSync(int id, const ByteArray &aid)
405 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
406 ErrorIllegalParameter &, ErrorSecurity &)
408 return openChannelSync(id, aid, 0x00);
411 Channel *Session::openChannelSync(int id, const ByteArray &aid, unsigned char P2)
412 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
413 ErrorIllegalParameter &, ErrorSecurity &)
415 Channel *channel = NULL;
417 if (getReader()->isSecureElementPresent() == true)
420 GVariant *var_aid = NULL, *var_response = NULL;
423 GError *error = NULL;
425 var_aid = GDBusHelper::convertByteArrayToVariant(aid);
427 if (smartcard_service_session_call_open_channel_sync(
428 (SmartcardServiceSession *)proxy,
429 GPOINTER_TO_UINT(context),
430 GPOINTER_TO_UINT(handle),
431 (guint)id, var_aid, (guint8)P2, &ret, &channel_id, &channel_number,
432 &var_response, NULL, &error) == true) {
433 if (ret == SCARD_ERROR_OK && channel_id != 0) {
436 GDBusHelper::convertVariantToByteArray(
437 var_response, response);
439 /* create new instance of channel */
440 channel = new ClientChannel(context,
441 this, channel_number,
442 response, (void *)channel_id);
445 channels.push_back(channel);
449 _ERR("alloc failed");
451 THROW_ERROR(SCARD_ERROR_OUT_OF_MEMORY);
454 _ERR("smartcard_service_session_call_open_channel_sync failed, [%d]", ret);
459 _ERR("smartcard_service_session_call_open_channel_sync failed, [%s]", error->message);
462 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
467 _ERR("unavailable session");
469 throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
472 return (Channel *)channel;
475 int Session::openChannel(int id, const ByteArray &aid, openChannelCallback callback, void *userData)
479 if (getReader()->isSecureElementPresent() == true)
483 CallbackParam *param = new CallbackParam();
485 param->instance = this;
486 param->callback = (void *)callback;
487 param->user_param = userData;
489 var_aid = GDBusHelper::convertByteArrayToVariant(aid);
491 smartcard_service_session_call_open_channel(
492 (SmartcardServiceSession *)proxy,
493 GPOINTER_TO_UINT(context),
494 GPOINTER_TO_UINT(handle),
495 (guint)id, var_aid, 0, NULL,
496 &Session::session_open_channel_cb, param);
498 result = SCARD_ERROR_OK;
502 _ERR("unavailable session");
503 result = SCARD_ERROR_ILLEGAL_STATE;
509 Channel *Session::openBasicChannelSync(const ByteArray &aid)
510 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
511 ErrorIllegalParameter &, ErrorSecurity &)
513 return openChannelSync(0, aid, 0x00);
516 Channel *Session::openBasicChannelSync(const ByteArray &aid, unsigned char P2)
517 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
518 ErrorIllegalParameter &, ErrorSecurity &)
520 return openChannelSync(0, aid, P2);
523 Channel *Session::openBasicChannelSync(const unsigned char *aid, unsigned int length)
524 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
525 ErrorIllegalParameter &, ErrorSecurity &)
527 ByteArray temp(aid, length);
529 return openBasicChannelSync(temp, 0x00);
532 Channel *Session::openBasicChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
533 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
534 ErrorIllegalParameter &, ErrorSecurity &)
536 ByteArray temp(aid, length);
538 return openBasicChannelSync(temp, P2);
541 int Session::openBasicChannel(const ByteArray &aid, openChannelCallback callback, void *userData)
543 return openChannel(0, aid, callback, userData);
546 int Session::openBasicChannel(const unsigned char *aid, unsigned int length,
547 openChannelCallback callback, void *userData)
549 ByteArray temp(aid, length);
551 return openBasicChannel(temp, callback, userData);
554 Channel *Session::openLogicalChannelSync(const ByteArray &aid)
555 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
556 ErrorIllegalParameter &, ErrorSecurity &)
558 return openChannelSync(1, aid, 0x00);
561 Channel *Session::openLogicalChannelSync(const ByteArray &aid, unsigned char P2)
562 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
563 ErrorIllegalParameter &, ErrorSecurity &)
565 return openChannelSync(1, aid, P2);
568 Channel *Session::openLogicalChannelSync(const unsigned char *aid, unsigned int length)
569 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
570 ErrorIllegalParameter &, ErrorSecurity &)
572 ByteArray temp(aid, length);
574 return openLogicalChannelSync(temp, 0x00);
577 Channel *Session::openLogicalChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
578 throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
579 ErrorIllegalParameter &, ErrorSecurity &)
581 ByteArray temp(aid, length);
583 return openLogicalChannelSync(temp, P2);
586 int Session::openLogicalChannel(const ByteArray &aid, openChannelCallback callback, void *userData)
588 return openChannel(1, aid, callback, userData);
591 int Session::openLogicalChannel(const unsigned char *aid, unsigned int length,
592 openChannelCallback callback, void *userData)
594 ByteArray temp(aid, length);
596 return openLogicalChannel(temp, callback, userData);
598 } /* namespace smartcard_service_api */
601 #define SESSION_EXTERN_BEGIN \
602 if (handle != NULL) \
604 Session *session = (Session *)handle;
606 #define SESSION_EXTERN_END \
610 _ERR("Invalid param"); \
613 using namespace smartcard_service_api;
615 EXTERN_API int session_get_reader(session_h handle, int* reader_handle)
617 int result = SCARD_ERROR_OK;
618 reader_h reader = NULL;
620 SESSION_EXTERN_BEGIN;
624 reader = session->getReader();
625 *reader_handle = (long)reader;
627 catch (ExceptionBase &e)
629 _ERR("Error occur : %s\n", e.what());
630 result = e.getErrorCode();
635 _ERR("Error occur : unknown error\n");
636 result = SCARD_ERROR_UNKNOWN;
645 EXTERN_API int session_is_closed(session_h handle, bool* is_closed)
647 int result = SCARD_ERROR_OK;
649 SESSION_EXTERN_BEGIN;
653 *is_closed = session->isClosed();
655 catch (ExceptionBase &e)
657 _ERR("Error occur : %s\n", e.what());
658 result = e.getErrorCode();
662 _ERR("Error occur : unknown error\n");
663 result = SCARD_ERROR_UNKNOWN;
671 EXTERN_API int session_close_channels(session_h handle)
673 int result = SCARD_ERROR_OK;
675 SESSION_EXTERN_BEGIN;
679 session->closeChannels();
681 catch (ExceptionBase &e)
683 _ERR("Error occur : %s\n", e.what());
684 result = e.getErrorCode();
688 _ERR("Error occur : unknown error\n");
689 result = SCARD_ERROR_UNKNOWN;
697 EXTERN_API int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length)
700 int result = SCARD_ERROR_OK;
702 SESSION_EXTERN_BEGIN;
706 temp = session->getATRSync();
710 *buffer = (unsigned char *)calloc(temp.size(), sizeof(char));
711 *length = temp.size();
713 memcpy(*buffer, temp.getBuffer(), *length);
716 catch (ErrorIllegalState &e)
718 _ERR("Error occur : %s\n", e.what());
719 result = e.getErrorCode();
721 if(result == SCARD_ERROR_OPERATION_NOT_SUPPORTED)
724 result = SCARD_ERROR_OK;
727 catch (ExceptionBase &e)
729 _ERR("Error occur : %s\n", e.what());
730 result = e.getErrorCode();
735 _ERR("Error occur : unknown error\n");
736 result = SCARD_ERROR_UNKNOWN;
745 EXTERN_API int session_close_sync(session_h handle)
747 int result = SCARD_ERROR_OK;
749 SESSION_EXTERN_BEGIN;
753 session->closeSync();
755 catch (ExceptionBase &e)
757 _ERR("Error occur : %s\n", e.what());
758 result = e.getErrorCode();
762 _ERR("Error occur : unknown error\n");
763 result = SCARD_ERROR_UNKNOWN;
771 EXTERN_API int session_open_basic_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->openBasicChannelSync(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_open_logical_channel_sync(session_h handle, unsigned char *aid,
801 unsigned int length, unsigned char P2, int* channel_handle)
803 int result = SCARD_ERROR_OK;
805 SESSION_EXTERN_BEGIN;
809 *channel_handle = (long)session->openLogicalChannelSync(aid, length, P2);
811 catch (ExceptionBase &e)
813 _ERR("Error occur : %s\n", e.what());
814 result = e.getErrorCode();
819 _ERR("Error occur : unknown error\n");
820 result = SCARD_ERROR_UNKNOWN;
829 EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
833 SESSION_EXTERN_BEGIN;
834 result = session->getATR((getATRCallback)callback, userData);
840 EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
844 SESSION_EXTERN_BEGIN;
845 result = session->close((closeSessionCallback)callback, userData);
851 EXTERN_API int session_open_basic_channel(session_h handle, unsigned char *aid,
852 unsigned int length, session_open_channel_cb callback, void *userData)
856 SESSION_EXTERN_BEGIN;
857 result = session->openBasicChannel(aid, length, (openChannelCallback)callback, userData);
863 EXTERN_API int session_open_logical_channel(session_h handle, unsigned char *aid,
864 unsigned int length, session_open_channel_cb callback, void *userData)
868 SESSION_EXTERN_BEGIN;
869 result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
875 EXTERN_API size_t session_get_channel_count(session_h handle)
879 SESSION_EXTERN_BEGIN;
880 result = session->getChannelCount();
886 EXTERN_API void session_destroy_instance(session_h handle)