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"
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",
65 _ERR("Can not create proxy : %s", error->message);
79 for (i = 0; i < channels.size(); i++)
81 delete (ClientChannel *)channels[i];
87 void Session::closeChannels()
91 for (i = 0; i < channels.size(); i++)
93 channels[i]->closeSync();
97 void Session::session_get_atr_cb(GObject *source_object,
98 GAsyncResult *res, gpointer user_data)
100 CallbackParam *param = (CallbackParam *)user_data;
102 getATRCallback callback;
105 GError *error = NULL;
108 _INFO("MSG_REQUEST_GET_ATR");
111 _ERR("null parameter!!!");
115 session = (Session *)param->instance;
116 callback = (getATRCallback)param->callback;
118 if (smartcard_service_session_call_get_atr_finish(
119 SMARTCARD_SERVICE_SESSION(source_object),
120 &result, &var_atr, res, &error) == true) {
121 if (result == SCARD_ERROR_OK) {
122 GDBusHelper::convertVariantToByteArray(var_atr, atr);
126 _ERR("smartcard_service_session_call_get_atr failed, [%d]", result);
129 _ERR("smartcard_service_session_call_get_atr failed, [%s]", error->message);
132 result = SCARD_ERROR_IPC_FAILED;
135 if (callback != NULL) {
136 callback(atr.getBuffer(),
137 atr.size(), result, param->user_param);
143 void Session::session_open_channel_cb(GObject *source_object,
144 GAsyncResult *res, gpointer user_data)
146 CallbackParam *param = (CallbackParam *)user_data;
148 openChannelCallback callback;
149 gint result = SCARD_ERROR_UNKNOWN;
152 GVariant *var_response;
153 GError *error = NULL;
154 Channel *channel = NULL;
156 _INFO("MSG_REQUEST_OPEN_CHANNEL");
159 _ERR("null parameter!!!");
163 session = (Session *)param->instance;
164 callback = (openChannelCallback)param->callback;
166 if (smartcard_service_session_call_open_channel_finish(
167 SMARTCARD_SERVICE_SESSION(source_object),
168 &result, &channel_id, &channel_number, &var_response,
169 res, &error) == true) {
170 if (result == SCARD_ERROR_OK) {
173 GDBusHelper::convertVariantToByteArray(
174 var_response, response);
176 /* create new instance of channel */
177 channel = new (std::nothrow)ClientChannel(session->context,
179 response, GUINT_TO_POINTER(channel_id));
180 if (channel != NULL) {
181 session->channels.push_back(channel);
183 _ERR("alloc failed");
185 result = SCARD_ERROR_OUT_OF_MEMORY;
188 _ERR("smartcard_service_session_call_open_channel failed, [%d]", result);
191 _ERR("smartcard_service_session_call_open_channel failed, [%s]", error->message);
194 result = SCARD_ERROR_IPC_FAILED;
197 if (callback != NULL) {
198 callback(channel, result, param->user_param);
204 void Session::session_close_cb(GObject *source_object,
205 GAsyncResult *res, gpointer user_data)
207 CallbackParam *param = (CallbackParam *)user_data;
209 closeSessionCallback callback;
211 GError *error = NULL;
213 _INFO("MSG_REQUEST_CLOSE_SESSION");
216 _ERR("null parameter!!!");
220 session = (Session *)param->instance;
221 callback = (closeSessionCallback)param->callback;
223 if (smartcard_service_session_call_close_session_finish(
224 SMARTCARD_SERVICE_SESSION(source_object),
225 &result, res, &error) == true) {
226 if (result == SCARD_ERROR_OK) {
227 session->closed = true;
229 _ERR("smartcard_service_session_call_close_session failed, [%d]", result);
232 _ERR("smartcard_service_session_call_close_session failed, [%s]", error->message);
235 result = SCARD_ERROR_IPC_FAILED;
238 if (callback != NULL) {
239 callback(result, param->user_param);
245 const ByteArray Session::getATRSync()
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 (std::nothrow)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()
323 if (isClosed() == false)
329 GError *error = NULL;
331 if (smartcard_service_session_call_close_session_sync(
332 (SmartcardServiceSession *)proxy,
333 GPOINTER_TO_UINT(context),
334 GPOINTER_TO_UINT(handle),
335 &ret, NULL, &error) == true) {
336 if (ret == SCARD_ERROR_OK) {
339 _ERR("smartcard_service_session_call_close_session_sync failed, [%d]", ret);
344 _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
347 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
352 int Session::close(closeSessionCallback callback, void *userData)
354 int result = SCARD_ERROR_OK;
356 if (isClosed() == false)
361 CallbackParam *param = new (std::nothrow)CallbackParam();
363 param->instance = this;
364 param->callback = (void *)callback;
365 param->user_param = userData;
367 smartcard_service_session_call_close_session(
368 (SmartcardServiceSession *)proxy,
369 GPOINTER_TO_UINT(context),
370 GPOINTER_TO_UINT(handle), NULL,
371 &Session::session_close_cb, param);
377 size_t Session::getChannelCount() const
381 if (getReader()->isSecureElementPresent() == true) {
382 count = channels.size();
384 _ERR("unavailable session");
385 throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
390 Channel *Session::openChannelSync(int id, const ByteArray &aid)
392 return openChannelSync(id, aid, 0x00);
395 Channel *Session::openChannelSync(int id, const ByteArray &aid, unsigned char P2)
397 Channel *channel = NULL;
399 if (getReader()->isSecureElementPresent() == true) {
401 GVariant *var_aid = NULL, *var_response = NULL;
404 GError *error = NULL;
406 var_aid = GDBusHelper::convertByteArrayToVariant(aid);
408 if (smartcard_service_session_call_open_channel_sync(
409 (SmartcardServiceSession *)proxy,
410 GPOINTER_TO_UINT(context),
411 GPOINTER_TO_UINT(handle),
412 (guint)id, var_aid, (guint8)P2, &ret, &channel_id, &channel_number,
413 &var_response, NULL, &error) == true) {
414 if (ret == SCARD_ERROR_OK && channel_id != 0) {
417 GDBusHelper::convertVariantToByteArray(
418 var_response, response);
420 /* create new instance of channel */
421 channel = new (std::nothrow)ClientChannel(context,
422 this, channel_number,
423 response, GUINT_TO_POINTER(channel_id));
424 if (channel != NULL) {
425 channels.push_back(channel);
427 _ERR("alloc failed");
429 THROW_ERROR(SCARD_ERROR_OUT_OF_MEMORY);
432 _ERR("smartcard_service_session_call_open_channel_sync failed, [%d]", ret);
437 _ERR("smartcard_service_session_call_open_channel_sync failed, [%s]", error->message);
440 THROW_ERROR(SCARD_ERROR_IPC_FAILED);
443 _ERR("unavailable session");
445 throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
448 return (Channel *)channel;
451 int Session::openChannel(int id, const ByteArray &aid, openChannelCallback callback, void *userData)
455 if (getReader()->isSecureElementPresent() == true) {
458 CallbackParam *param = new (std::nothrow)CallbackParam();
460 param->instance = this;
461 param->callback = (void *)callback;
462 param->user_param = userData;
464 var_aid = GDBusHelper::convertByteArrayToVariant(aid);
466 smartcard_service_session_call_open_channel(
467 (SmartcardServiceSession *)proxy,
468 GPOINTER_TO_UINT(context),
469 GPOINTER_TO_UINT(handle),
470 (guint)id, var_aid, 0, NULL,
471 &Session::session_open_channel_cb, param);
473 result = SCARD_ERROR_OK;
475 _ERR("unavailable session");
476 result = SCARD_ERROR_ILLEGAL_STATE;
482 Channel *Session::openBasicChannelSync(const ByteArray &aid)
484 return openChannelSync(0, aid, 0x00);
487 Channel *Session::openBasicChannelSync(const ByteArray &aid, unsigned char P2)
489 return openChannelSync(0, aid, P2);
492 Channel *Session::openBasicChannelSync(const unsigned char *aid, unsigned int length)
494 ByteArray temp(aid, length);
496 return openBasicChannelSync(temp, 0x00);
499 Channel *Session::openBasicChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
501 ByteArray temp(aid, length);
503 return openBasicChannelSync(temp, P2);
506 int Session::openBasicChannel(const ByteArray &aid, openChannelCallback callback, void *userData)
508 return openChannel(0, aid, callback, userData);
511 int Session::openBasicChannel(const unsigned char *aid, unsigned int length,
512 openChannelCallback callback, void *userData)
514 ByteArray temp(aid, length);
516 return openBasicChannel(temp, callback, userData);
519 Channel *Session::openLogicalChannelSync(const ByteArray &aid)
521 return openChannelSync(1, aid, 0x00);
524 Channel *Session::openLogicalChannelSync(const ByteArray &aid, unsigned char P2)
526 return openChannelSync(1, aid, P2);
529 Channel *Session::openLogicalChannelSync(const unsigned char *aid, unsigned int length)
531 ByteArray temp(aid, length);
533 return openLogicalChannelSync(temp, 0x00);
536 Channel *Session::openLogicalChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
538 ByteArray temp(aid, length);
540 return openLogicalChannelSync(temp, P2);
543 int Session::openLogicalChannel(const ByteArray &aid, openChannelCallback callback, void *userData)
545 return openChannel(1, aid, callback, userData);
548 int Session::openLogicalChannel(const unsigned char *aid, unsigned int length,
549 openChannelCallback callback, void *userData)
551 ByteArray temp(aid, length);
553 return openLogicalChannel(temp, callback, userData);
555 } /* namespace smartcard_service_api */
558 #define SESSION_EXTERN_BEGIN \
559 if (handle != NULL) \
561 Session *session = (Session *)handle;
563 #define SESSION_EXTERN_END \
567 _ERR("Invalid param"); \
570 using namespace smartcard_service_api;
572 EXTERN_API int session_get_reader(session_h handle, int* reader_handle)
574 int result = SCARD_ERROR_OK;
575 reader_h reader = NULL;
577 SESSION_EXTERN_BEGIN;
581 reader = session->getReader();
582 *reader_handle = (long)reader;
584 catch (ExceptionBase &e)
586 _ERR("Error occur : %s\n", e.what());
587 result = e.getErrorCode();
592 _ERR("Error occur : unknown error\n");
593 result = SCARD_ERROR_UNKNOWN;
602 EXTERN_API int session_is_closed(session_h handle, bool* is_closed)
604 int result = SCARD_ERROR_OK;
606 SESSION_EXTERN_BEGIN;
610 *is_closed = session->isClosed();
612 catch (ExceptionBase &e)
614 _ERR("Error occur : %s\n", e.what());
615 result = e.getErrorCode();
619 _ERR("Error occur : unknown error\n");
620 result = SCARD_ERROR_UNKNOWN;
628 EXTERN_API int session_close_channels(session_h handle)
630 int result = SCARD_ERROR_OK;
632 SESSION_EXTERN_BEGIN;
636 session->closeChannels();
638 catch (ExceptionBase &e)
640 _ERR("Error occur : %s\n", e.what());
641 result = e.getErrorCode();
645 _ERR("Error occur : unknown error\n");
646 result = SCARD_ERROR_UNKNOWN;
654 EXTERN_API int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length)
657 int result = SCARD_ERROR_OK;
659 SESSION_EXTERN_BEGIN;
663 temp = session->getATRSync();
667 *buffer = (unsigned char *)calloc(temp.size(), sizeof(char));
668 *length = temp.size();
670 memcpy(*buffer, temp.getBuffer(), *length);
673 catch (ErrorIllegalState &e)
675 _ERR("Error occur : %s\n", e.what());
676 result = e.getErrorCode();
678 if(result == SCARD_ERROR_OPERATION_NOT_SUPPORTED)
681 result = SCARD_ERROR_OK;
684 catch (ExceptionBase &e)
686 _ERR("Error occur : %s\n", e.what());
687 result = e.getErrorCode();
692 _ERR("Error occur : unknown error\n");
693 result = SCARD_ERROR_UNKNOWN;
702 EXTERN_API int session_close_sync(session_h handle)
704 int result = SCARD_ERROR_OK;
706 SESSION_EXTERN_BEGIN;
710 session->closeSync();
712 catch (ExceptionBase &e)
714 _ERR("Error occur : %s\n", e.what());
715 result = e.getErrorCode();
719 _ERR("Error occur : unknown error\n");
720 result = SCARD_ERROR_UNKNOWN;
728 EXTERN_API int session_open_basic_channel_sync(session_h handle, unsigned char *aid,
729 unsigned int length, unsigned char P2, int* channel_handle)
731 int result = SCARD_ERROR_OK;
733 SESSION_EXTERN_BEGIN;
737 *channel_handle = (long)session->openBasicChannelSync(aid, length, P2);
739 catch (ExceptionBase &e)
741 _ERR("Error occur : %s\n", e.what());
742 result = e.getErrorCode();
747 _ERR("Error occur : unknown error\n");
748 result = SCARD_ERROR_UNKNOWN;
757 EXTERN_API int session_open_logical_channel_sync(session_h handle, unsigned char *aid,
758 unsigned int length, unsigned char P2, int* channel_handle)
760 int result = SCARD_ERROR_OK;
762 SESSION_EXTERN_BEGIN;
766 *channel_handle = (long)session->openLogicalChannelSync(aid, length, P2);
768 catch (ExceptionBase &e)
770 _ERR("Error occur : %s\n", e.what());
771 result = e.getErrorCode();
776 _ERR("Error occur : unknown error\n");
777 result = SCARD_ERROR_UNKNOWN;
786 EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
790 SESSION_EXTERN_BEGIN;
791 result = session->getATR((getATRCallback)callback, userData);
797 EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
801 SESSION_EXTERN_BEGIN;
802 result = session->close((closeSessionCallback)callback, userData);
808 EXTERN_API int session_open_basic_channel(session_h handle, unsigned char *aid,
809 unsigned int length, session_open_channel_cb callback, void *userData)
813 SESSION_EXTERN_BEGIN;
814 result = session->openBasicChannel(aid, length, (openChannelCallback)callback, userData);
820 EXTERN_API int session_open_logical_channel(session_h handle, unsigned char *aid,
821 unsigned int length, session_open_channel_cb callback, void *userData)
825 SESSION_EXTERN_BEGIN;
826 result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
832 EXTERN_API size_t session_get_channel_count(session_h handle)
836 SESSION_EXTERN_BEGIN;
837 result = session->getChannelCount();
843 EXTERN_API void session_destroy_instance(session_h handle)