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 /* initialize client */
59 if (!g_thread_supported())
66 /* init default context */
69 proxy = smartcard_service_channel_proxy_new_for_bus_sync(
70 G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
71 "org.tizen.SmartcardService",
72 "/org/tizen/SmartcardService/Channel",
76 _ERR("Can not create proxy : %s", error->message);
82 ClientChannel::~ClientChannel()
87 void ClientChannel::channel_transmit_cb(GObject *source_object,
88 GAsyncResult *res, gpointer user_data)
90 CallbackParam *param = (CallbackParam *)user_data;
91 transmitCallback callback;
93 GVariant *var_response;
97 _INFO("MSG_REQUEST_TRANSMIT");
100 _ERR("null parameter!!!");
104 callback = (transmitCallback)param->callback;
106 if (smartcard_service_channel_call_transmit_finish(
107 SMARTCARD_SERVICE_CHANNEL(source_object),
108 &result, &var_response, res, &error) == true) {
109 if (result == SCARD_ERROR_OK) {
110 GDBusHelper::convertVariantToByteArray(var_response, response);
112 _ERR("smartcard_service_channel_call_transmit failed, [%d]", result);
115 _ERR("smartcard_service_channel_call_transmit failed, [%s]", error->message);
118 result = SCARD_ERROR_IPC_FAILED;
121 if (callback != NULL) {
122 callback(response.getBuffer(),
124 result, param->user_param);
130 void ClientChannel::channel_close_cb(GObject *source_object,
131 GAsyncResult *res, gpointer user_data)
133 CallbackParam *param = (CallbackParam *)user_data;
134 ClientChannel *channel;
135 closeChannelCallback callback;
137 GError *error = NULL;
139 _INFO("MSG_REQUEST_CLOSE_CHANNEL");
142 _ERR("null parameter!!!");
146 channel = (ClientChannel *)param->instance;
147 callback = (closeChannelCallback)param->callback;
149 if (smartcard_service_channel_call_close_channel_finish(
150 SMARTCARD_SERVICE_CHANNEL(source_object),
151 &result, res, &error) == true) {
152 if (result == SCARD_ERROR_OK) {
153 channel->channelNum = -1;
155 _ERR("smartcard_service_channel_call_close_channel failed, [%d]", result);
158 _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()
172 throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
173 ErrorIllegalState &, ErrorIllegalParameter &)
175 if (isClosed() == false)
177 if (getSession()->getReader()->isSecureElementPresent() == true)
180 GError *error = NULL;
183 _ERR("dbus proxy is not initialized yet");
184 throw ErrorIllegalState(SCARD_ERROR_NOT_INITIALIZED);
187 if (smartcard_service_channel_call_close_channel_sync(
188 (SmartcardServiceChannel *)proxy,
189 GPOINTER_TO_UINT(context),
190 GPOINTER_TO_UINT(handle),
191 &ret, NULL, &error) == true) {
192 if (ret != SCARD_ERROR_OK) {
193 _ERR("smartcard_service_channel_call_close_channel_sync failed, [%d]", ret);
197 _ERR("smartcard_service_channel_call_close_channel_sync failed, [%s]", error->message);
200 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)
216 if (getSession()->getReader()->isSecureElementPresent() == true)
218 CallbackParam *param = new CallbackParam();
220 param->instance = this;
221 param->callback = (void *)callback;
222 param->user_param = userParam;
224 smartcard_service_channel_call_close_channel(
225 (SmartcardServiceChannel *)proxy,
226 GPOINTER_TO_UINT(context),
227 GPOINTER_TO_UINT(handle), NULL,
228 &ClientChannel::channel_close_cb, param);
232 _ERR("unavailable channel");
233 result = SCARD_ERROR_ILLEGAL_STATE;
240 int ClientChannel::transmitSync(const ByteArray &command, ByteArray &result)
241 throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
242 ErrorIllegalParameter &, ErrorSecurity &)
244 int rv = SCARD_ERROR_OK;
246 if (getSession()->getReader()->isSecureElementPresent() == true)
248 GVariant *var_command = NULL, *var_response = NULL;
249 GError *error = NULL;
251 var_command = GDBusHelper::convertByteArrayToVariant(command);
253 if (smartcard_service_channel_call_transmit_sync(
254 (SmartcardServiceChannel *)proxy,
255 GPOINTER_TO_UINT(context),
256 GPOINTER_TO_UINT(handle),
257 var_command, &rv, &var_response,
258 NULL, &error) == true) {
260 if (rv == SCARD_ERROR_OK) {
261 GDBusHelper::convertVariantToByteArray(var_response, result);
263 _ERR("smartcard_service_session_call_get_atr_sync failed, [%d]", rv);
267 _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
270 throw ErrorIO(SCARD_ERROR_IPC_FAILED);
275 _ERR("unavailable channel");
276 throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
282 int ClientChannel::transmit(const ByteArray &command, transmitCallback callback, void *userParam)
286 if (getSession()->getReader()->isSecureElementPresent() == true)
288 GVariant *var_command;
289 CallbackParam *param = new CallbackParam();
291 param->instance = this;
292 param->callback = (void *)callback;
293 param->user_param = userParam;
295 var_command = GDBusHelper::convertByteArrayToVariant(command);
297 smartcard_service_channel_call_transmit(
298 (SmartcardServiceChannel *)proxy,
299 GPOINTER_TO_UINT(context),
300 GPOINTER_TO_UINT(handle),
302 &ClientChannel::channel_transmit_cb, param);
304 result = SCARD_ERROR_OK;
308 _ERR("unavailable channel");
309 result = SCARD_ERROR_ILLEGAL_STATE;
314 } /* namespace smartcard_service_api */
317 #define CHANNEL_EXTERN_BEGIN \
318 if (handle != NULL) \
320 ClientChannel *channel = (ClientChannel *)handle;
322 #define CHANNEL_EXTERN_END \
326 _ERR("Invalid param"); \
329 using namespace smartcard_service_api;
331 EXTERN_API int channel_close(channel_h handle, channel_close_cb callback, void *userParam)
335 CHANNEL_EXTERN_BEGIN;
336 result = channel->close((closeChannelCallback)callback, userParam);
342 EXTERN_API int channel_transmit(channel_h handle, unsigned char *command,
343 unsigned int length, channel_transmit_cb callback, void *userParam)
347 CHANNEL_EXTERN_BEGIN;
350 temp.assign(command, length);
351 result = channel->transmit(temp, (transmitCallback)callback, userParam);
357 EXTERN_API void channel_close_sync(channel_h handle)
359 CHANNEL_EXTERN_BEGIN;
362 channel->closeSync();
370 EXTERN_API int channel_transmit_sync(channel_h handle, unsigned char *command,
371 unsigned int cmd_len, unsigned char **response, unsigned int *resp_len)
375 if (command == NULL || cmd_len == 0 || response == NULL || resp_len == NULL)
378 CHANNEL_EXTERN_BEGIN;
379 ByteArray temp, resp;
381 temp.assign(command, cmd_len);
385 result = channel->transmitSync(temp, resp);
388 *resp_len = resp.size();
389 *response = (unsigned char *)calloc(1, *resp_len);
390 memcpy(*response, resp.getBuffer(), *resp_len);
402 EXTERN_API bool channel_is_basic_channel(channel_h handle)
406 CHANNEL_EXTERN_BEGIN;
407 result = channel->isBasicChannel();
413 EXTERN_API bool channel_is_closed(channel_h handle)
417 CHANNEL_EXTERN_BEGIN;
418 result = channel->isClosed();
424 EXTERN_API unsigned int channel_get_select_response_length(channel_h handle)
426 unsigned int result = 0;
428 CHANNEL_EXTERN_BEGIN;
429 result = channel->getSelectResponse().size();
435 EXTERN_API bool channel_get_select_response(channel_h handle,
436 unsigned char *buffer, unsigned int length)
440 if (buffer == NULL || length == 0)
445 CHANNEL_EXTERN_BEGIN;
448 response = channel->getSelectResponse();
449 if (response.size() > 0)
451 memcpy(buffer, response.getBuffer(), MIN(length, response.size()));
459 EXTERN_API session_h channel_get_session(channel_h handle)
461 session_h session = NULL;
463 CHANNEL_EXTERN_BEGIN;
464 session = channel->getSession();
470 EXTERN_API void channel_destroy_instance(channel_h handle)