#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <glib.h>
/* SLP library header */
/* local header */
#include "Debug.h"
-#include "Message.h"
-#include "ClientIPC.h"
#include "ClientChannel.h"
#include "ReaderHelper.h"
#include "APDUHelper.h"
+#include "ClientGDBus.h"
#ifndef EXTERN_API
#define EXTERN_API __attribute__((visibility("default")))
namespace smartcard_service_api
{
ClientChannel::ClientChannel(void *context, Session *session,
- int channelNum, ByteArray selectResponse, void *handle)
+ int channelNum, const ByteArray &selectResponse, void *handle)
: Channel(session)
{
this->channelNum = -1;
if (handle == NULL)
{
- SCARD_DEBUG_ERR("ClientIPC::getInstance() failed");
+ _ERR("ClientIPC::getInstance() failed");
return;
}
this->handle = handle;
this->selectResponse = selectResponse;
this->context = context;
+
+ /* init default context */
+ GError *error = NULL;
+
+ proxy = smartcard_service_channel_proxy_new_for_bus_sync(
+ G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
+ "org.tizen.SmartcardService",
+ "/org/tizen/SmartcardService/Channel",
+ NULL, &error);
+ if (proxy == NULL)
+ {
+ _ERR("Can not create proxy : %s", error->message);
+ g_error_free(error);
+ return;
+ }
}
ClientChannel::~ClientChannel()
closeSync();
}
- void ClientChannel::closeSync() throw(ErrorIO &, ErrorIllegalState &)
+ void ClientChannel::channel_transmit_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+ {
+ CallbackParam *param = (CallbackParam *)user_data;
+ transmitCallback callback;
+ gint result;
+ GVariant *var_response;
+ GError *error = NULL;
+ ByteArray response;
+
+ _INFO("MSG_REQUEST_TRANSMIT");
+
+ if (param == NULL) {
+ _ERR("null parameter!!!");
+ return;
+ }
+
+ callback = (transmitCallback)param->callback;
+
+ if (smartcard_service_channel_call_transmit_finish(
+ SMARTCARD_SERVICE_CHANNEL(source_object),
+ &result, &var_response, res, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ GDBusHelper::convertVariantToByteArray(var_response, response);
+ } else {
+ _ERR("smartcard_service_channel_call_transmit failed, [%d]", result);
+ }
+ } else {
+ _ERR("smartcard_service_channel_call_transmit failed, [%s]", error->message);
+ g_error_free(error);
+
+ result = SCARD_ERROR_IPC_FAILED;
+ }
+
+ if (callback != NULL) {
+ callback(response.getBuffer(),
+ response.size(),
+ result, param->user_param);
+ }
+
+ delete param;
+ }
+
+ void ClientChannel::channel_close_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+ {
+ CallbackParam *param = (CallbackParam *)user_data;
+ ClientChannel *channel;
+ closeChannelCallback callback;
+ gint result;
+ GError *error = NULL;
+
+ _INFO("MSG_REQUEST_CLOSE_CHANNEL");
+
+ if (param == NULL) {
+ _ERR("null parameter!!!");
+ return;
+ }
+
+ channel = (ClientChannel *)param->instance;
+ callback = (closeChannelCallback)param->callback;
+
+ if (smartcard_service_channel_call_close_channel_finish(
+ SMARTCARD_SERVICE_CHANNEL(source_object),
+ &result, res, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ channel->channelNum = -1;
+ } else {
+ _ERR("smartcard_service_channel_call_close_channel failed, [%d]", result);
+ }
+ } else {
+ _ERR("smartcard_service_channel_call_close_channel failed, [%s]", error->message);
+ g_error_free(error);
+
+ result = SCARD_ERROR_IPC_FAILED;
+ }
+
+ if (callback != NULL) {
+ callback(result, param->user_param);
+ }
+
+ delete param;
+ }
+
+ void ClientChannel::closeSync()
+ throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
+ ErrorIllegalState &, ErrorIllegalParameter &)
{
-#ifdef CLIENT_IPC_THREAD
if (isClosed() == false)
{
if (getSession()->getReader()->isSecureElementPresent() == true)
{
- Message msg;
- int rv;
-
- /* send message to server */
- msg.message = Message::MSG_REQUEST_CLOSE_CHANNEL;
- msg.param1 = (unsigned long)handle;
- msg.error = (unsigned long)context; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
-
- syncLock();
- if (ClientIPC::getInstance().sendMessage(&msg) == true)
- {
- rv = waitTimedCondition(0);
- if (rv < 0)
- {
- SCARD_DEBUG_ERR("closeSync failed [%d]", rv);
- this->error = SCARD_ERROR_OPERATION_TIMEOUT;
- }
- }
- else
- {
- SCARD_DEBUG_ERR("sendMessage failed");
- this->error = SCARD_ERROR_IPC_FAILED;
+ gint ret;
+ GError *error = NULL;
+
+ if (proxy == NULL) {
+ _ERR("dbus proxy is not initialized yet");
+ throw ErrorIllegalState(SCARD_ERROR_NOT_INITIALIZED);
}
- syncUnlock();
- channelNum = -1;
+ if (smartcard_service_channel_call_close_channel_sync(
+ (SmartcardServiceChannel *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ &ret, NULL, &error) == true) {
+ if (ret != SCARD_ERROR_OK) {
+ _ERR("smartcard_service_channel_call_close_channel_sync failed, [%d]", ret);
+ THROW_ERROR(ret);
+ }
+ } else {
+ _ERR("smartcard_service_channel_call_close_channel_sync failed, [%s]", error->message);
+ g_error_free(error);
- if (this->error != SCARD_ERROR_OK)
- {
- ThrowError::throwError(this->error);
+ throw ErrorIO(SCARD_ERROR_IPC_FAILED);
}
}
else
{
- /* FIXME */
- SCARD_DEBUG("unavailable channel");
+ _INFO("unavailable channel");
}
}
-#endif
}
- int ClientChannel::close(closeCallback callback, void *userParam)
+ int ClientChannel::close(closeChannelCallback callback, void *userParam)
{
int result = SCARD_ERROR_OK;
{
if (getSession()->getReader()->isSecureElementPresent() == true)
{
- Message msg;
- channelNum = -1;
-
- /* send message to server */
- msg.message = Message::MSG_REQUEST_CLOSE_CHANNEL;
- msg.param1 = (unsigned long)handle;
- msg.error = (unsigned long)context; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)callback;
- msg.userParam = userParam;
-
- if (ClientIPC::getInstance().sendMessage(&msg) == false)
- {
- result = SCARD_ERROR_IPC_FAILED;
- }
+ CallbackParam *param = new CallbackParam();
+
+ param->instance = this;
+ param->callback = (void *)callback;
+ param->user_param = userParam;
+
+ smartcard_service_channel_call_close_channel(
+ (SmartcardServiceChannel *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle), NULL,
+ &ClientChannel::channel_close_cb, param);
}
else
{
- SCARD_DEBUG_ERR("unavailable channel");
+ _ERR("unavailable channel");
result = SCARD_ERROR_ILLEGAL_STATE;
}
}
return result;
}
- int ClientChannel::transmitSync(ByteArray command, ByteArray &result)
- throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
+ int ClientChannel::transmitSync(const ByteArray &command, ByteArray &result)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
{
int rv = SCARD_ERROR_OK;
if (getSession()->getReader()->isSecureElementPresent() == true)
{
- Message msg;
-
-#ifdef CLIENT_IPC_THREAD
- /* send message to server */
- msg.message = Message::MSG_REQUEST_TRANSMIT;
- msg.param1 = (unsigned long)handle;
- msg.param2 = 0;
- msg.data = command;
- msg.error = (unsigned long)context; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
-
- syncLock();
- if (ClientIPC::getInstance().sendMessage(&msg) == true)
- {
- rv = waitTimedCondition(0);
- if (rv >= 0)
- {
- result = response;
-
- rv = SCARD_ERROR_OK;
+ GVariant *var_command = NULL, *var_response = NULL;
+ GError *error = NULL;
+
+ var_command = GDBusHelper::convertByteArrayToVariant(command);
+
+ if (smartcard_service_channel_call_transmit_sync(
+ (SmartcardServiceChannel *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ var_command, &rv, &var_response,
+ NULL, &error) == true) {
+
+ if (rv == SCARD_ERROR_OK) {
+ GDBusHelper::convertVariantToByteArray(var_response, result);
+ } else {
+ _ERR("smartcard_service_session_call_get_atr_sync failed, [%d]", rv);
+ THROW_ERROR(rv);
}
- else
- {
- SCARD_DEBUG_ERR("timeout");
+ } else {
+ _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
+ g_error_free(error);
- this->error = SCARD_ERROR_OPERATION_TIMEOUT;
- }
+ throw ErrorIO(SCARD_ERROR_IPC_FAILED);
}
- else
- {
- SCARD_DEBUG_ERR("sendMessage failed");
- }
- syncUnlock();
-
- if (this->error != SCARD_ERROR_OK)
- {
- ThrowError::throwError(this->error);
- }
-#endif
}
else
{
- SCARD_DEBUG_ERR("unavailable channel");
+ _ERR("unavailable channel");
throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
}
return rv;
}
- int ClientChannel::transmit(ByteArray command, transmitCallback callback, void *userParam)
+ int ClientChannel::transmit(const ByteArray &command, transmitCallback callback, void *userParam)
{
int result;
if (getSession()->getReader()->isSecureElementPresent() == true)
{
- Message msg;
-
- /* send message to server */
- msg.message = Message::MSG_REQUEST_TRANSMIT;
- msg.param1 = (unsigned long)handle;
- msg.param2 = 0;
- msg.data = command;
- msg.error = (unsigned long)context; /* using error to context */
- msg.caller = (void *)this;
- msg.callback = (void *)callback;
- msg.userParam = userParam;
-
- if (ClientIPC::getInstance().sendMessage(&msg) == true)
- {
- result = SCARD_ERROR_OK;
- }
- else
- {
- result = SCARD_ERROR_IPC_FAILED;
- }
- }
- else
- {
- SCARD_DEBUG_ERR("unavailable channel");
- result = SCARD_ERROR_ILLEGAL_STATE;
- }
+ GVariant *var_command;
+ CallbackParam *param = new CallbackParam();
- return result;
- }
+ param->instance = this;
+ param->callback = (void *)callback;
+ param->user_param = userParam;
- bool ClientChannel::dispatcherCallback(void *message)
- {
- Message *msg = (Message *)message;
- ClientChannel *channel = NULL;
- bool result = false;
+ var_command = GDBusHelper::convertByteArrayToVariant(command);
- if (msg == NULL)
- {
- SCARD_DEBUG_ERR("message is null");
- return result;
- }
+ smartcard_service_channel_call_transmit(
+ (SmartcardServiceChannel *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ var_command, NULL,
+ &ClientChannel::channel_transmit_cb, param);
- channel = (ClientChannel *)msg->caller;
-
- switch (msg->message)
+ result = SCARD_ERROR_OK;
+ }
+ else
{
- case Message::MSG_REQUEST_TRANSMIT :
- {
- /* transmit result */
- SCARD_DEBUG("MSG_REQUEST_TRANSMIT");
-
- if (msg->error == 0 &&
- ResponseHelper::getStatus(msg->data) == 0)
- {
- /* store select response */
- if (msg->data.getAt(1) == APDUCommand::INS_SELECT_FILE)
- channel->setSelectResponse(msg->data);
- }
-
- if (msg->isSynchronousCall() == true) /* synchronized call */
- {
- /* sync call */
- channel->syncLock();
-
- /* copy result */
- channel->error = msg->error;
- channel->response = msg->data;
-
- channel->signalCondition();
- channel->syncUnlock();
- }
- else if (msg->callback != NULL)
- {
- transmitCallback cb = (transmitCallback)msg->callback;
-
- /* async call */
- cb(msg->data.getBuffer(), msg->data.getLength(), msg->error, msg->userParam);
- }
- }
- break;
-
- case Message::MSG_REQUEST_CLOSE_CHANNEL :
- {
- SCARD_DEBUG("MSG_REQUEST_CLOSE_CHANNEL");
-
- if (msg->isSynchronousCall() == true) /* synchronized call */
- {
- /* sync call */
- channel->syncLock();
-
- channel->error = msg->error;
-
- channel->signalCondition();
- channel->syncUnlock();
- }
- else if (msg->callback != NULL)
- {
- closeCallback cb = (closeCallback)msg->callback;
-
- /* async call */
- cb(msg->error, msg->userParam);
- }
- }
- break;
-
- default:
- SCARD_DEBUG("unknwon message : %s", msg->toString());
- break;
+ _ERR("unavailable channel");
+ result = SCARD_ERROR_ILLEGAL_STATE;
}
return result;
} \
else \
{ \
- SCARD_DEBUG_ERR("Invalid param"); \
+ _ERR("Invalid param"); \
}
using namespace smartcard_service_api;
int result = -1;
CHANNEL_EXTERN_BEGIN;
- result = channel->close((closeCallback)callback, userParam);
+ result = channel->close((closeChannelCallback)callback, userParam);
CHANNEL_EXTERN_END;
return result;
CHANNEL_EXTERN_BEGIN;
ByteArray temp;
- temp.setBuffer(command, length);
+ temp.assign(command, length);
result = channel->transmit(temp, (transmitCallback)callback, userParam);
CHANNEL_EXTERN_END;
EXTERN_API void channel_close_sync(channel_h handle)
{
-#ifdef CLIENT_IPC_THREAD
CHANNEL_EXTERN_BEGIN;
try
{
{
}
CHANNEL_EXTERN_END;
-#endif
}
EXTERN_API int channel_transmit_sync(channel_h handle, unsigned char *command,
{
int result = -1;
-#ifdef CLIENT_IPC_THREAD
if (command == NULL || cmd_len == 0 || response == NULL || resp_len == NULL)
return result;
CHANNEL_EXTERN_BEGIN;
ByteArray temp, resp;
- temp.setBuffer(command, cmd_len);
+ temp.assign(command, cmd_len);
try
{
result = channel->transmitSync(temp, resp);
- if (resp.getLength() > 0)
+ if (resp.size() > 0)
{
- *resp_len = resp.getLength();
+ *resp_len = resp.size();
*response = (unsigned char *)calloc(1, *resp_len);
memcpy(*response, resp.getBuffer(), *resp_len);
}
result = -1;
}
CHANNEL_EXTERN_END;
-#endif
return result;
}
unsigned int result = 0;
CHANNEL_EXTERN_BEGIN;
- result = channel->getSelectResponse().getLength();
+ result = channel->getSelectResponse().size();
CHANNEL_EXTERN_END;
return result;
ByteArray response;
response = channel->getSelectResponse();
- if (response.getLength() > 0)
+ if (response.size() > 0)
{
- memcpy(buffer, response.getBuffer(), MIN(length, response.getLength()));
+ memcpy(buffer, response.getBuffer(), MIN(length, response.size()));
result = true;
}
CHANNEL_EXTERN_END;