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.
23 #include "ClientChannel.h"
24 #include "ReaderHelper.h"
25 #include "APDUHelper.h"
26 #include "ClientGDBus.h"
29 #define EXTERN_API __attribute__((visibility("default")))
32 namespace smartcard_service_api
34 ClientChannel::ClientChannel(void *context, Session *session,
35 int channelNum, const ByteArray &selectResponse, void *handle)
38 this->channelNum = -1;
44 _ERR("ClientIPC::getInstance() failed");
49 this->channelNum = channelNum;
50 this->handle = handle;
51 this->selectResponse = selectResponse;
52 this->context = context;
54 /* init default context */
57 proxy = smartcard_service_channel_proxy_new_for_bus_sync(
58 G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
59 "org.tizen.SmartcardService",
60 "/org/tizen/SmartcardService/Channel",
64 _ERR("Can not create proxy : %s", error->message);
70 ClientChannel::~ClientChannel()
75 void ClientChannel::channel_transmit_cb(GObject *source_object,
76 GAsyncResult *res, gpointer user_data)
78 CallbackParam *param = (CallbackParam *)user_data;
79 transmitCallback callback;
81 GVariant *var_response;
85 _INFO("MSG_REQUEST_TRANSMIT");
88 _ERR("null parameter!!!");
92 callback = (transmitCallback)param->callback;
94 if (smartcard_service_channel_call_transmit_finish(
95 SMARTCARD_SERVICE_CHANNEL(source_object),
96 &result, &var_response, res, &error) == true) {
97 if (result == SCARD_ERROR_OK) {
98 GDBusHelper::convertVariantToByteArray(var_response, response);
100 _ERR("smartcard_service_channel_call_transmit failed, [%d]", result);
103 _ERR("smartcard_service_channel_call_transmit failed, [%s]", error->message);
106 result = SCARD_ERROR_IPC_FAILED;
109 if (callback != NULL) {
110 callback(response.getBuffer(),
112 result, param->user_param);
118 void ClientChannel::channel_close_cb(GObject *source_object,
119 GAsyncResult *res, gpointer user_data)
121 CallbackParam *param = (CallbackParam *)user_data;
122 ClientChannel *channel;
123 closeChannelCallback callback;
125 GError *error = NULL;
127 _INFO("MSG_REQUEST_CLOSE_CHANNEL");
130 _ERR("null parameter!!!");
134 channel = (ClientChannel *)param->instance;
135 callback = (closeChannelCallback)param->callback;
137 if (smartcard_service_channel_call_close_channel_finish(
138 SMARTCARD_SERVICE_CHANNEL(source_object),
139 &result, res, &error) == true) {
140 if (result == SCARD_ERROR_OK) {
141 channel->channelNum = -1;
143 _ERR("smartcard_service_channel_call_close_channel failed, [%d]", result);
146 _ERR("smartcard_service_channel_call_close_channel failed, [%s]", error->message);
149 result = SCARD_ERROR_IPC_FAILED;
152 if (callback != NULL) {
153 callback(result, param->user_param);
159 void ClientChannel::closeSync()
160 throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
161 ErrorIllegalState &, ErrorIllegalParameter &)
163 if (isClosed() == false)
165 if (getSession()->getReader()->isSecureElementPresent() == true)
168 GError *error = NULL;
171 _ERR("dbus proxy is not initialized yet");
172 throw ErrorIllegalState(SCARD_ERROR_NOT_INITIALIZED);
175 if (smartcard_service_channel_call_close_channel_sync(
176 (SmartcardServiceChannel *)proxy,
177 GPOINTER_TO_UINT(context),
178 GPOINTER_TO_UINT(handle),
179 &ret, NULL, &error) == true) {
180 if (ret != SCARD_ERROR_OK) {
181 _ERR("smartcard_service_channel_call_close_channel_sync failed, [%d]", ret);
185 _ERR("smartcard_service_channel_call_close_channel_sync failed, [%s]", error->message);
188 throw ErrorIO(SCARD_ERROR_IPC_FAILED);
193 _INFO("unavailable channel");
198 int ClientChannel::close(closeChannelCallback callback, void *userParam)
200 int result = SCARD_ERROR_OK;
202 if (isClosed() == false)
204 if (getSession()->getReader()->isSecureElementPresent() == true)
206 CallbackParam *param = new CallbackParam();
208 param->instance = this;
209 param->callback = (void *)callback;
210 param->user_param = userParam;
212 smartcard_service_channel_call_close_channel(
213 (SmartcardServiceChannel *)proxy,
214 GPOINTER_TO_UINT(context),
215 GPOINTER_TO_UINT(handle), NULL,
216 &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)
236 GVariant *var_command = NULL, *var_response = NULL;
237 GError *error = NULL;
239 var_command = GDBusHelper::convertByteArrayToVariant(command);
241 if (smartcard_service_channel_call_transmit_sync(
242 (SmartcardServiceChannel *)proxy,
243 GPOINTER_TO_UINT(context),
244 GPOINTER_TO_UINT(handle),
245 var_command, &rv, &var_response,
246 NULL, &error) == true) {
248 if (rv == SCARD_ERROR_OK) {
249 GDBusHelper::convertVariantToByteArray(var_response, result);
251 _ERR("smartcard_service_session_call_get_atr_sync failed, [%d]", rv);
255 _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
258 throw ErrorIO(SCARD_ERROR_IPC_FAILED);
263 _ERR("unavailable channel");
264 throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
270 int ClientChannel::transmit(const ByteArray &command, transmitCallback callback, void *userParam)
274 if (getSession()->getReader()->isSecureElementPresent() == true)
276 GVariant *var_command;
277 CallbackParam *param = new CallbackParam();
279 param->instance = this;
280 param->callback = (void *)callback;
281 param->user_param = userParam;
283 var_command = GDBusHelper::convertByteArrayToVariant(command);
285 smartcard_service_channel_call_transmit(
286 (SmartcardServiceChannel *)proxy,
287 GPOINTER_TO_UINT(context),
288 GPOINTER_TO_UINT(handle),
290 &ClientChannel::channel_transmit_cb, param);
292 result = SCARD_ERROR_OK;
296 _ERR("unavailable channel");
297 result = SCARD_ERROR_ILLEGAL_STATE;
302 } /* namespace smartcard_service_api */
305 #define CHANNEL_EXTERN_BEGIN \
306 if (handle != NULL) \
308 ClientChannel *channel = (ClientChannel *)handle;
310 #define CHANNEL_EXTERN_END \
314 _ERR("Invalid param"); \
317 using namespace smartcard_service_api;
319 EXTERN_API int channel_close(channel_h handle, channel_close_cb callback, void *userParam)
323 CHANNEL_EXTERN_BEGIN;
324 result = channel->close((closeChannelCallback)callback, userParam);
330 EXTERN_API int channel_transmit(channel_h handle, unsigned char *command,
331 unsigned int length, channel_transmit_cb callback, void *userParam)
335 CHANNEL_EXTERN_BEGIN;
338 temp.assign(command, length);
339 result = channel->transmit(temp, (transmitCallback)callback, userParam);
345 EXTERN_API void channel_close_sync(channel_h handle)
347 CHANNEL_EXTERN_BEGIN;
350 channel->closeSync();
358 EXTERN_API int channel_transmit_sync(channel_h handle, unsigned char *command,
359 unsigned int cmd_len, unsigned char **response, unsigned int *resp_len)
363 if (command == NULL || cmd_len == 0 || response == NULL || resp_len == NULL)
366 CHANNEL_EXTERN_BEGIN;
367 ByteArray temp, resp;
369 temp.assign(command, cmd_len);
373 result = channel->transmitSync(temp, resp);
376 *resp_len = resp.size();
377 *response = (unsigned char *)calloc(1, *resp_len);
378 memcpy(*response, resp.getBuffer(), *resp_len);
390 EXTERN_API bool channel_is_basic_channel(channel_h handle)
394 CHANNEL_EXTERN_BEGIN;
395 result = channel->isBasicChannel();
401 EXTERN_API bool channel_is_closed(channel_h handle)
405 CHANNEL_EXTERN_BEGIN;
406 result = channel->isClosed();
412 EXTERN_API unsigned int channel_get_select_response_length(channel_h handle)
414 unsigned int result = 0;
416 CHANNEL_EXTERN_BEGIN;
417 result = channel->getSelectResponse().size();
423 EXTERN_API bool channel_get_select_response(channel_h handle,
424 unsigned char *buffer, unsigned int length)
428 if (buffer == NULL || length == 0)
433 CHANNEL_EXTERN_BEGIN;
436 response = channel->getSelectResponse();
437 if (response.size() > 0)
439 memcpy(buffer, response.getBuffer(), MIN(length, response.size()));
447 EXTERN_API session_h channel_get_session(channel_h handle)
449 session_h session = NULL;
451 CHANNEL_EXTERN_BEGIN;
452 session = channel->getSession();
458 EXTERN_API void channel_destroy_instance(channel_h handle)