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 */
27 #include "ClientChannel.h"
28 #include "ReaderHelper.h"
29 #include "APDUHelper.h"
30 #include "ClientGDBus.h"
33 #define EXTERN_API __attribute__((visibility("default")))
36 namespace smartcard_service_api
38 ClientChannel::ClientChannel(void *context, Session *session,
39 int channelNum, const ByteArray &selectResponse, void *handle)
42 this->channelNum = -1;
48 _ERR("ClientIPC::getInstance() failed");
53 this->channelNum = channelNum;
54 this->handle = handle;
55 this->selectResponse = selectResponse;
56 this->context = context;
58 /* init default context */
61 proxy = smartcard_service_channel_proxy_new_for_bus_sync(
62 G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
63 "org.tizen.SmartcardService",
64 "/org/tizen/SmartcardService/Channel",
68 _ERR("Can not create proxy : %s", error->message);
74 ClientChannel::~ClientChannel()
79 void ClientChannel::channel_transmit_cb(GObject *source_object,
80 GAsyncResult *res, gpointer user_data)
82 CallbackParam *param = (CallbackParam *)user_data;
83 transmitCallback callback;
85 GVariant *var_response;
89 _INFO("MSG_REQUEST_TRANSMIT");
92 _ERR("null parameter!!!");
96 callback = (transmitCallback)param->callback;
98 if (smartcard_service_channel_call_transmit_finish(
99 SMARTCARD_SERVICE_CHANNEL(source_object),
100 &result, &var_response, res, &error) == true) {
101 if (result == SCARD_ERROR_OK) {
102 GDBusHelper::convertVariantToByteArray(var_response, response);
104 _ERR("smartcard_service_channel_call_transmit failed, [%d]", result);
107 _ERR("smartcard_service_channel_call_transmit failed, [%s]", error->message);
110 result = SCARD_ERROR_IPC_FAILED;
113 if (callback != NULL) {
114 callback(response.getBuffer(),
116 result, param->user_param);
122 void ClientChannel::channel_close_cb(GObject *source_object,
123 GAsyncResult *res, gpointer user_data)
125 CallbackParam *param = (CallbackParam *)user_data;
126 ClientChannel *channel;
127 closeChannelCallback callback;
129 GError *error = NULL;
131 _INFO("MSG_REQUEST_CLOSE_CHANNEL");
134 _ERR("null parameter!!!");
138 channel = (ClientChannel *)param->instance;
139 callback = (closeChannelCallback)param->callback;
141 if (smartcard_service_channel_call_close_channel_finish(
142 SMARTCARD_SERVICE_CHANNEL(source_object),
143 &result, res, &error) == true) {
144 if (result == SCARD_ERROR_OK) {
145 channel->channelNum = -1;
147 _ERR("smartcard_service_channel_call_close_channel failed, [%d]", result);
150 _ERR("smartcard_service_channel_call_close_channel failed, [%s]", error->message);
153 result = SCARD_ERROR_IPC_FAILED;
156 if (callback != NULL) {
157 callback(result, param->user_param);
163 void ClientChannel::closeSync()
164 throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
165 ErrorIllegalState &, ErrorIllegalParameter &)
167 if (isClosed() == false)
169 if (getSession()->getReader()->isSecureElementPresent() == true) {
171 GError *error = NULL;
175 _ERR("dbus proxy is not initialized yet");
176 throw ErrorIllegalState(SCARD_ERROR_NOT_INITIALIZED);
179 if (smartcard_service_channel_call_close_channel_sync(
180 (SmartcardServiceChannel *)proxy,
181 GPOINTER_TO_UINT(context),
182 GPOINTER_TO_UINT(handle),
183 &ret, NULL, &error) == true) {
184 if (ret == SCARD_ERROR_OK) {
187 _ERR("smartcard_service_channel_call_close_channel_sync failed, [%d]", ret);
191 _ERR("smartcard_service_channel_call_close_channel_sync failed, [%s]", error->message);
194 throw ErrorIO(SCARD_ERROR_IPC_FAILED);
197 _INFO("unavailable channel");
202 int ClientChannel::close(closeChannelCallback callback, void *userParam)
204 int result = SCARD_ERROR_OK;
206 if (isClosed() == false) {
207 if (getSession()->getReader()->isSecureElementPresent() == true) {
208 CallbackParam *param = new CallbackParam();
210 param->instance = this;
211 param->callback = (void *)callback;
212 param->user_param = userParam;
214 smartcard_service_channel_call_close_channel(
215 (SmartcardServiceChannel *)proxy,
216 GPOINTER_TO_UINT(context),
217 GPOINTER_TO_UINT(handle), NULL,
218 &ClientChannel::channel_close_cb, param);
220 _ERR("unavailable channel");
221 result = SCARD_ERROR_ILLEGAL_STATE;
228 int ClientChannel::transmitSync(const ByteArray &command, ByteArray &result)
229 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
230 ErrorIllegalParameter &, ErrorSecurity &)
232 int rv = SCARD_ERROR_OK;
234 if (getSession()->getReader()->isSecureElementPresent() == true) {
235 GVariant *var_command = NULL, *var_response = NULL;
236 GError *error = NULL;
238 var_command = GDBusHelper::convertByteArrayToVariant(command);
240 if (smartcard_service_channel_call_transmit_sync(
241 (SmartcardServiceChannel *)proxy,
242 GPOINTER_TO_UINT(context),
243 GPOINTER_TO_UINT(handle),
244 var_command, &rv, &var_response,
245 NULL, &error) == true) {
246 if (rv == SCARD_ERROR_OK) {
247 GDBusHelper::convertVariantToByteArray(var_response, transmitResponse);
248 result = transmitResponse;
250 _ERR("smartcard_service_session_call_transmit failed, [%d]", rv);
254 _ERR("smartcard_service_session_call_transmit failed, [%s]", error->message);
257 throw ErrorIO(SCARD_ERROR_IPC_FAILED);
260 _ERR("unavailable channel");
261 throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
267 int ClientChannel::transmit(const ByteArray &command, transmitCallback callback, void *userParam)
271 if (getSession()->getReader()->isSecureElementPresent() == true) {
272 GVariant *var_command;
273 CallbackParam *param = new CallbackParam();
275 param->instance = this;
276 param->callback = (void *)callback;
277 param->user_param = userParam;
279 var_command = GDBusHelper::convertByteArrayToVariant(command);
281 smartcard_service_channel_call_transmit(
282 (SmartcardServiceChannel *)proxy,
283 GPOINTER_TO_UINT(context),
284 GPOINTER_TO_UINT(handle),
286 &ClientChannel::channel_transmit_cb, param);
288 result = SCARD_ERROR_OK;
290 _ERR("unavailable channel");
291 result = SCARD_ERROR_ILLEGAL_STATE;
296 } /* namespace smartcard_service_api */
299 #define CHANNEL_EXTERN_BEGIN \
300 if (handle != NULL) \
302 ClientChannel *channel = (ClientChannel *)handle;
304 #define CHANNEL_EXTERN_END \
308 _ERR("Invalid param"); \
311 using namespace smartcard_service_api;
313 EXTERN_API int channel_close_sync(channel_h handle)
315 int result = SCARD_ERROR_OK;
317 CHANNEL_EXTERN_BEGIN;
321 channel->closeSync();
323 catch (ExceptionBase &e)
325 _ERR("Error occur : %s\n", e.what());
326 result = e.getErrorCode();
330 _ERR("Error occur : unknown error\n");
331 result = SCARD_ERROR_UNKNOWN;
339 EXTERN_API int channel_transmit_sync(channel_h handle, unsigned char *command,
340 unsigned int cmd_len, unsigned char **response, unsigned int *resp_len)
342 int result = SCARD_ERROR_OK;
344 if (command == NULL || cmd_len == 0 || response == NULL || resp_len == NULL)
345 return SCARD_ERROR_UNKNOWN;
347 CHANNEL_EXTERN_BEGIN;
351 ByteArray temp, resp;
353 temp.assign(command, cmd_len);
354 channel->transmitSync(temp, resp);
358 *response = (unsigned char *)calloc(resp.size(), sizeof(unsigned char));
359 *resp_len = resp.size();
360 memcpy(*response, resp.getBuffer(), *resp_len);
363 catch (ExceptionBase &e)
365 _ERR("Error occur : %s\n", e.what());
366 result = e.getErrorCode();
371 _ERR("Error occur : unknown error\n");
372 result = SCARD_ERROR_UNKNOWN;
381 EXTERN_API int channel_is_basic_channel(channel_h handle, bool* is_basic_channel)
383 int result = SCARD_ERROR_OK;
385 CHANNEL_EXTERN_BEGIN;
389 *is_basic_channel = channel->isBasicChannel();
391 catch (ExceptionBase &e)
393 _ERR("Error occur : %s\n", e.what());
394 result = e.getErrorCode();
398 _ERR("Error occur : unknown error\n");
399 result = SCARD_ERROR_UNKNOWN;
407 EXTERN_API int channel_is_closed(channel_h handle, bool* is_closed)
409 int result = SCARD_ERROR_OK;
411 CHANNEL_EXTERN_BEGIN;
415 *is_closed = channel->isClosed();
417 catch (ExceptionBase &e)
419 _ERR("Error occur : %s\n", e.what());
420 result = e.getErrorCode();
424 _ERR("Error occur : unknown error\n");
425 result = SCARD_ERROR_UNKNOWN;
433 EXTERN_API int channel_get_select_response(channel_h handle,
434 unsigned char **buffer, size_t *length)
436 int result = SCARD_ERROR_OK;
438 CHANNEL_EXTERN_BEGIN;
442 ByteArray response = channel->getSelectResponse();
443 uint8_t* get_buffer = response.getBuffer();
445 *length = response.size();
449 *buffer = (unsigned char *)calloc(*length, sizeof(unsigned char));
450 if(*buffer == NULL || get_buffer == NULL)
453 return SCARD_ERROR_NOT_ENOUGH_RESOURCE;
456 memcpy(*buffer, get_buffer, *length);
459 catch (ExceptionBase &e)
461 _ERR("Error occur : %s\n", e.what());
462 result = e.getErrorCode();
467 _ERR("Error occur : unknown error\n");
468 result = SCARD_ERROR_UNKNOWN;
477 EXTERN_API int channel_get_transmit_response(channel_h handle,
478 unsigned char **buffer, size_t *length)
480 int result = SCARD_ERROR_OK;
482 CHANNEL_EXTERN_BEGIN;
488 response = channel->getTransmitResponse();
490 *length = response.size();
494 *buffer = (unsigned char *)calloc(*length, sizeof(unsigned char));
495 memcpy(*buffer, response.getBuffer(), *length);
498 catch (ExceptionBase &e)
500 _ERR("Error occur : %s\n", e.what());
501 result = e.getErrorCode();
506 _ERR("Error occur : unknown error\n");
507 result = SCARD_ERROR_UNKNOWN;
516 EXTERN_API int channel_get_session(channel_h handle, int *session_handle)
518 int result = SCARD_ERROR_OK;
519 session_h session = NULL;
521 CHANNEL_EXTERN_BEGIN;
525 session = channel->getSession();
526 *session_handle = (long)session;
528 catch (ExceptionBase &e)
530 _ERR("Error occur : %s\n", e.what());
531 result = e.getErrorCode();
535 _ERR("Error occur : unknown error\n");
536 result = SCARD_ERROR_UNKNOWN;
544 EXTERN_API int channel_select_next(channel_h handle, bool *pSuccess)
546 int result = SCARD_ERROR_OK;
548 CHANNEL_EXTERN_BEGIN;
552 *pSuccess = channel->selectNext();
554 catch (ExceptionBase &e)
556 _ERR("Error occur : %s\n", e.what());
557 result = e.getErrorCode();
561 _ERR("Error occur : unknown error\n");
562 result = SCARD_ERROR_UNKNOWN;
570 EXTERN_API unsigned int channel_get_select_response_length(channel_h handle)
572 unsigned int result = 0;
574 CHANNEL_EXTERN_BEGIN;
575 result = channel->getSelectResponse().size();
581 EXTERN_API int channel_close(channel_h handle, channel_close_cb callback, void *userParam)
585 CHANNEL_EXTERN_BEGIN;
586 result = channel->close((closeChannelCallback)callback, userParam);
592 EXTERN_API int channel_transmit(channel_h handle, unsigned char *command,
593 unsigned int length, channel_transmit_cb callback, void *userParam)
597 CHANNEL_EXTERN_BEGIN;
600 temp.assign(command, length);
601 result = channel->transmit(temp, (transmitCallback)callback, userParam);
607 EXTERN_API void channel_destroy_instance(channel_h handle)