2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
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"
27 #include "ClientChannel.h"
28 #include "ReaderHelper.h"
29 #include "APDUHelper.h"
30 #include "ClientGDBus.h"
35 #define EXTERN_API __attribute__((visibility("default")))
38 namespace smartcard_service_api
40 ClientChannel::ClientChannel(void *context, Session *session,
41 int channelNum, const ByteArray &selectResponse, void *handle)
44 this->channelNum = -1;
50 _ERR("ClientIPC::getInstance() failed");
55 this->channelNum = channelNum;
56 this->handle = handle;
57 this->selectResponse = selectResponse;
58 this->context = context;
60 /* init default context */
63 proxy = smartcard_service_channel_proxy_new_for_bus_sync(
64 G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
65 "org.tizen.SmartcardService",
66 "/org/tizen/SmartcardService/Channel",
71 _ERR("Can not create proxy : %s", error->message);
78 ClientChannel::~ClientChannel()
83 void ClientChannel::channel_transmit_cb(GObject *source_object,
84 GAsyncResult *res, gpointer user_data)
86 CallbackParam *param = (CallbackParam *)user_data;
87 transmitCallback callback;
89 GVariant *var_response;
93 _INFO("MSG_REQUEST_TRANSMIT");
96 _ERR("null parameter!!!");
100 callback = (transmitCallback)param->callback;
102 if (smartcard_service_channel_call_transmit_finish(
103 SMARTCARD_SERVICE_CHANNEL(source_object),
104 &result, &var_response, res, &error) == true) {
105 if (result == SCARD_ERROR_OK) {
106 GDBusHelper::convertVariantToByteArray(var_response, response);
108 _ERR("smartcard_service_channel_call_transmit failed, [%d]", result);
112 _ERR("smartcard_service_channel_call_transmit failed, [%s]", error->message);
116 result = SCARD_ERROR_IPC_FAILED;
119 if (callback != NULL) {
120 callback(response.getBuffer(),
122 result, param->user_param);
128 void ClientChannel::channel_close_cb(GObject *source_object,
129 GAsyncResult *res, gpointer user_data)
131 CallbackParam *param = (CallbackParam *)user_data;
132 ClientChannel *channel;
133 closeChannelCallback callback;
135 GError *error = NULL;
137 _INFO("MSG_REQUEST_CLOSE_CHANNEL");
140 _ERR("null parameter!!!");
144 channel = (ClientChannel *)param->instance;
145 callback = (closeChannelCallback)param->callback;
147 if (smartcard_service_channel_call_close_channel_finish(
148 SMARTCARD_SERVICE_CHANNEL(source_object),
149 &result, res, &error) == true) {
150 if (result == SCARD_ERROR_OK) {
151 channel->channelNum = -1;
153 _ERR("smartcard_service_channel_call_close_channel failed, [%d]", result);
157 _ERR("smartcard_service_channel_call_close_channel failed, [%s]", error->message);
161 result = SCARD_ERROR_IPC_FAILED;
164 if (callback != NULL) {
165 callback(result, param->user_param);
171 void ClientChannel::closeSync()
173 if (isClosed() == false)
175 if (getSession()->getReader()->isSecureElementPresent() == true) {
177 GError *error = NULL;
181 _ERR("dbus proxy is not initialized yet");
182 throw ErrorIllegalState(SCARD_ERROR_NOT_INITIALIZED);
185 if (smartcard_service_channel_call_close_channel_sync(
186 (SmartcardServiceChannel *)proxy,
187 GPOINTER_TO_UINT(context),
188 GPOINTER_TO_UINT(handle),
189 &ret, NULL, &error) == true) {
190 if (ret == SCARD_ERROR_OK) {
193 _ERR("smartcard_service_channel_call_close_channel_sync failed, [%d]", ret);
198 _ERR("smartcard_service_channel_call_close_channel_sync failed, [%s]", error->message);
202 throw ErrorIO(SCARD_ERROR_IPC_FAILED);
205 _INFO("unavailable channel");
210 int ClientChannel::close(closeChannelCallback callback, void *userParam)
212 int result = SCARD_ERROR_OK;
214 if (isClosed() == false) {
215 if (getSession()->getReader()->isSecureElementPresent() == true) {
216 CallbackParam *param = new CallbackParam();
218 param->instance = this;
219 param->callback = (void *)callback;
220 param->user_param = userParam;
222 smartcard_service_channel_call_close_channel(
223 (SmartcardServiceChannel *)proxy,
224 GPOINTER_TO_UINT(context),
225 GPOINTER_TO_UINT(handle), NULL,
226 &ClientChannel::channel_close_cb, param);
228 _ERR("unavailable channel");
229 result = SCARD_ERROR_ILLEGAL_STATE;
236 int ClientChannel::transmitSync(const ByteArray &command, ByteArray &result)
238 int rv = SCARD_ERROR_OK;
240 if (getSession()->getReader()->isSecureElementPresent() == true) {
241 GVariant *var_command = NULL, *var_response = NULL;
242 GError *error = NULL;
244 var_command = GDBusHelper::convertByteArrayToVariant(command);
246 if (smartcard_service_channel_call_transmit_sync(
247 (SmartcardServiceChannel *)proxy,
248 GPOINTER_TO_UINT(context),
249 GPOINTER_TO_UINT(handle),
250 var_command, &rv, &var_response,
251 NULL, &error) == true) {
252 if (rv == SCARD_ERROR_OK) {
253 GDBusHelper::convertVariantToByteArray(var_response, transmitResponse);
254 result = transmitResponse;
256 _ERR("smartcard_service_session_call_transmit failed, [%d]", rv);
261 _ERR("smartcard_service_session_call_transmit failed, [%s]", error->message);
265 throw ErrorIO(SCARD_ERROR_IPC_FAILED);
268 _ERR("unavailable channel");
269 throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
275 int ClientChannel::transmit(const ByteArray &command, transmitCallback callback, void *userParam)
279 if (getSession()->getReader()->isSecureElementPresent() == true) {
280 GVariant *var_command;
281 CallbackParam *param = new CallbackParam();
283 param->instance = this;
284 param->callback = (void *)callback;
285 param->user_param = userParam;
287 var_command = GDBusHelper::convertByteArrayToVariant(command);
289 smartcard_service_channel_call_transmit(
290 (SmartcardServiceChannel *)proxy,
291 GPOINTER_TO_UINT(context),
292 GPOINTER_TO_UINT(handle),
294 &ClientChannel::channel_transmit_cb, param);
296 result = SCARD_ERROR_OK;
298 _ERR("unavailable channel");
299 result = SCARD_ERROR_ILLEGAL_STATE;
304 } /* namespace smartcard_service_api */
307 #define CHANNEL_EXTERN_BEGIN \
308 if (handle != NULL) \
310 ClientChannel *channel = (ClientChannel *)handle;
312 #define CHANNEL_EXTERN_END \
316 _ERR("Invalid param"); \
319 using namespace smartcard_service_api;
321 EXTERN_API int channel_close_sync(channel_h handle)
323 int result = SCARD_ERROR_OK;
325 CHANNEL_EXTERN_BEGIN;
329 channel->closeSync();
331 catch (ExceptionBase &e)
333 _ERR("Error occur : %s\n", e.what());
334 result = e.getErrorCode();
338 _ERR("Error occur : unknown error\n");
339 result = SCARD_ERROR_UNKNOWN;
347 EXTERN_API int channel_transmit_sync(channel_h handle, unsigned char *command,
348 unsigned int cmd_len, unsigned char **response, unsigned int *resp_len)
350 int result = SCARD_ERROR_OK;
352 if (command == NULL || cmd_len == 0 || response == NULL || resp_len == NULL)
353 return SCARD_ERROR_UNKNOWN;
355 CHANNEL_EXTERN_BEGIN;
359 ByteArray temp, resp;
361 temp.assign(command, cmd_len);
362 channel->transmitSync(temp, resp);
366 *response = (unsigned char *)calloc(resp.size(), sizeof(unsigned char));
367 *resp_len = resp.size();
368 memcpy(*response, resp.getBuffer(), *resp_len);
371 catch (ExceptionBase &e)
373 _ERR("Error occur : %s\n", e.what());
374 result = e.getErrorCode();
379 _ERR("Error occur : unknown error\n");
380 result = SCARD_ERROR_UNKNOWN;
389 EXTERN_API int channel_is_basic_channel(channel_h handle, bool* is_basic_channel)
391 int result = SCARD_ERROR_OK;
393 CHANNEL_EXTERN_BEGIN;
397 *is_basic_channel = channel->isBasicChannel();
399 catch (ExceptionBase &e)
401 _ERR("Error occur : %s\n", e.what());
402 result = e.getErrorCode();
406 _ERR("Error occur : unknown error\n");
407 result = SCARD_ERROR_UNKNOWN;
415 EXTERN_API int channel_is_closed(channel_h handle, bool* is_closed)
417 int result = SCARD_ERROR_OK;
419 CHANNEL_EXTERN_BEGIN;
423 *is_closed = channel->isClosed();
425 catch (ExceptionBase &e)
427 _ERR("Error occur : %s\n", e.what());
428 result = e.getErrorCode();
432 _ERR("Error occur : unknown error\n");
433 result = SCARD_ERROR_UNKNOWN;
441 EXTERN_API int channel_get_select_response(channel_h handle,
442 unsigned char **buffer, size_t *length)
444 int result = SCARD_ERROR_OK;
446 CHANNEL_EXTERN_BEGIN;
450 ByteArray response = channel->getSelectResponse();
451 uint8_t* get_buffer = response.getBuffer();
453 *length = response.size();
457 *buffer = (unsigned char *)calloc(*length, sizeof(unsigned char));
458 if(*buffer == NULL || get_buffer == NULL)
461 return SCARD_ERROR_NOT_ENOUGH_RESOURCE;
464 memcpy(*buffer, get_buffer, *length);
467 catch (ExceptionBase &e)
469 _ERR("Error occur : %s\n", e.what());
470 result = e.getErrorCode();
475 _ERR("Error occur : unknown error\n");
476 result = SCARD_ERROR_UNKNOWN;
485 EXTERN_API int channel_get_transmit_response(channel_h handle,
486 unsigned char **buffer, size_t *length)
488 int result = SCARD_ERROR_OK;
490 CHANNEL_EXTERN_BEGIN;
496 response = channel->getTransmitResponse();
498 *length = response.size();
502 *buffer = (unsigned char *)calloc(*length, sizeof(unsigned char));
503 memcpy(*buffer, response.getBuffer(), *length);
506 catch (ExceptionBase &e)
508 _ERR("Error occur : %s\n", e.what());
509 result = e.getErrorCode();
514 _ERR("Error occur : unknown error\n");
515 result = SCARD_ERROR_UNKNOWN;
524 EXTERN_API int channel_get_session(channel_h handle, int *session_handle)
526 int result = SCARD_ERROR_OK;
527 session_h session = NULL;
529 CHANNEL_EXTERN_BEGIN;
533 session = channel->getSession();
534 *session_handle = (long)session;
536 catch (ExceptionBase &e)
538 _ERR("Error occur : %s\n", e.what());
539 result = e.getErrorCode();
543 _ERR("Error occur : unknown error\n");
544 result = SCARD_ERROR_UNKNOWN;
552 EXTERN_API int channel_select_next(channel_h handle, bool *pSuccess)
554 int result = SCARD_ERROR_OK;
556 CHANNEL_EXTERN_BEGIN;
560 *pSuccess = channel->selectNext();
562 catch (ExceptionBase &e)
564 _ERR("Error occur : %s\n", e.what());
565 result = e.getErrorCode();
569 _ERR("Error occur : unknown error\n");
570 result = SCARD_ERROR_UNKNOWN;
578 EXTERN_API unsigned int channel_get_select_response_length(channel_h handle)
580 unsigned int result = 0;
582 CHANNEL_EXTERN_BEGIN;
583 result = channel->getSelectResponse().size();
589 EXTERN_API int channel_close(channel_h handle, channel_close_cb callback, void *userParam)
593 CHANNEL_EXTERN_BEGIN;
594 result = channel->close((closeChannelCallback)callback, userParam);
600 EXTERN_API int channel_transmit(channel_h handle, unsigned char *command,
601 unsigned int length, channel_transmit_cb callback, void *userParam)
605 CHANNEL_EXTERN_BEGIN;
608 temp.assign(command, length);
609 result = channel->transmit(temp, (transmitCallback)callback, userParam);
615 EXTERN_API void channel_destroy_instance(channel_h handle)