SET(CMAKE_VERBOSE_MAKEFILE OFF)
-IF("${USE_AUTOSTART}" STREQUAL "1")
- ADD_DEFINITIONS("-DUSE_AUTOSTART")
-ENDIF()
+IF("${USE_GDBUS}" STREQUAL "1")
+ ADD_DEFINITIONS("-DUSE_GDBUS")
+
+ IF("${USE_AUTOSTART}" STREQUAL "1")
+ ADD_DEFINITIONS("-DUSE_AUTOSTART")
+ ENDIF()
+
+ FIND_PROGRAM(GDBUS_CODEGEN NAMES gdbus-codegen)
+ EXEC_PROGRAM(${GDBUS_CODEGEN} ARGS
+ " \\
+ --generate-c-code ${CMAKE_CURRENT_SOURCE_DIR}/common/smartcard-service-gdbus \\
+ --c-namespace SmartcardService\\
+ --interface-prefix org.tizen.SmartcardService. \\
+ ${CMAKE_CURRENT_SOURCE_DIR}/common/smartcard-service-gdbus.xml \\
+ ")
+ELSE()
+ ADD_DEFINITIONS("-DCLIENT_IPC_THREAD")
+ ADD_DEFINITIONS("-DUSE_IPC_EPOLL")
+
+ IF("${USE_AUTOSTART}" STREQUAL "1")
+ ADD_DEFINITIONS("-DUSE_AUTOSTART")
-ADD_DEFINITIONS("-DCLIENT_IPC_THREAD")
-ADD_DEFINITIONS("-DUSE_IPC_EPOLL")
+ FIND_PROGRAM(DBUS_BINDING_TOOL NAMES dbus-binding-tool)
+ EXEC_PROGRAM("${DBUS_BINDING_TOOL}" ARGS "--prefix=smartcard_service ${CMAKE_CURRENT_SOURCE_DIR}/common/smartcard-service.xml --mode=glib-server --output=${CMAKE_CURRENT_SOURCE_DIR}/common/include/smartcard-service-binding.h")
+ EXEC_PROGRAM("${DBUS_BINDING_TOOL}" ARGS "--prefix=smartcard_service ${CMAKE_CURRENT_SOURCE_DIR}/common/smartcard-service.xml --mode=glib-client --output=${CMAKE_CURRENT_SOURCE_DIR}/common/include/smartcard-service-glue.h")
+ ENDIF()
+ENDIF()
ADD_SUBDIRECTORY(common)
ADD_SUBDIRECTORY(client)
ADD_SUBDIRECTORY(server)
-ADD_SUBDIRECTORY(test-client)
+
+IF("${TEST_CLIENT}" STREQUAL "1")
+ ADD_SUBDIRECTORY(test-client)
+ENDIF()
SET(VERSION_MAJOR 1)
SET(VERSION ${VERSION_MAJOR}.0.0)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../server/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SRCS)
IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
- SET(CMAKE_BUILD_TYPE "Release")
+ SET(CMAKE_BUILD_TYPE "Release")
ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs_client REQUIRED gthread-2.0 dlog dbus-glib-1 security-server)
+pkg_check_modules(pkgs_client REQUIRED glib-2.0 dlog dbus-glib-1 security-server)
MESSAGE("${LIB_NAME} ld flag : ${pkgs_client_LDFLAGS}")
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
FOREACH(hfile ${EXPORT_HEADER})
- INSTALL(FILES ${hfile} DESTINATION include/${LIB_NAME})
+ INSTALL(FILES ${hfile} DESTINATION include/${LIB_NAME})
ENDFOREACH(hfile)
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#ifdef USE_GDBUS
+#include <glib.h>
+#endif
/* SLP library header */
/* local header */
#include "Debug.h"
-#include "Message.h"
-#include "ClientIPC.h"
#include "ClientChannel.h"
#include "ReaderHelper.h"
#include "APDUHelper.h"
+#ifdef USE_GDBUS
+#include "smartcard-service-gdbus.h"
+#include "GDBusHelper.h"
+#else
+#include "Message.h"
+#include "ClientIPC.h"
+#endif
#ifndef EXTERN_API
#define EXTERN_API __attribute__((visibility("default")))
this->handle = handle;
this->selectResponse = selectResponse;
this->context = context;
+#ifdef USE_GDBUS
+ /* initialize client */
+ if (!g_thread_supported())
+ {
+ g_thread_init(NULL);
+ }
+
+ g_type_init();
+
+ /* 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;
+ }
+#endif
}
ClientChannel::~ClientChannel()
closeSync();
}
+#ifdef USE_GDBUS
+ 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.getLength(),
+ 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;
+ }
+#endif
void ClientChannel::closeSync()
throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
ErrorIllegalState &, ErrorIllegalParameter &)
{
-#ifdef CLIENT_IPC_THREAD
if (isClosed() == false)
{
if (getSession()->getReader()->isSecureElementPresent() == true)
{
+#ifdef USE_GDBUS
+ gint ret;
+ GError *error = NULL;
+
+ if (proxy == NULL) {
+ _ERR("dbus proxy is not initialized yet");
+ throw ErrorIllegalState(SCARD_ERROR_NOT_INITIALIZED);
+ }
+
+ 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);
+
+ throw ErrorIO(SCARD_ERROR_IPC_FAILED);
+ }
+#else
Message msg;
int rv;
+#ifdef CLIENT_IPC_THREAD
/* send message to server */
msg.message = Message::MSG_REQUEST_CLOSE_CHANNEL;
msg.param1 = (unsigned long)handle;
{
ThrowError::throwError(this->error);
}
+#endif
+#endif
}
else
{
_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)
{
+#ifdef USE_GDBUS
+ 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
Message msg;
channelNum = -1;
_ERR("sendMessage failed");
result = SCARD_ERROR_IPC_FAILED;
}
+#endif
}
else
{
ErrorIllegalParameter &, ErrorSecurity &)
{
int rv = SCARD_ERROR_OK;
+
if (getSession()->getReader()->isSecureElementPresent() == true)
{
- Message msg;
+#ifdef USE_GDBUS
+ 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 {
+ _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
+ g_error_free(error);
+ throw ErrorIO(SCARD_ERROR_IPC_FAILED);
+ }
+#else
+ Message msg;
#ifdef CLIENT_IPC_THREAD
/* send message to server */
msg.message = Message::MSG_REQUEST_TRANSMIT;
ThrowError::throwError(this->error);
}
#endif
+#endif
}
else
{
if (getSession()->getReader()->isSecureElementPresent() == true)
{
+#ifdef USE_GDBUS
+ GVariant *var_command;
+ CallbackParam *param = new CallbackParam();
+
+ param->instance = this;
+ param->callback = (void *)callback;
+ param->user_param = userParam;
+
+ var_command = GDBusHelper::convertByteArrayToVariant(command);
+
+ smartcard_service_channel_call_transmit(
+ (SmartcardServiceChannel *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ var_command, NULL,
+ &ClientChannel::channel_close_cb, param);
+
+ result = SCARD_ERROR_OK;
+#else
Message msg;
/* send message to server */
_ERR("sendMessage failed");
result = SCARD_ERROR_IPC_FAILED;
}
+#endif
}
else
{
return result;
}
+#ifndef USE_GDBUS
bool ClientChannel::dispatcherCallback(void *message)
{
Message *msg = (Message *)message;
}
else if (msg->callback != NULL)
{
- closeCallback cb = (closeCallback)msg->callback;
+ closeChannelCallback cb = (closeChannelCallback)msg->callback;
/* async call */
cb(msg->error, msg->userParam);
return result;
}
+#endif /* USE_GDBUS */
} /* namespace smartcard_service_api */
/* export C API */
int result = -1;
CHANNEL_EXTERN_BEGIN;
- result = channel->close((closeCallback)callback, userParam);
+ result = channel->close((closeChannelCallback)callback, userParam);
CHANNEL_EXTERN_END;
return result;
* limitations under the License.
*/
+#ifndef USE_GDBUS
/* standard library header */
#include <glib.h>
}
} /* namespace open_mobile_api */
-
+#endif /* USE_GDBUS */
* limitations under the License.
*/
+#ifndef USE_GDBUS
/* standard library header */
#include <sys/socket.h>
#include <unistd.h>
return result;
}
-
} /* namespace open_mobile_api */
+#endif /* USE_GDBUS */
/* local header */
#include "Debug.h"
-#include "Message.h"
-#include "ClientIPC.h"
#include "Reader.h"
#include "Session.h"
+#ifdef USE_GDBUS
+#include "GDBusHelper.h"
+#include "smartcard-service-gdbus.h"
+#else
+#include "Message.h"
+#include "ClientIPC.h"
+#endif
#ifndef EXTERN_API
#define EXTERN_API __attribute__((visibility("default")))
namespace smartcard_service_api
{
- Reader::Reader(void *context, const char *name, void *handle)
- : ReaderHelper()
+ Reader::Reader(void *context, const char *name, void *handle) :
+ ReaderHelper(), context(context), handle(handle)
{
unsigned int length = 0;
_BEGIN();
- this->context = NULL;
- this->handle = NULL;
-
if (context == NULL || name == NULL || strlen(name) == 0 || handle == NULL)
{
_ERR("invalid param");
length = (length < sizeof(this->name)) ? length : sizeof(this->name);
memcpy(this->name, name, length);
+#ifdef USE_GDBUS
+ /* initialize client */
+ if (!g_thread_supported())
+ {
+ g_thread_init(NULL);
+ }
+
+ g_type_init();
+
+ /* init default context */
+ GError *error = NULL;
+
+ proxy = smartcard_service_reader_proxy_new_for_bus_sync(
+ G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
+ "org.tizen.SmartcardService",
+ "/org/tizen/SmartcardService/Reader",
+ NULL, &error);
+ if (proxy == NULL)
+ {
+ _ERR("Can not create proxy : %s", error->message);
+ g_error_free(error);
+ return;
+ }
+#endif
present = true;
_END();
throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
ErrorIllegalParameter &, ErrorSecurity &)
{
- openedSession = NULL;
+ Session *session = NULL;
if (isSecureElementPresent() == true)
{
+#ifdef USE_GDBUS
+ gint result;
+ GError *error = NULL;
+ guint session_id;
+
+ if (smartcard_service_reader_call_open_session_sync(
+ (SmartcardServiceReader *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ &result, &session_id, NULL, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ /* create new instance of channel */
+
+ session = new Session(context, this,
+ GUINT_TO_POINTER(session_id));
+ if (session != NULL) {
+ sessions.push_back(session);
+ } else {
+ _ERR("Session creating instance failed");
+
+ THROW_ERROR(SCARD_ERROR_OUT_OF_MEMORY);
+ }
+ } else {
+ _ERR("smartcard_service_reader_call_open_session_sync failed, [%d]", result);
+
+ THROW_ERROR(result);
+ }
+ } else {
+ _ERR("smartcard_service_reader_call_open_session_sync failed, [%s]", error->message);
+ g_error_free(error);
+
+ THROW_ERROR(SCARD_ERROR_IPC_FAILED);
+ }
+#else
Message msg;
int rv;
+ openedSession = NULL;
#ifdef CLIENT_IPC_THREAD
/* request channel handle from server */
msg.message = Message::MSG_REQUEST_OPEN_SESSION;
_ERR("time over");
this->error = SCARD_ERROR_OPERATION_TIMEOUT;
}
+
+ session = openedSession;
}
else
{
ThrowError::throwError(this->error);
}
#endif
+#endif
}
else
{
throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
}
- return (Session *)openedSession;
+ return session;
}
+#ifdef USE_GDBUS
+ void Reader::reader_open_session_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+ {
+ CallbackParam *param = (CallbackParam *)user_data;
+ Reader *reader;
+ openSessionCallback callback;
+ Session *session = NULL;
+ gint result;
+ guint handle;
+ GError *error = NULL;
+
+ _INFO("MSG_REQUEST_OPEN_SESSION");
+
+ if (param == NULL) {
+ _ERR("null parameter!!!");
+ return;
+ }
+
+ reader = (Reader *)param->instance;
+ callback = (openSessionCallback)param->callback;
+
+ if (smartcard_service_reader_call_open_session_finish(
+ SMARTCARD_SERVICE_READER(source_object),
+ &result, &handle, res, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ /* create new instance of channel */
+ session = new Session(reader->context, reader,
+ GUINT_TO_POINTER(handle));
+ if (session != NULL) {
+ reader->sessions.push_back(session);
+ } else {
+ _ERR("Session creating instance failed");
+
+ result = SCARD_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ _ERR("smartcard_service_reader_call_open_session failed, [%d]", result);
+ }
+ } else {
+ _ERR("smartcard_service_reader_call_open_session failed, [%s]", error->message);
+ g_error_free(error);
+
+ result = SCARD_ERROR_IPC_FAILED;
+ }
+
+ if (callback != NULL) {
+ callback(session, result, param->user_param);
+ }
+
+ delete param;
+ }
+#endif
int Reader::openSession(openSessionCallback callback, void *userData)
{
int result;
if (isSecureElementPresent() == true)
{
+#ifdef USE_GDBUS
+ CallbackParam *param = new CallbackParam();
+
+ param->instance = this;
+ param->callback = (void *)callback;
+ param->user_param = userData;
+
+ smartcard_service_reader_call_open_session(
+ (SmartcardServiceReader *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ NULL, &Reader::reader_open_session_cb, param);
+
+ result = SCARD_ERROR_OK;
+#else
Message msg;
/* request channel handle from server */
_ERR("sendMessage failed");
result = SCARD_ERROR_IPC_FAILED;
}
+#endif
}
else
{
return result;
}
+#ifndef USE_GDBUS
bool Reader::dispatcherCallback(void *message)
{
Message *msg = (Message *)message;
return result;
}
-
+#endif
} /* namespace smartcard_service_api */
/* export C API */
#include <unistd.h>
#include <string.h>
#include <glib.h>
+#include <glib-object.h>
/* SLP library header */
/* local header */
#include "Debug.h"
-#include "ClientIPC.h"
-#include "ClientDispatcher.h"
#include "SEService.h"
#include "Reader.h"
+#ifdef USE_GDBUS
+#include "smartcard-service-gdbus.h"
+#else
#include "Message.h"
+#include "ClientIPC.h"
+#include "ClientDispatcher.h"
+#endif
#ifndef EXTERN_API
#define EXTERN_API __attribute__((visibility("default")))
namespace smartcard_service_api
{
SEService::SEService() : SEServiceHelper(),
- handle(-1), context(NULL),
- handler(NULL), listener(NULL)
+ handle(-1), context(NULL), handler(NULL), listener(NULL)
{
+#ifdef USE_GDBUS
+ proxy = NULL;
+#endif
}
SEService::SEService(void *user_data, serviceConnected handler)
return new SEService(user_data, handler);
}
+#ifdef USE_GDBUS
+ void SEService::reader_inserted(GObject *source_object,
+ guint reader_id, gchar *reader_name, gpointer user_data)
+ {
+ Reader *reader = NULL;
+ SEService *service = (SEService *)user_data;
+
+ _INFO("[MSG_NOTIFY_SE_INSERTED]");
+
+ /* add readers */
+ reader = new Reader(service->context,
+ reader_name, GUINT_TO_POINTER(reader_id));
+ if (reader != NULL)
+ {
+ service->readers.push_back(reader);
+ }
+ else
+ {
+ _ERR("alloc failed");
+ }
+
+ if (service->listener != NULL)
+ {
+ service->listener->eventHandler(service,
+ reader_name, 1, service->context);
+ }
+ else
+ {
+ _DBG("listener is null");
+ }
+ }
+
+ void SEService::reader_removed(GObject *source_object,
+ guint reader_id, gchar *reader_name, gpointer user_data)
+ {
+ SEService *service = (SEService *)user_data;
+ size_t i;
+
+ _INFO("[MSG_NOTIFY_SE_REMOVED]");
+
+ for (i = 0; i < service->readers.size(); i++)
+ {
+ if (((Reader *)service->readers[i])->handle ==
+ GUINT_TO_POINTER(reader_id))
+ {
+ ((Reader *)service->readers[i])->unavailable();
+ break;
+ }
+ }
+
+ if (service->listener != NULL)
+ {
+ service->listener->eventHandler(service,
+ reader_name, 2, service->context);
+ }
+ else
+ {
+ _DBG("listener is null");
+ }
+ }
+
+ void SEService::se_service_shutdown_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+ {
+ SEService *service = (SEService *)user_data;
+ gint result;
+ GError *error = NULL;
+
+ if (smartcard_service_se_service_call_shutdown_finish(
+ SMARTCARD_SERVICE_SE_SERVICE(source_object),
+ &result, res, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ service->connected = false;
+ } else {
+ _ERR("smartcard_service_se_service_call_shutdown failed, [%d]", result);
+ }
+ } else {
+ _ERR("smartcard_service_se_service_call_shutdown failed, [%s]", error->message);
+ g_error_free(error);
+ }
+ }
+
+ void SEService::se_service_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+ {
+ SEService *service = (SEService *)user_data;
+ gint result;
+ guint handle;
+ GVariant *readers = NULL;
+ GError *error = NULL;
+
+ if (service == NULL) {
+ _ERR("null parameter!!!");
+ return;
+ }
+
+ if (smartcard_service_se_service_call_se_service_finish(
+ SMARTCARD_SERVICE_SE_SERVICE(source_object),
+ &result, &handle, &readers, res, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ service->connected = true;
+ service->handle = handle;
+ service->parseReaderInformation(readers);
+ }
+ } else {
+ _ERR("smartcard_service_se_service_call_se_service failed, [%s]", error->message);
+ g_error_free(error);
+
+ result = SCARD_ERROR_IPC_FAILED;
+ }
+
+ if (service->handler != NULL) {
+ service->handler(service, service->context);
+ } else if (service->listener != NULL) {
+ if (result == SCARD_ERROR_OK) {
+ service->listener->serviceConnected(service, service->context);
+ } else {
+ service->listener->errorHandler(service, result, service->context);
+ }
+ }
+ }
+#endif
void SEService::shutdown()
{
if (connected == true)
{
readers[i]->closeSessions();
}
-
+#ifdef USE_GDBUS
+ smartcard_service_se_service_call_shutdown(
+ (SmartcardServiceSeService *)proxy, handle,
+ NULL, &SEService::se_service_shutdown_cb, this);
+#else
Message msg;
msg.message = Message::MSG_REQUEST_SHUTDOWN;
{
_ERR("time over");
}
+#endif
}
}
void SEService::shutdownSync()
{
-#ifdef CLIENT_IPC_THREAD
if (connected == true)
{
uint32_t i;
{
readers[i]->closeSessions();
}
+#ifdef USE_GDBUS
+ gint result;
+ GError *error = NULL;
+
+ if (smartcard_service_se_service_call_shutdown_sync(
+ (SmartcardServiceSeService *)proxy,
+ handle, &result, NULL, &error) == false) {
+ _ERR("smartcard_service_se_service_call_shutdown_sync failed, [%s]", error->message);
+
+ g_error_free(error);
+ }
+ connected = false;
+#else
+#ifdef CLIENT_IPC_THREAD
/* send message to load se */
Message msg;
_ERR("sendMessage failed");
}
syncUnlock();
- }
#endif
+#endif
+ }
}
bool SEService::_initialize() throw(ErrorIO &)
{
bool result = false;
+#ifndef USE_GDBUS
ClientIPC *clientIPC;
ClientDispatcher *clientDispatcher;
-
+#endif
_BEGIN();
/* initialize client */
g_thread_init(NULL);
}
+ g_type_init();
+
+#ifdef USE_GDBUS
+ /* init default context */
+ GError *error = NULL;
+
+ proxy = smartcard_service_se_service_proxy_new_for_bus_sync(
+ G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
+ "org.tizen.SmartcardService",
+ "/org/tizen/SmartcardService/SeService",
+ NULL, &error);
+ if (proxy == NULL)
+ {
+ _ERR("Can not create proxy : %s", error->message);
+ g_error_free(error);
+ return false;
+ }
+
+ g_signal_connect(proxy, "reader-inserted",
+ G_CALLBACK(&SEService::reader_inserted), this);
+
+ g_signal_connect(proxy, "reader-removed",
+ G_CALLBACK(&SEService::reader_removed), this);
+
+ /* request reader */
+ smartcard_service_se_service_call_se_service(
+ (SmartcardServiceSeService *)proxy, NULL,
+ &SEService::se_service_cb, this);
+#else
clientDispatcher = &ClientDispatcher::getInstance();
clientIPC = &ClientIPC::getInstance();
result = clientIPC->sendMessage(&msg);
}
-
+#endif
_END();
return result;
return _initialize();
}
+#ifdef USE_GDBUS
+ bool SEService::parseReaderInformation(GVariant *variant)
+ {
+ Reader *reader = NULL;
+
+ GVariantIter *iter;
+ gsize count;
+ guint handle;
+ gchar *name;
+
+ g_variant_get(variant, "a(us)", &iter);
+
+ count = g_variant_iter_n_children(iter);
+ while (g_variant_iter_loop(iter, "(us)", &handle, &name) == true)
+ {
+ SECURE_LOGD("Reader : name [%s], handle [%08x]", name, handle);
+
+ /* add readers */
+ reader = new Reader((void *)this->handle, name, GUINT_TO_POINTER(handle));
+ if (reader == NULL)
+ {
+ _ERR("alloc failed");
+ continue;
+ }
+
+ readers.push_back(reader);
+ }
+
+ g_variant_iter_free(iter);
+
+ return true;
+ }
+#endif
bool SEService::parseReaderInformation(unsigned int count, ByteArray data)
{
size_t i;
return true;
}
+#ifndef USE_GDBUS
bool SEService::dispatcherCallback(void *message)
{
Message *msg = (Message *)message;
return result;
}
-
+#endif
} /* namespace smartcard_service_api */
/* export C API */
#include "Session.h"
#include "Reader.h"
#include "ClientChannel.h"
+#ifdef USE_GDBUS
+#include "smartcard-service-gdbus.h"
+#include "GDBusHelper.h"
+#else
#include "ClientIPC.h"
+#endif
#ifndef EXTERN_API
#define EXTERN_API __attribute__((visibility("default")))
this->context = context;
this->handle = handle;
+
+#ifdef USE_GDBUS
+ /* initialize client */
+ if (!g_thread_supported())
+ {
+ g_thread_init(NULL);
+ }
+
+ g_type_init();
+
+ /* init default context */
+ GError *error = NULL;
+
+ proxy = smartcard_service_session_proxy_new_for_bus_sync(
+ G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
+ "org.tizen.SmartcardService",
+ "/org/tizen/SmartcardService/Session",
+ NULL, &error);
+ if (proxy == NULL)
+ {
+ _ERR("Can not create proxy : %s", error->message);
+ g_error_free(error);
+ return;
+ }
+#endif
closed = false;
}
channels[i]->closeSync();
}
}
+#ifdef USE_GDBUS
+ void Session::session_get_atr_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+ {
+ CallbackParam *param = (CallbackParam *)user_data;
+ Session *session;
+ getATRCallback callback;
+ gint result;
+ GVariant *var_atr;
+ GError *error = NULL;
+ ByteArray atr;
+
+ _INFO("MSG_REQUEST_GET_ATR");
+
+ if (param == NULL) {
+ _ERR("null parameter!!!");
+ return;
+ }
+
+ session = (Session *)param->instance;
+ callback = (getATRCallback)param->callback;
+
+ if (smartcard_service_session_call_get_atr_finish(
+ SMARTCARD_SERVICE_SESSION(source_object),
+ &result, &var_atr, res, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ GDBusHelper::convertVariantToByteArray(var_atr, atr);
+
+ session->atr = atr;
+ } else {
+ _ERR("smartcard_service_session_call_get_atr failed, [%d]", result);
+ }
+ } else {
+ _ERR("smartcard_service_session_call_get_atr failed, [%s]", error->message);
+ g_error_free(error);
+
+ result = SCARD_ERROR_IPC_FAILED;
+ }
+
+ if (callback != NULL) {
+ callback(atr.getBuffer(), atr.getLength(), result, param->user_param);
+ }
+
+ delete param;
+ }
+
+ void Session::session_open_channel_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+ {
+ CallbackParam *param = (CallbackParam *)user_data;
+ Session *session;
+ openChannelCallback callback;
+ gint result;
+ guint channel_id;
+ GVariant *var_response;
+ GError *error = NULL;
+ Channel *channel;
+
+ _INFO("MSG_REQUEST_OPEN_CHANNEL");
+ if (param == NULL) {
+ _ERR("null parameter!!!");
+ return;
+ }
+
+ session = (Session *)param->instance;
+ callback = (openChannelCallback)param->callback;
+
+ if (smartcard_service_session_call_open_channel_finish(
+ SMARTCARD_SERVICE_SESSION(source_object),
+ &result, &channel_id, &var_response,
+ res, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ ByteArray response;
+
+ GDBusHelper::convertVariantToByteArray(
+ var_response, response);
+
+ /* create new instance of channel */
+ channel = new ClientChannel(session->context,
+ session, channel_id,
+ response, (void *)channel_id);
+ if (channel != NULL) {
+ session->channels.push_back(channel);
+ } else {
+ _ERR("alloc failed");
+
+ result = SCARD_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ _ERR("smartcard_service_session_call_open_channel failed, [%d]", result);
+ }
+ } else {
+ _ERR("smartcard_service_session_call_open_channel failed, [%s]", error->message);
+ g_error_free(error);
+
+ result = SCARD_ERROR_IPC_FAILED;
+ }
+
+ if (callback != NULL) {
+ callback(channel, result, param->user_param);
+ }
+
+ delete param;
+ }
+
+ void Session::session_close_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+ {
+ CallbackParam *param = (CallbackParam *)user_data;
+ Session *session;
+ closeSessionCallback callback;
+ gint result;
+ GError *error = NULL;
+
+ _INFO("MSG_REQUEST_CLOSE_SESSION");
+
+ if (param == NULL) {
+ _ERR("null parameter!!!");
+ return;
+ }
+
+ session = (Session *)param->instance;
+ callback = (closeSessionCallback)param->callback;
+
+ if (smartcard_service_session_call_close_session_finish(
+ SMARTCARD_SERVICE_SESSION(source_object),
+ &result, res, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ session->closed = true;
+ } else {
+ _ERR("smartcard_service_session_call_close_session failed, [%d]", result);
+ }
+ } else {
+ _ERR("smartcard_service_session_call_close_session failed, [%s]", error->message);
+ g_error_free(error);
+
+ result = SCARD_ERROR_IPC_FAILED;
+ }
+
+ if (callback != NULL) {
+ callback(result, param->user_param);
+ }
+
+ delete param;
+ }
+#endif
ByteArray Session::getATRSync()
throw (ExceptionBase &, ErrorIO &, ErrorSecurity &,
ErrorIllegalState &, ErrorIllegalParameter &)
{
ByteArray result;
+
if (getReader()->isSecureElementPresent() == true)
{
if (atr.isEmpty() == true)
{
+#ifdef USE_GDBUS
+ gint ret;
+ GVariant *var_atr = NULL;
+ GError *error = NULL;
+
+ if (smartcard_service_session_call_get_atr_sync(
+ (SmartcardServiceSession *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ &ret, &var_atr, NULL, &error) == true) {
+ if (ret == SCARD_ERROR_OK) {
+ GDBusHelper::convertVariantToByteArray(var_atr, result);
+
+ atr = result;
+ } else {
+ _ERR("smartcard_service_session_call_get_atr_sync failed, [%d]", ret);
+
+ THROW_ERROR(ret);
+ }
+ } else {
+ _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
+ g_error_free(error);
+
+ THROW_ERROR(SCARD_ERROR_IPC_FAILED);
+ }
+#else
Message msg;
int rv;
-
#ifdef CLIENT_IPC_THREAD
/* request channel handle from server */
msg.message = Message::MSG_REQUEST_GET_ATR;
ThrowError::throwError(this->error);
}
#endif
+#endif
}
result = atr;
{
if (atr.isEmpty() == true)
{
- Message msg;
+#ifdef USE_GDBUS
+ CallbackParam *param = new CallbackParam();
+ param->instance = this;
+ param->callback = (void *)callback;
+ param->user_param = userData;
- /* request channel handle from server */
+ smartcard_service_session_call_get_atr(
+ (SmartcardServiceSession *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle), NULL,
+ &Session::session_get_atr_cb, param);
+
+ result = SCARD_ERROR_OK;
+#else
+ Message msg;
+
+ /* request channel handle from server */
msg.message = Message::MSG_REQUEST_GET_ATR;
msg.param1 = (unsigned long)handle;
msg.error = (unsigned long)context; /* using error to context */
_ERR("sendMessage failed");
result = SCARD_ERROR_IPC_FAILED;
}
+#endif
}
else
{
throw (ExceptionBase &, ErrorIO &, ErrorSecurity &,
ErrorIllegalState &, ErrorIllegalParameter &)
{
- Message msg;
- int rv;
-
-#ifdef CLIENT_IPC_THREAD
if (isClosed() == false)
{
closed = true;
closeChannels();
+#ifdef USE_GDBUS
+ gint ret;
+ GError *error = NULL;
+
+ if (smartcard_service_session_call_close_session_sync(
+ (SmartcardServiceSession *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ &ret, NULL, &error) == true) {
+ if (ret == SCARD_ERROR_OK) {
+ closed = true;
+ } else {
+ _ERR("smartcard_service_session_call_close_session_sync failed, [%d]", ret);
+
+ THROW_ERROR(ret);
+ }
+ } else {
+ _ERR("smartcard_service_session_call_get_atr_sync failed, [%s]", error->message);
+ g_error_free(error);
+ THROW_ERROR(SCARD_ERROR_IPC_FAILED);
+ }
+#else
+ int rv;
+ Message msg;
+
+#ifdef CLIENT_IPC_THREAD
/* request channel handle from server */
msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
msg.param1 = (unsigned long)handle;
{
ThrowError::throwError(this->error);
}
- }
#endif
+#endif
+ }
}
int Session::close(closeSessionCallback callback, void *userData)
{
int result = SCARD_ERROR_OK;
- Message msg;
if (isClosed() == false)
{
closed = true;
closeChannels();
-
+#ifdef USE_GDBUS
+ CallbackParam *param = new CallbackParam();
+
+ param->instance = this;
+ param->callback = (void *)callback;
+ param->user_param = userData;
+
+ smartcard_service_session_call_close_session(
+ (SmartcardServiceSession *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle), NULL,
+ &Session::session_close_cb, param);
+#else
+ Message msg;
/* request channel handle from server */
msg.message = Message::MSG_REQUEST_CLOSE_SESSION;
msg.param1 = (unsigned long)handle;
_ERR("sendMessage failed");
result = SCARD_ERROR_IPC_FAILED;
}
+#endif
}
return result;
unsigned int Session::getChannelCountSync()
{
- channelCount = -1;
+ unsigned int count = 0;
if (getReader()->isSecureElementPresent() == true)
{
+#ifdef USE_GDBUS
+ count = channels.size();
+#else
Message msg;
int rv;
-
+ channelCount = -1;
#ifdef CLIENT_IPC_THREAD
/* request channel handle from server */
msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
msg.caller = (void *)this;
msg.callback = (void *)this; /* if callback is class instance, it means synchronized call */
- channelCount = -1;
-
syncLock();
if (ClientIPC::getInstance().sendMessage(&msg) == true)
{
_ERR("time over");
this->error = SCARD_ERROR_OPERATION_TIMEOUT;
}
+
+ count = channelCount;
}
else
{
ThrowError::throwError(this->error);
}
#endif
+#endif
}
else
{
throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
}
- return channelCount;
+ return count;
}
int Session::getChannelCount(getChannelCountCallback callback, void *userData)
if (getReader()->isSecureElementPresent() == true)
{
+#ifdef USE_GDBUS
+#else
Message msg;
-
msg.message = Message::MSG_REQUEST_GET_CHANNEL_COUNT;
msg.param1 = (unsigned long)handle;
msg.error = (unsigned long)context; /* using error to context */
_ERR("sendMessage failed");
result = SCARD_ERROR_IPC_FAILED;
}
+#endif
}
else
{
return result;
}
- Channel *Session::openChannelSync(int id, ByteArray aid)
+ Channel *Session::openChannelSync(int id, ByteArray &aid)
throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
ErrorIllegalParameter &, ErrorSecurity &)
{
- openedChannel = NULL;
+ Channel *channel = NULL;
if (getReader()->isSecureElementPresent() == true)
{
+#ifdef USE_GDBUS
+ gint ret;
+ GVariant *var_aid = NULL, *var_response = NULL;
+ guint channel_id;
+ GError *error = NULL;
+
+ var_aid = GDBusHelper::convertByteArrayToVariant(aid);
+
+ if (smartcard_service_session_call_open_channel_sync(
+ (SmartcardServiceSession *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ (guint)id, var_aid, &ret, &channel_id,
+ &var_response, NULL, &error) == true) {
+ if (ret == SCARD_ERROR_OK && channel_id != 0) {
+ ByteArray response;
+
+ GDBusHelper::convertVariantToByteArray(
+ var_response, response);
+
+ /* create new instance of channel */
+ channel = new ClientChannel(context,
+ this, channel_id,
+ response, (void *)channel_id);
+ if (channel != NULL)
+ {
+ channels.push_back(channel);
+ }
+ else
+ {
+ _ERR("alloc failed");
+
+ THROW_ERROR(SCARD_ERROR_OUT_OF_MEMORY);
+ }
+ } else {
+ _ERR("smartcard_service_session_call_open_channel_sync failed, [%d]", ret);
+
+ THROW_ERROR(ret);
+ }
+ } else {
+ _ERR("smartcard_service_session_call_open_channel_sync failed, [%s]", error->message);
+ g_error_free(error);
+
+ THROW_ERROR(SCARD_ERROR_IPC_FAILED);
+ }
+#else
Message msg;
int rv;
_ERR("time over");
this->error = SCARD_ERROR_OPERATION_TIMEOUT;
}
+
+ channel = openedChannel;
}
else
{
{
ThrowError::throwError(this->error);
}
+#endif
}
else
{
_ERR("unavailable session");
+
throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
}
- return (Channel *)openedChannel;
+ return (Channel *)channel;
}
- int Session::openChannel(int id, ByteArray aid, openChannelCallback callback, void *userData)
+ int Session::openChannel(int id, ByteArray &aid, openChannelCallback callback, void *userData)
{
int result;
if (getReader()->isSecureElementPresent() == true)
{
+#ifdef USE_GDBUS
+ GVariant *var_aid;
+
+ CallbackParam *param = new CallbackParam();
+
+ param->instance = this;
+ param->callback = (void *)callback;
+ param->user_param = userData;
+
+ var_aid = GDBusHelper::convertByteArrayToVariant(aid);
+
+ smartcard_service_session_call_open_channel(
+ (SmartcardServiceSession *)proxy,
+ GPOINTER_TO_UINT(context),
+ GPOINTER_TO_UINT(handle),
+ (guint)id, var_aid, NULL,
+ &Session::session_open_channel_cb, param);
+#else
Message msg;
/* request channel handle from server */
_ERR("sendMessage failed");
result = SCARD_ERROR_IPC_FAILED;
}
+#endif
}
else
{
return result;
}
- Channel *Session::openBasicChannelSync(ByteArray aid)
+ Channel *Session::openBasicChannelSync(ByteArray &aid)
throw (ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
return openChannelSync(0, aid);
Channel *Session::openBasicChannelSync(unsigned char *aid, unsigned int length)
throw (ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
- return openBasicChannelSync(ByteArray(aid, length));
+ ByteArray temp(aid, length);
+
+ return openBasicChannelSync(temp);
}
- int Session::openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData)
+ int Session::openBasicChannel(ByteArray &aid, openChannelCallback callback, void *userData)
{
return openChannel(0, aid, callback, userData);
}
int Session::openBasicChannel(unsigned char *aid, unsigned int length,
openChannelCallback callback, void *userData)
{
- return openBasicChannel(ByteArray(aid, length), callback, userData);
+ ByteArray temp(aid, length);
+
+ return openBasicChannel(temp, callback, userData);
}
- Channel *Session::openLogicalChannelSync(ByteArray aid)
+ Channel *Session::openLogicalChannelSync(ByteArray &aid)
throw (ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
return openChannelSync(1, aid);
Channel *Session::openLogicalChannelSync(unsigned char *aid, unsigned int length)
throw (ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
- return openLogicalChannelSync(ByteArray(aid, length));
+ ByteArray temp(aid, length);
+
+ return openLogicalChannelSync(temp);
}
- int Session::openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData)
+ int Session::openLogicalChannel(ByteArray &aid, openChannelCallback callback, void *userData)
{
return openChannel(1, aid, callback, userData);
}
int Session::openLogicalChannel(unsigned char *aid, unsigned int length,
openChannelCallback callback, void *userData)
{
- return openLogicalChannel(ByteArray(aid, length), callback, userData);
+ ByteArray temp(aid, length);
+
+ return openLogicalChannel(temp, callback, userData);
}
+#ifndef USE_GDBUS
bool Session::dispatcherCallback(void *message)
{
Message *msg = (Message *)message;
return result;
}
+#endif
} /* namespace smartcard_service_api */
/* export C API */
#define CLIENTCHANNEL_H_
/* standard library header */
-
+#ifdef USE_GDBUS
+#include <gio/gio.h>
+#endif
/* SLP library header */
/* local header */
private:
void *context;
void *handle;
+#ifdef USE_GDBUS
+ void *proxy;
+#else
/* temporary data for sync function */
int error;
ByteArray response;
-
+#endif
ClientChannel(void *context, Session *session, int channelNum,
ByteArray selectResponse, void *handle);
~ClientChannel();
+#ifdef USE_GDBUS
+ static void channel_transmit_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data);
+ static void channel_close_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data);
+#else
static bool dispatcherCallback(void *message);
-
+#endif
public:
- int close(closeCallback callback, void *userParam);
+ int close(closeChannelCallback callback, void *userParam);
int transmit(ByteArray command, transmitCallback callback,
void *userParam);
throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
ErrorIllegalParameter &, ErrorSecurity &);
+#ifndef USE_GDBUS
friend class ClientDispatcher;
+#endif
friend class Session;
};
-
} /* namespace smartcard_service_api */
#endif /* __cplusplus */
#ifndef CLIENTDISPATCHER_H_
#define CLIENTDISPATCHER_H_
-
+#ifndef USE_GDBUS
/* standard library header */
#include <map>
};
} /* namespace open_mobile_api */
+#endif /* USE_GDBUS */
#endif /* CLIENTDISPATCHER_H_ */
#ifndef CLIENTIPC_H_
#define CLIENTIPC_H_
-
+#ifndef USE_GDBUS
/* standard library header */
#ifdef USE_AUTOSTART
#include <dbus/dbus-glib.h>
};
} /* namespace open_mobile_api */
+#endif /* USE_GDBUS */
#endif /* CLIENTIPC_H_ */
#define READER_H_
/* standard library header */
+#ifdef USE_GDBUS
+#include <glib.h>
+#include <gio/gio.h>
+#endif
/* SLP library header */
private:
void *context;
void *handle;
+#ifdef USE_GDBUS
+ void *proxy;
+#else
/* temporary data for sync function */
int error;
Session *openedSession;
+#endif
Reader(void *context, const char *name, void *handle);
~Reader();
- void unavailable();
-
+ inline void unavailable() { present = false; }
+#ifdef USE_GDBUS
+ static void reader_open_session_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data);
+#else
static bool dispatcherCallback(void *message);
+#endif
public:
void closeSessions()
ErrorIllegalParameter &, ErrorSecurity &);
friend class SEService;
+#ifndef USE_GDBUS
friend class ClientDispatcher;
+#endif
};
} /* namespace smartcard_service_api */
#endif /* __cplusplus */
#define SESERVICE_H_
/* standard library header */
+#ifdef USE_GDBUS
+#include <glib.h>
+#include <gio/gio.h>
+#endif
/* SLP library header */
void *context;
serviceConnected handler;
SEServiceListener *listener;
-
+#ifdef USE_GDBUS
+ void *proxy;
+#endif
SEService();
- static bool dispatcherCallback(void *message);
+ void addReader(unsigned int handle, const char *name);
bool parseReaderInformation(unsigned int count, ByteArray data);
+#ifdef USE_GDBUS
+ bool parseReaderInformation(GVariant *variant);
+#else
+ static bool dispatcherCallback(void *message);
+#endif
bool _initialize()
throw(ErrorIO &);
SEService *initializeSync(void *context, serviceConnected handler)
throw(ErrorIO &, ErrorIllegalParameter &);
+#ifdef USE_GDBUS
+ static void reader_inserted(GObject *source_object,
+ guint reader_id, gchar *reader_name,
+ gpointer user_data);
+ static void reader_removed(GObject *source_object,
+ guint reader_id, gchar *reader_name,
+ gpointer user_data);
+ static void se_service_shutdown_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data);
+ static void se_service_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data);
+#endif
public:
SEService(void *user_data, serviceConnected handler)
throw(ErrorIO &, ErrorIllegalParameter &);
void shutdown();
void shutdownSync();
+#ifndef USE_GDBUS
friend class ClientDispatcher;
+#endif
};
} /* namespace smartcard_service_api */
#endif /* __cplusplus */
#define SESSION_H_
/* standard library header */
+#ifdef USE_GDBUS
+#include <gio/gio.h>
+#endif
/* SLP library header */
private:
void *context;
void *handle;
+#ifdef USE_GDBUS
+ void *proxy;
+#else
/* temporary data for sync function */
int error;
Channel *openedChannel;
unsigned int channelCount;
-
+#endif
Session(void *context, Reader *reader, void *handle);
~Session();
- int openChannel(int id, ByteArray aid, openChannelCallback callback, void *userData);
- static bool dispatcherCallback(void *message);
-
- Channel *openChannelSync(int id, ByteArray aid)
+ int openChannel(int id, ByteArray &aid, openChannelCallback callback, void *userData);
+ Channel *openChannelSync(int id, ByteArray &aid)
throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
ErrorIllegalParameter &, ErrorSecurity &);
+#ifdef USE_GDBUS
+ static void session_get_atr_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data);
+ static void session_open_channel_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data);
+ static void session_close_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data);
+#else
+ static bool dispatcherCallback(void *message);
+#endif
public:
void closeChannels()
int getATR(getATRCallback callback, void *userData);
int close(closeSessionCallback callback, void *userData);
- int openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData);
+ int openBasicChannel(ByteArray &aid, openChannelCallback callback, void *userData);
int openBasicChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData);
- int openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData);
+ int openLogicalChannel(ByteArray &aid, openChannelCallback callback, void *userData);
int openLogicalChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData);
int getChannelCount(getChannelCountCallback callback, void * userData);
throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
ErrorIllegalState &, ErrorIllegalParameter &);
- Channel *openBasicChannelSync(ByteArray aid)
+ Channel *openBasicChannelSync(ByteArray &aid)
throw(ErrorIO &, ErrorIllegalState &,
ErrorIllegalParameter &, ErrorSecurity &);
throw(ErrorIO &, ErrorIllegalState &,
ErrorIllegalParameter &, ErrorSecurity &);
- Channel *openLogicalChannelSync(ByteArray aid)
+ Channel *openLogicalChannelSync(ByteArray &aid)
throw(ErrorIO &, ErrorIllegalState &,
ErrorIllegalParameter &, ErrorSecurity &);
unsigned int getChannelCountSync();
+#ifndef USE_GDBUS
friend class ClientDispatcher;
+#endif
friend class Reader;
};
-
} /* namespace smartcard_service_api */
#endif /* __cplusplus */
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SRCS)
#IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
-# SET(CMAKE_BUILD_TYPE "Debug")
+# SET(CMAKE_BUILD_TYPE "Debug")
#ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
#MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs_common REQUIRED dlog glib-2.0 aul libssl pkgmgr pkgmgr-info)
+pkg_check_modules(pkgs_common REQUIRED glib-2.0 gio-unix-2.0 dlog aul libssl pkgmgr pkgmgr-info)
MESSAGE("${LIB_NAME} ld flag : ${pkgs_common_LDFLAGS}")
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${LIB_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_INSTALL_DIR})
FOREACH(hfile ${EXPORT_HEADER})
- INSTALL(FILES ${hfile} DESTINATION include/${LIB_NAME})
+ INSTALL(FILES ${hfile} DESTINATION include/${LIB_NAME})
ENDFOREACH(hfile)
--- /dev/null
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef USE_GDBUS
+#include "GDBusHelper.h"
+
+namespace smartcard_service_api
+{
+ GDBusHelper::GDBusHelper()
+ {
+ }
+
+ GDBusHelper::~GDBusHelper()
+ {
+ }
+
+ void GDBusHelper::convertVariantToByteArray(GVariant *var,
+ ByteArray &array)
+ {
+ GVariantIter *iter;
+ guint8 element;
+ guint8 *buf = NULL;
+ guint size = 0;
+ guint i;
+
+ g_variant_get(var, "a(y)", &iter);
+
+ size = g_variant_iter_n_children(iter);
+ buf = g_new0(guint8, size);
+
+ for (i = 0; g_variant_iter_loop(iter, "(y)", &element); i++)
+ {
+ buf[i] = element;
+ }
+
+ g_variant_iter_free(iter);
+
+ array.setBuffer((uint8_t *)buf, (uint32_t)i);
+
+ g_free(buf);
+ }
+
+ GVariant *GDBusHelper::convertByteArrayToVariant(const ByteArray &array)
+ {
+ GVariantBuilder builder;
+ uint32_t i;
+
+ g_variant_builder_init(&builder, G_VARIANT_TYPE("a(y)"));
+
+ for (i = 0; i < array.getLength(); i++)
+ g_variant_builder_add(&builder, "(y)", array[i]);
+
+ return g_variant_builder_end(&builder);
+ }
+} /* namespace smartcard_service_api */
+#endif
* limitations under the License.
*/
+#ifndef USE_GDBUS
/* standard library header */
#include <stdio.h>
#include <stdlib.h>
}
} /* namespace smartcard_service_api */
+#endif
typedef void (*transmitCallback)(unsigned char *buffer, unsigned int length,
int error, void *userParam);
- typedef void (*closeCallback)(int error, void *userParam);
+ typedef void (*closeChannelCallback)(int error, void *userParam);
class Channel : public Synchronous
{
inline ByteArray getSelectResponse() const throw() { return selectResponse; }
inline SessionHelper *getSession() const throw() { return session; }
- virtual int close(closeCallback callback, void *userParam) = 0;
+ virtual int close(closeChannelCallback callback, void *userParam) = 0;
virtual int transmit(ByteArray command, transmitCallback callback, void *userData) = 0;
virtual void closeSync()
#include "smartcard-types.h"
+#define THROW_ERROR(errorCode) \
+ { \
+ switch (errorCode) \
+ { \
+ case SCARD_ERROR_OK : \
+ /* do nothing */ \
+ break; \
+ \
+ case SCARD_ERROR_IPC_FAILED : \
+ case SCARD_ERROR_IO_FAILED : \
+ case SCARD_ERROR_OPERATION_TIMEOUT : \
+ throw ErrorIO(errorCode); \
+ break; \
+ \
+ case SCARD_ERROR_SECURITY_NOT_ALLOWED : \
+ throw ErrorSecurity(errorCode); \
+ break; \
+ \
+ case SCARD_ERROR_UNAVAILABLE : \
+ case SCARD_ERROR_NOT_SUPPORTED : \
+ case SCARD_ERROR_NOT_INITIALIZED : \
+ case SCARD_ERROR_SE_NOT_INITIALIZED : \
+ case SCARD_ERROR_ILLEGAL_STATE : \
+ case SCARD_ERROR_OPERATION_NOT_SUPPORTED : \
+ throw ErrorIllegalState(errorCode); \
+ break; \
+ \
+ case SCARD_ERROR_ILLEGAL_PARAM : \
+ case SCARD_ERROR_ILLEGAL_REFERENCE : \
+ throw ErrorIllegalParameter(errorCode); \
+ break; \
+ \
+ default : \
+ case SCARD_ERROR_UNKNOWN : \
+ case SCARD_ERROR_OUT_OF_MEMORY : \
+ case SCARD_ERROR_NOT_ENOUGH_RESOURCE : \
+ case SCARD_ERROR_NEED_MORE_BUFFER : \
+ throw ExceptionBase(errorCode); \
+ break; \
+ } \
+ }
+
namespace smartcard_service_api
{
class ExceptionBase : public std::exception
--- /dev/null
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GDBUSHELPER_H_
+#define GDBUSHELPER_H_
+
+#ifdef USE_GDBUS
+#include <glib.h>
+
+#include "ByteArray.h"
+
+namespace smartcard_service_api
+{
+ class CallbackParam
+ {
+ public :
+ void *instance;
+ void *callback;
+ void *user_param;
+ };
+
+ class GDBusHelper
+ {
+ public :
+ GDBusHelper();
+ ~GDBusHelper();
+
+ static void convertVariantToByteArray(GVariant *var,
+ ByteArray &array);
+
+ static GVariant *convertByteArrayToVariant(
+ const ByteArray &array);
+ };
+} /* namespace smartcard_service_api */
+#endif
+#endif /* GDBUSHELPER_H_ */
#ifndef IPCHELPER_H_
#define IPCHELPER_H_
+#ifndef USE_GDBUS
/* standard library header */
#include <glib.h>
#include <pthread.h>
};
} /* namespace smartcard_service_api */
+#endif
#endif /* IPCHELPER_H_ */
virtual int getATR(getATRCallback callback, void *userData) = 0;
virtual int close(closeSessionCallback callback, void *userData) = 0;
- virtual int openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData) = 0;
+ virtual int openBasicChannel(ByteArray &aid, openChannelCallback callback, void *userData) = 0;
virtual int openBasicChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData) = 0;
- virtual int openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData) = 0;
+ virtual int openLogicalChannel(ByteArray &aid, openChannelCallback callback, void *userData) = 0;
virtual int openLogicalChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData) = 0;
virtual ByteArray getATRSync()
throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
ErrorIllegalState &, ErrorIllegalParameter &) = 0;
- virtual Channel *openBasicChannelSync(ByteArray aid)
+ virtual Channel *openBasicChannelSync(ByteArray &aid)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &) = 0;
virtual Channel *openBasicChannelSync(unsigned char *aid, unsigned int length)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &) = 0;
- virtual Channel *openLogicalChannelSync(ByteArray aid)
+ virtual Channel *openLogicalChannelSync(ByteArray &aid)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &) = 0;
virtual Channel *openLogicalChannelSync(unsigned char *aid, unsigned int length)
--- /dev/null
+<!--
+ org.tizen.SmartcardService
+-->
+
+<node>
+ <interface name="org.tizen.SmartcardService.SeService">
+ <!--
+ SeService
+ -->
+ <method name="SeService">
+ <arg type="i" name="result" direction="out" />
+ <arg type="u" name="handle" direction="out" />
+ <arg type="a(us)" name="readers" direction="out" />
+ </method>
+
+ <!--
+ shutdown
+ -->
+ <method name="shutdown">
+ <arg type="u" name="service_id" direction="in" />
+ <arg type="i" name="result" direction="out" />
+ </method>
+
+ <!--
+ ReaderInserted
+ -->
+ <signal name="ReaderInserted">
+ <arg type="u" name="reader_id" />
+ <arg type="s" name="reader_name" />
+ </signal>
+
+ <!--
+ ReaderRemoved
+ -->
+ <signal name="ReaderRemoved">
+ <arg type="u" name="reader_id" />
+ <arg type="s" name="reader_name" />
+ </signal>
+ </interface>
+
+ <interface name="org.tizen.SmartcardService.Reader">
+ <!--
+ openSession
+ -->
+ <method name="openSession">
+ <arg type="u" name="service_id" direction="in" />
+ <arg type="u" name="reader_id" direction="in" />
+ <arg type="i" name="result" direction="out" />
+ <arg type="u" name="handle" direction="out" />
+ </method>
+ </interface>
+
+ <interface name="org.tizen.SmartcardService.Session">
+ <!--
+ getATR
+ -->
+ <method name="getATR">
+ <arg type="u" name="service_id" direction="in" />
+ <arg type="u" name="session_id" direction="in" />
+ <arg type="i" name="result" direction="out" />
+ <arg type="a(y)" name="atr" direction="out" />
+ </method>
+ <!--
+ openChannel
+ -->
+ <method name="openChannel">
+ <arg type="u" name="service_id" direction="in" />
+ <arg type="u" name="session_id" direction="in" />
+ <arg type="u" name="type" direction="in" />
+ <arg type="a(y)" name="aid" direction="in" />
+ <arg type="i" name="result" direction="out" />
+ <arg type="u" name="handle" direction="out" />
+ <arg type="a(y)" name="select_response" direction="out" />
+ </method>
+ <!--
+ closeSession
+ -->
+ <method name="closeSession">
+ <arg type="u" name="service_id" direction="in" />
+ <arg type="u" name="session_id" direction="in" />
+ <arg type="i" name="result" direction="out" />
+ </method>
+ </interface>
+
+ <interface name="org.tizen.SmartcardService.Channel">
+ <!--
+ transmit
+ -->
+ <method name="transmit">
+ <arg type="u" name="service_id" direction="in" />
+ <arg type="u" name="channel_id" direction="in" />
+ <arg type="a(y)" name="command" direction="in" />
+ <arg type="i" name="result" direction="out" />
+ <arg type="a(y)" name="response" direction="out" />
+ </method>
+ <!--
+ closeChannel
+ -->
+ <method name="closeChannel">
+ <arg type="u" name="service_id" direction="in" />
+ <arg type="u" name="channel_id" direction="in" />
+ <arg type="i" name="result" direction="out" />
+ </method>
+ </interface>
+</node>
+# FOR COMMENTING DEFINITION, MUST USE %% instead of %
+%global use_autostart "-DUSE_AUTOSTART=1"
+%global use_gdbus "-DUSE_GDBUS=1"
+#%%global test_client "-DTEST_CLIENT=1"
+
Name: smartcard-service
Summary: Smartcard Service FW
-Version: 0.1.19
-Release: 3
+Version: 0.1.20
+Release: 0
Group: libs
License: Apache-2.0
Source0: %{name}-%{version}.tar.gz
-#IFNDEF USE_AUTOSTART
-#Source1: smartcard-service-server.init
-#ENDIF
+%if 0%{!?use_autostart:1}
+Source1: smartcard-service-server.init
+%endif
BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(gio-unix-2.0)
BuildRequires: pkgconfig(security-server)
BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(vconf)
BuildRequires: pkgconfig(pkgmgr)
BuildRequires: pkgconfig(pkgmgr-info)
BuildRequires: cmake
+BuildRequires: python
+BuildRequires: python-xml
BuildRequires: gettext-tools
Requires(post): /sbin/ldconfig
%build
mkdir obj-arm-limux-qnueabi
cd obj-arm-limux-qnueabi
-#IFNDEF USE_AUTOSTART
-#cmake .. -DCMAKE_INSTALL_PREFIX=%{_prefix}
-#ELSE
-%cmake .. -DUSE_AUTOSTART=1 # daemon will be started when client makes instance by DBUS
-#ENDIF
+%cmake .. -DCMAKE_INSTALL_PREFIX=%{_prefix} %{?use_autostart} %{?use_gdbus} %{?test_client}
#make %{?jobs:-j%jobs}
%install
cd obj-arm-limux-qnueabi
%make_install
-#IFNDEF USE_AUTOSTART
-#%__mkdir -p %{buildroot}/etc/init.d/
-#%__mkdir -p %{buildroot}/etc/rc.d/rc3.d/
-#%__mkdir -p %{buildroot}/etc/rc.d/rc5.d/
-#%__cp -af %SOURCE1 %{buildroot}/etc/init.d/smartcard-service-server
-#chmod 755 %{buildroot}/etc/init.d/smartcard-service-server
-#ENDIF
+%if 0%{!?use_autostart:1}
+ %__mkdir -p %{buildroot}/etc/init.d/
+ %__mkdir -p %{buildroot}/etc/rc.d/rc3.d/
+ %__mkdir -p %{buildroot}/etc/rc.d/rc5.d/
+ %__cp -af %SOURCE1 %{buildroot}/etc/init.d/smartcard-service-server
+ chmod 755 %{buildroot}/etc/init.d/smartcard-service-server
+%endif
mkdir -p %{buildroot}/usr/share/license
cp -af %{_builddir}/%{name}-%{version}/packaging/smartcard-service %{buildroot}/usr/share/license/
cp -af %{_builddir}/%{name}-%{version}/packaging/smartcard-service-common %{buildroot}/usr/share/license/
%post
/sbin/ldconfig
-#IFNDEF USE_AUTOSTART
-#ln -sf /etc/init.d/smartcard-service-server /etc/rc.d/rc3.d/S79smartcard-service-server
-#ln -sf /etc/init.d/smartcard-service-server /etc/rc.d/rc5.d/S79smartcard-service-server
-#ENDIF
+%if 0%{!?use_autostart:1}
+ ln -sf /etc/init.d/smartcard-service-server /etc/rc.d/rc3.d/S79smartcard-service-server
+ ln -sf /etc/init.d/smartcard-service-server /etc/rc.d/rc5.d/S79smartcard-service-server
+%endif
%postun
/sbin/ldconfig
-#IFNDEF USE_AUTOSTART
-#rm -f /etc/rc.d/rc3.d/S79smartcard-service-server
-#rm -f /etc/rc.d/rc5.d/S79smartcard-service-server
-#ENDIF
+%if 0%{!?use_autostart:1}
+ rm -f /etc/rc.d/rc3.d/S79smartcard-service-server
+ rm -f /etc/rc.d/rc5.d/S79smartcard-service-server
+%endif
%files
%manifest smartcard-service.manifest
%manifest smartcard-service-server.manifest
%defattr(-,root,root,-)
%{_bindir}/smartcard-daemon
-#/usr/bin/smartcard-test-client
-#IFNDEF USE_AUTOSTART
-#/etc/init.d/smartcard-service-server
-#ELSE
-/usr/share/dbus-1/services/org.tizen.smartcard_service.service
-#ENDIF
+%if 0%{?test_client:1}
+ /usr/bin/smartcard-test-client
+%endif
+%if 0%{?use_autostart:1}
+ /usr/share/dbus-1/services/org.tizen.smartcard_service.service
+%else
+ /etc/init.d/smartcard-service-server
+%endif
/usr/share/license/smartcard-service-server
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(smartcard-daemon CXX)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../common/include)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs_server REQUIRED glib-2.0 gobject-2.0 security-server vconf dlog dbus-glib-1)
+pkg_check_modules(pkgs_server REQUIRED glib-2.0 gio-2.0 security-server vconf dlog dbus-glib-1)
FOREACH(flag ${pkgs_server_CFLAGS})
SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
MESSAGE("CHECK MODULE in ${PROJECT_NAME} ${pkgs_server_LDFLAGS}")
-IF("${USE_AUTOSTART}" STREQUAL "1")
- FIND_PROGRAM(DBUS_BINDING_TOOL NAMES dbus-binding-tool)
- EXEC_PROGRAM("${DBUS_BINDING_TOOL}" ARGS "--prefix=smartcard_service ${CMAKE_CURRENT_SOURCE_DIR}/smartcard-service.xml --mode=glib-server --output=${CMAKE_CURRENT_SOURCE_DIR}/include/smartcard-service-binding.h")
- EXEC_PROGRAM("${DBUS_BINDING_TOOL}" ARGS "--prefix=smartcard_service ${CMAKE_CURRENT_SOURCE_DIR}/smartcard-service.xml --mode=glib-client --output=${CMAKE_CURRENT_SOURCE_DIR}/include/smartcard-service-glue.h")
-ENDIF()
-
SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} -pipe -fomit-frame-pointer -Wall -Wno-trigraphs -fno-strict-aliasing -Wl,-zdefs -fvisibility=hidden -std=c++0x")
SET(ARM_CXXFLAGS "${ARM_CXXLAGS} -mapcs -mno-sched-prolog -mabi=aapcs-linux -Uarm -fno-common -fpic")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS}")
mapServices.clear();
}
+#ifndef USE_GDBUS
bool ClientInstance::sendMessageToAllServices(int socket, Message &msg)
{
bool result = true;
return result;
}
+#endif
void ClientInstance::generateCertificationHashes()
{
* limitations under the License.
*/
+#ifndef USE_GDBUS
/* standard library header */
#include <stdio.h>
#include <string.h>
#include "Debug.h"
#include "Exception.h"
#include "ServerDispatcher.h"
+#include "ServerIPC.h"
#include "ServerResource.h"
#include "ServerSEService.h"
#include "ServerChannel.h"
}
} /* namespace smartcard_service_api */
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef USE_GDBUS
+#include <unistd.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <vector>
+#include <string>
+#include <sys/socket.h>
+
+#include "smartcard-types.h"
+#include "Debug.h"
+#include "ByteArray.h"
+#include "ServerResource.h"
+#include "GDBusHelper.h"
+#include "ServerGDBus.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+ ServerGDBus::ServerGDBus() : dbus_proxy(NULL), connection(NULL),
+ seService(NULL), reader(NULL), session(NULL), channel(NULL)
+ {
+ }
+
+ ServerGDBus::~ServerGDBus()
+ {
+ deinit();
+ }
+
+ ServerGDBus &ServerGDBus::getInstance()
+ {
+ static ServerGDBus serverGDBus;
+
+ return serverGDBus;
+ }
+
+ void ServerGDBus::name_owner_changed(GDBusProxy *proxy,
+ const gchar *name, const gchar *old_owner,
+ const gchar *new_owner, void *user_data)
+ {
+ if (strlen(new_owner) == 0) {
+ ClientInstance *client;
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ client = resource.getClient(old_owner);
+ if (client != NULL) {
+ _INFO("terminated client, pid [%d]", client->getPID());
+ resource.removeClient(old_owner);
+
+ if (resource.getClientCount() == 0) {
+ g_main_loop_quit((GMainLoop *)resource.getMainLoopInstance());
+ }
+ }
+ }
+ }
+
+ bool ServerGDBus::_init()
+ {
+ GError *error = NULL;
+
+ /* init default context */
+ dbus_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL, /* GDBusInterfaceInfo */
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ NULL, /* GCancellable */
+ &error);
+ if (dbus_proxy == NULL)
+ {
+ _ERR("Can not create proxy : %s", error->message);
+ g_error_free(error);
+
+ return false;
+ }
+
+ g_signal_connect(dbus_proxy, "name-owner-changed",
+ G_CALLBACK(&ServerGDBus::name_owner_changed),
+ this);
+
+ return true;
+ }
+
+ void ServerGDBus::_deinit()
+ {
+ if (dbus_proxy != NULL) {
+ g_object_unref(dbus_proxy);
+ dbus_proxy = NULL;
+ }
+ }
+
+ bool ServerGDBus::init()
+ {
+ GError *error = NULL;
+
+ _init();
+
+ connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (connection != NULL) {
+ } else {
+ _ERR("Can not get connection %s", error->message);
+ g_error_free(error);
+
+ return false;
+ }
+
+ initSEService();
+ initReader();
+ initSession();
+ initChannel();
+
+ return true;
+ }
+
+ void ServerGDBus::deinit()
+ {
+ deinitSEService();
+ deinitReader();
+ deinitSession();
+ deinitChannel();
+
+ if (connection != NULL) {
+ g_object_unref(connection);
+ connection = NULL;
+ }
+
+ _deinit();
+ }
+
+ static gboolean _call_get_connection_unix_process_id_sync(
+ GDBusProxy *proxy, const gchar *arg_name, guint *out_pid,
+ GCancellable *cancellable, GError **error) {
+ GVariant *_ret;
+
+ _ret = g_dbus_proxy_call_sync(proxy,
+ "GetConnectionUnixProcessID",
+ g_variant_new("(s)", arg_name),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1, cancellable, error);
+ if (_ret != NULL) {
+ g_variant_get(_ret, "(u)", out_pid);
+ g_variant_unref(_ret);
+ }
+
+ return _ret != NULL;
+ }
+
+ pid_t ServerGDBus::getPID(const char *name)
+ {
+ guint pid = 0;
+ GError *error = NULL;
+
+ if (_call_get_connection_unix_process_id_sync(
+ (GDBusProxy *)dbus_proxy, name,
+ &pid, NULL, &error) == true) {
+ } else {
+ _ERR("_g_freedesktop_dbus_call_get_connection_unix_process_id_sync failed : %s", error->message);
+ g_error_free(error);
+ }
+
+ return pid;
+ }
+
+ /* SEService *
+ *
+ *
+ */
+ static GVariant *_reader_to_variant(vector<pair<unsigned int, string> > &readers)
+ {
+ GVariantBuilder builder;
+ uint32_t i;
+
+ g_variant_builder_init(&builder, G_VARIANT_TYPE("a(us)"));
+
+ for (i = 0; i < readers.size(); i++) {
+ g_variant_builder_add(&builder, "(us)", readers[i].first, readers[i].second.c_str());
+ }
+
+ return g_variant_builder_end(&builder);
+ }
+
+ static gboolean _handle_se_service(SmartcardServiceSeService *object,
+ GDBusMethodInvocation *invocation)
+ {
+ _INFO("[MSG_REQUEST_READERS]");
+
+ gint result = SCARD_ERROR_OK;
+ GVariant *readers = NULL;
+ vector<pair<unsigned int, string> > list;
+ unsigned int handle = IntegerHandle::INVALID_HANDLE;
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ /* load secure elements */
+ resource.loadSecureElements();
+
+ const char *name = g_dbus_method_invocation_get_sender(invocation);
+
+ pid_t pid = ServerGDBus::getInstance().getPID(name);
+
+ _INFO("service requested, pid [%d]", pid);
+
+ if (pid > 0) {
+ ClientInstance *instance;
+
+ instance = resource.getClient(name);
+ if (instance == NULL) {
+ _INFO("create client instance, pid [%d]", pid);
+
+ resource.createClient(name, pid);
+
+ instance = resource.getClient(name);
+
+ /* generate certification hashes */
+ instance->generateCertificationHashes();
+ }
+
+ if (instance != NULL) {
+ ServiceInstance *service;
+
+ /* create service */
+ service = resource.createService(name);
+ if (service != NULL) {
+
+ handle = service->getHandle();
+ resource.getReaders(list);
+
+ } else {
+ _ERR("createService failed");
+
+ result = SCARD_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ _ERR("client doesn't exist, pid [%d]", pid);
+
+ result = SCARD_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ _ERR("invalid pid, [%d]", pid);
+
+ result = SCARD_ERROR_IPC_FAILED;
+ }
+
+ readers = _reader_to_variant(list);
+ if (list.size() > 0) {
+ } else {
+ _INFO("no secure elements");
+ }
+
+ /* response to client */
+ smartcard_service_se_service_complete_se_service(object,
+ invocation, result, handle, readers);
+
+ return true;
+ }
+
+ static gboolean _handle_shutdown(SmartcardServiceSeService *object,
+ GDBusMethodInvocation *invocation, guint handle)
+ {
+ _INFO("[MSG_REQUEST_SHUTDOWN]");
+
+ const char *name = g_dbus_method_invocation_get_sender(invocation);
+
+ ServerResource::getInstance().removeService(name, handle);
+
+ /* response to client */
+ smartcard_service_se_service_complete_shutdown(object,
+ invocation, SCARD_ERROR_OK);
+
+ return true;
+ }
+
+ bool ServerGDBus::initSEService()
+ {
+ GError *error = NULL;
+
+ seService = smartcard_service_se_service_skeleton_new();
+
+ g_signal_connect(seService,
+ "handle-se-service",
+ G_CALLBACK(_handle_se_service),
+ NULL);
+
+ g_signal_connect(seService,
+ "handle-shutdown",
+ G_CALLBACK(_handle_shutdown),
+ NULL);
+
+ if (g_dbus_interface_skeleton_export(
+ G_DBUS_INTERFACE_SKELETON(seService),
+ connection,
+ "/org/tizen/SmartcardService/SeService",
+ &error) == false)
+ {
+ _ERR("Can not skeleton_export %s", error->message);
+
+ g_error_free(error);
+ g_object_unref(seService);
+ seService = NULL;
+
+ return false;
+ }
+
+ return true;
+ }
+
+ void ServerGDBus::deinitSEService()
+ {
+ if (seService != NULL) {
+ g_object_unref(seService);
+ seService = NULL;
+ }
+ }
+
+ /* Reader *
+ *
+ *
+ */
+ static gboolean _handle_open_session(SmartcardServiceReader *object,
+ GDBusMethodInvocation *invocation, guint service_id,
+ guint reader_id)
+ {
+ unsigned int handle = IntegerHandle::INVALID_HANDLE;
+ int result;
+
+ _INFO("[MSG_REQUEST_OPEN_SESSION]");
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ const char *name = g_dbus_method_invocation_get_sender(invocation);
+
+ if (resource.isValidReaderHandle(reader_id))
+ {
+ vector<ByteArray> temp;
+
+ handle = resource.createSession(name, service_id, reader_id, temp, (void *)NULL);
+ if (handle != IntegerHandle::INVALID_HANDLE)
+ {
+ result = SCARD_ERROR_OK;
+ }
+ else
+ {
+ _ERR("createSession failed [%d]", handle);
+ result = SCARD_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ else
+ {
+ _ERR("request invalid reader handle [%d]", reader_id);
+ result = SCARD_ERROR_ILLEGAL_PARAM;
+ }
+
+ /* response to client */
+ smartcard_service_reader_complete_open_session(object,
+ invocation, result, handle);
+
+ return true;
+ }
+
+ bool ServerGDBus::initReader()
+ {
+ GError *error = NULL;
+
+ reader = smartcard_service_reader_skeleton_new();
+
+ g_signal_connect(reader,
+ "handle-open-session",
+ G_CALLBACK(_handle_open_session),
+ NULL);
+
+ if (g_dbus_interface_skeleton_export(
+ G_DBUS_INTERFACE_SKELETON(reader),
+ connection,
+ "/org/tizen/SmartcardService/Reader",
+ &error) == false)
+ {
+ _ERR("Can not skeleton_export %s", error->message);
+
+ g_error_free(error);
+ g_object_unref(reader);
+ reader = NULL;
+
+ return false;
+ }
+
+ return true;
+ }
+
+ void ServerGDBus::deinitReader()
+ {
+ if (reader != NULL) {
+ g_object_unref(reader);
+ reader = NULL;
+ }
+ }
+
+ /* Session *
+ *
+ *
+ */
+ static gboolean _handle_close_session(SmartcardServiceSession *object,
+ GDBusMethodInvocation *invocation, guint service_id,
+ guint session_id)
+ {
+ _INFO("[MSG_REQUEST_CLOSE_SESSION]");
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ const char *name = g_dbus_method_invocation_get_sender(invocation);
+
+ if (resource.isValidSessionHandle(name, service_id, session_id))
+ {
+ resource.removeSession(name, service_id, session_id);
+ }
+
+ /* response to client */
+ smartcard_service_session_complete_close_session(object,
+ invocation, SCARD_ERROR_OK);
+
+ return true;
+ }
+
+ static gboolean _handle_get_atr(SmartcardServiceSession *object,
+ GDBusMethodInvocation *invocation, guint service_id,
+ guint session_id)
+ {
+ int result;
+ GVariant *atr = NULL;
+ ServiceInstance *client = NULL;
+
+ _INFO("[MSG_REQUEST_GET_ATR]");
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ const char *name = g_dbus_method_invocation_get_sender(invocation);
+
+ if ((client = resource.getService(name, service_id)) != NULL)
+ {
+ Terminal *terminal = NULL;
+
+ if ((terminal = client->getTerminal(session_id)) != NULL)
+ {
+ int rv;
+ ByteArray temp;
+
+ if ((rv = terminal->getATRSync(temp)) == 0)
+ {
+ atr = GDBusHelper::convertByteArrayToVariant(temp);
+ result = SCARD_ERROR_OK;
+ }
+ else
+ {
+ _ERR("transmit failed [%d]", rv);
+
+ result = rv;
+ }
+ }
+ else
+ {
+ _ERR("getTerminal failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
+ result = SCARD_ERROR_UNAVAILABLE;
+ }
+ }
+ else
+ {
+ _ERR("getClient failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
+ result = SCARD_ERROR_UNAVAILABLE;
+ }
+
+ if (atr == NULL) {
+ atr = GDBusHelper::convertByteArrayToVariant(ByteArray::EMPTY);
+ }
+
+ /* response to client */
+ smartcard_service_session_complete_get_atr(object, invocation,
+ result, atr);
+
+ return true;
+ }
+
+ static gboolean _handle_open_channel(SmartcardServiceSession *object,
+ GDBusMethodInvocation *invocation, guint service_id,
+ guint session_id, guint type, GVariant *aid)
+ {
+ int result = SCARD_ERROR_UNKNOWN;
+ GVariant *response = NULL;
+ unsigned int channelID = IntegerHandle::INVALID_HANDLE;
+
+ _INFO("[MSG_REQUEST_OPEN_CHANNEL]");
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ const char *name = g_dbus_method_invocation_get_sender(invocation);
+
+ try
+ {
+ ByteArray tempAid;
+
+ GDBusHelper::convertVariantToByteArray(aid, tempAid);
+
+ channelID = resource.createChannel(name, service_id, session_id, type, tempAid);
+ if (channelID != IntegerHandle::INVALID_HANDLE)
+ {
+ ServerChannel *temp;
+
+ temp = (ServerChannel *)resource.getChannel(name, service_id, channelID);
+ if (temp != NULL)
+ {
+ result = SCARD_ERROR_OK;
+ response = GDBusHelper::convertByteArrayToVariant(temp->getSelectResponse());
+ }
+ }
+ else
+ {
+ _ERR("channel is null.");
+
+ /* set error value */
+ result = SCARD_ERROR_UNAVAILABLE;
+ }
+ }
+ catch (ExceptionBase &e)
+ {
+ result = e.getErrorCode();
+ }
+
+ if (response == NULL) {
+ response = GDBusHelper::convertByteArrayToVariant(ByteArray::EMPTY);
+ }
+ /* response to client */
+ smartcard_service_session_complete_open_channel(object,
+ invocation, result, channelID, response);
+
+ return true;
+ }
+
+ bool ServerGDBus::initSession()
+ {
+ GError *error = NULL;
+
+ session = smartcard_service_session_skeleton_new();
+
+ g_signal_connect(session,
+ "handle-close-session",
+ G_CALLBACK(_handle_close_session),
+ NULL);
+
+ g_signal_connect(session,
+ "handle-get-atr",
+ G_CALLBACK(_handle_get_atr),
+ NULL);
+
+ g_signal_connect(session,
+ "handle-open-channel",
+ G_CALLBACK(_handle_open_channel),
+ NULL);
+
+ if (g_dbus_interface_skeleton_export(
+ G_DBUS_INTERFACE_SKELETON(session),
+ connection,
+ "/org/tizen/SmartcardService/Session",
+ &error) == false)
+ {
+ _ERR("Can not skeleton_export %s", error->message);
+
+ g_error_free(error);
+ g_object_unref(session);
+ session = NULL;
+
+ return false;
+ }
+
+ return true;
+ }
+
+ void ServerGDBus::deinitSession()
+ {
+ if (session != NULL) {
+ g_object_unref(session);
+ session = NULL;
+ }
+ }
+
+ /* Channel *
+ *
+ *
+ */
+ static gboolean _handle_close_channel(SmartcardServiceChannel *object,
+ GDBusMethodInvocation *invocation, guint service_id,
+ guint channel_id)
+ {
+ int result;
+
+ _INFO("[MSG_REQUEST_CLOSE_CHANNEL]");
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ const char *name = g_dbus_method_invocation_get_sender(invocation);
+
+ result = SCARD_ERROR_OK;
+
+ if (resource.getChannel(name, service_id, channel_id) != NULL)
+ {
+ resource.removeChannel(name, service_id, channel_id);
+ }
+
+ /* response to client */
+ smartcard_service_channel_complete_close_channel(object,
+ invocation, result);
+
+ return true;
+ }
+
+ static gboolean _handle_transmit(SmartcardServiceChannel *object,
+ GDBusMethodInvocation *invocation, guint service_id,
+ guint channel_id, GVariant *command)
+ {
+ int result;
+ Channel *channel = NULL;
+ GVariant *response = NULL;
+
+ _INFO("[MSG_REQUEST_TRANSMIT]");
+
+ ServerResource &resource = ServerResource::getInstance();
+
+ const char *name = g_dbus_method_invocation_get_sender(invocation);
+
+ if ((channel = resource.getChannel(name, service_id, channel_id)) != NULL)
+ {
+ int rv;
+ ByteArray cmd, resp;
+
+ GDBusHelper::convertVariantToByteArray(command, cmd);
+
+ if ((rv = channel->transmitSync(cmd, resp)) == 0)
+ {
+ response = GDBusHelper::convertByteArrayToVariant(resp);
+ result = SCARD_ERROR_OK;
+ }
+ else
+ {
+ _ERR("transmit failed [%d]", rv);
+ result = rv;
+ }
+ }
+ else
+ {
+ _ERR("invalid handle : name [%s], service_id [%d], channel_id [%d]", name, service_id, channel_id);
+ result = SCARD_ERROR_UNAVAILABLE;
+ }
+
+ if (response == NULL) {
+ response = GDBusHelper::convertByteArrayToVariant(ByteArray::EMPTY);
+ }
+
+ /* response to client */
+ smartcard_service_channel_complete_transmit(object, invocation,
+ result, response);
+
+ return true;
+ }
+
+ bool ServerGDBus::initChannel()
+ {
+ GError *error = NULL;
+
+ channel = smartcard_service_channel_skeleton_new();
+
+ g_signal_connect(channel,
+ "handle-close-channel",
+ G_CALLBACK(_handle_close_channel),
+ NULL);
+
+ g_signal_connect(channel,
+ "handle-transmit",
+ G_CALLBACK(_handle_transmit),
+ NULL);
+
+ if (g_dbus_interface_skeleton_export(
+ G_DBUS_INTERFACE_SKELETON(channel),
+ connection,
+ "/org/tizen/SmartcardService/Channel",
+ &error) == false)
+ {
+ _ERR("Can not skeleton_export %s", error->message);
+
+ g_error_free(error);
+ g_object_unref(channel);
+ channel = NULL;
+
+ return false;
+ }
+
+ return true;
+ }
+
+ void ServerGDBus::deinitChannel()
+ {
+ if (channel != NULL) {
+ g_object_unref(channel);
+ channel = NULL;
+ }
+ }
+} /* namespace smartcard_service_api */
+#endif
* limitations under the License.
*/
+#ifndef USE_GDBUS
/* standard library header */
#include <string.h>
#include <sys/socket.h>
ipc->createListenSocket();
}
+#endif /* USE_GDBUS */
#define EXTERN_API __attribute__((visibility("default")))
#endif
+using namespace std;
+
namespace smartcard_service_api
{
unsigned int IntegerHandle::newHandle = 0;
: mainLoop(NULL), seLoaded(false)
{
_BEGIN();
-
+#ifndef USE_GDBUS
serverIPC = ServerIPC::getInstance();
serverDispatcher = ServerDispatcher::getInstance();
-
+#endif
_END();
}
return serverResource;
}
+#ifdef USE_GDBUS
+ bool ServerResource::createClient(const char *name, pid_t pid)
+ {
+ bool result = false;
+
+ if (getClient(name) == NULL)
+ {
+ ClientInstance *instance = new ClientInstance(name, pid);
+ if (instance != NULL)
+ {
+ mapClients.insert(make_pair(name, instance));
+ result = true;
+ }
+ else
+ {
+ _ERR("alloc failed");
+ }
+ }
+ else
+ {
+ _ERR("client already exist, name [%s]", name);
+ }
+
+ return result;
+ }
+
+ ClientInstance *ServerResource::getClient(const char *name)
+ {
+ ClientInstance *result = NULL;
+ map<string, ClientInstance *>::iterator item;
+
+ if ((item = mapClients.find(name)) != mapClients.end())
+ {
+ result = item->second;
+ }
+
+ return result;
+ }
+
+ void ServerResource::removeClient(const char *name)
+ {
+ map<string, ClientInstance *>::iterator item;
+
+ if ((item = mapClients.find(name)) != mapClients.end())
+ {
+ delete item->second;
+ mapClients.erase(item);
+ }
+ else
+ {
+ _DBG("client removed already, name [%s]", name);
+ }
+ }
+
+ void ServerResource::removeClients()
+ {
+ map<string, ClientInstance *>::iterator item;
+
+ for (item = mapClients.begin(); item != mapClients.end(); item++)
+ {
+ delete item->second;
+ }
+
+ mapClients.clear();
+ }
+
+ int ServerResource::getClientCount()
+ {
+ return (int)mapClients.size();
+ }
+
+ ServiceInstance *ServerResource::createService(const char *name)
+ {
+ ServiceInstance *result = NULL;
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(name)) != NULL)
+ {
+ if ((result = instance->createService()) == NULL)
+ {
+ _ERR("ClientInstance::createService failed [%d]", name);
+ }
+ }
+ else
+ {
+ _ERR("client doesn't exist, name [%s]", name);
+ }
+
+ return result;
+ }
+
+ ServiceInstance *ServerResource::getService(const char *name, unsigned int handle)
+ {
+ ServiceInstance *result = NULL;
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(name)) != NULL)
+ {
+ result = instance->getService(handle);
+ }
+ else
+ {
+ _ERR("client doesn't exist, name [%s]", name);
+ }
+
+ return result;
+ }
+
+ void ServerResource::removeService(const char *name, unsigned int handle)
+ {
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(name)) != NULL)
+ {
+ instance->removeService(handle);
+ }
+ else
+ {
+ _ERR("client doesn't exist, name [%s]", name);
+ }
+ }
+
+ void ServerResource::removeServices(const char *name)
+ {
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(name)) != NULL)
+ {
+ instance->removeServices();
+ }
+ else
+ {
+ _ERR("client doesn't exist, name [%s]", name);
+ }
+ }
+
+ unsigned int ServerResource::createSession(const char *name, unsigned int handle, unsigned int readerID, vector<ByteArray> &certHashes, void *caller)
+ {
+ unsigned int result = -1;
+ Terminal *temp = NULL;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(name, handle)) != NULL)
+ {
+ if ((temp = getTerminalByReaderID(readerID)) != NULL)
+ {
+ result = instance->openSession(temp, certHashes, caller);
+ }
+ }
+ else
+ {
+ _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
+ }
+
+ return result;
+ }
+
+ ServerSession *ServerResource::getSession(const char *name, unsigned int handle, unsigned int sessionID)
+ {
+ ServerSession *result = NULL;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(name, handle)) != NULL)
+ {
+ result = instance->getSession(sessionID);
+ }
+ else
+ {
+ _ERR("Session doesn't exist : name [%s], handle [%d], handle [%d]", name, handle, sessionID);
+ }
+
+ return result;
+ }
+
+ bool ServerResource::isValidSessionHandle(const char *name, unsigned int handle, unsigned int session)
+ {
+ ServiceInstance *instance = NULL;
+
+ return (((instance = getService(name, handle)) != NULL) && (instance->isVaildSessionHandle(session)));
+ }
+
+ unsigned int ServerResource::getChannelCount(const char *name, unsigned int handle, unsigned int sessionID)
+ {
+ unsigned int result = -1;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(name, handle)) != NULL)
+ {
+ result = instance->getChannelCountBySession(sessionID);
+ }
+ else
+ {
+ _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
+ }
+
+ return result;
+ }
+
+ void ServerResource::removeSession(const char *name, unsigned int handle, unsigned int sessionID)
+ {
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(name, handle)) != NULL)
+ {
+ instance->closeSession(sessionID);
+ }
+ else
+ {
+ _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
+ }
+ }
+
+ unsigned int ServerResource::createChannel(const char *name, unsigned int handle, unsigned int sessionID, int channelType, ByteArray aid)
+ throw(ExceptionBase &)
+ {
+ unsigned int result = -1;
+ ServiceInstance *service = NULL;
+
+ if ((service = getService(name, handle)) != NULL)
+ {
+ if (service->isVaildSessionHandle(sessionID) == true)
+ {
+ ServerSession *session = NULL;
+ Terminal *terminal = NULL;
+
+ terminal = service->getTerminal(sessionID);
+ session = service->getSession(sessionID);
+ if (terminal != NULL && session != NULL)
+ {
+ result = _createChannel(terminal, service, channelType, sessionID, aid);
+ if (result == IntegerHandle::INVALID_HANDLE)
+ {
+ _ERR("create channel failed [%d]", sessionID);
+ }
+ }
+ else
+ {
+ _ERR("session is invalid [%d]", sessionID);
+ throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
+ }
+ }
+ else
+ {
+ _ERR("session is invalid [%d]", sessionID);
+ throw ExceptionBase(SCARD_ERROR_ILLEGAL_STATE);
+ }
+ }
+ else
+ {
+ _ERR("getService is failed, name [%s], handle [%d]", name, handle);
+ throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
+ }
+
+ return result;
+ }
+
+ Channel *ServerResource::getChannel(const char *name, unsigned int handle, unsigned int channelID)
+ {
+ Channel *result = NULL;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(name, handle)) != NULL)
+ {
+ result = instance->getChannel(channelID);
+ }
+ else
+ {
+ _ERR("Channel doesn't exist : name [%s], handle [%d], handle [%d]", name, handle, channelID);
+ }
+
+ return result;
+ }
+
+ void ServerResource::removeChannel(const char *name, unsigned int handle, unsigned int channelID)
+ {
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(name, handle)) != NULL)
+ {
+ instance->closeChannel(channelID);
+ }
+ else
+ {
+ _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
+ }
+ }
+#else
bool ServerResource::createClient(void *ioChannel, int socket, int watchID, int state, int pid)
{
bool result = false;
}
else
{
- _ERR("client already exist [%d]", socket);
+ _ERR("client already exist, socket[%d]", socket);
+ }
+
+ return result;
+ }
+
+ bool ServerResource::createClient(int pid)
+ {
+ bool result = false;
+
+ if (getClient(pid) == NULL)
+ {
+ ClientInstance *instance = new ClientInstance(pid);
+ if (instance != NULL)
+ {
+ mapClients.insert(make_pair(pid, instance));
+ result = true;
+ }
+ else
+ {
+ _ERR("alloc failed");
+ }
+ }
+ else
+ {
+ _ERR("client already exist, pid[%d]", pid);
}
return result;
}
}
- int ServerResource::getClientCount()
- {
- return (int)mapClients.size();
- }
-
void ServerResource::removeClient(int socket)
{
map<int, ClientInstance *>::iterator item;
if ((item = mapClients.find(socket)) != mapClients.end())
{
+#ifndef USE_GDBUS
ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
-
+#endif
delete item->second;
mapClients.erase(item);
}
for (item = mapClients.begin(); item != mapClients.end(); item++)
{
- ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
-
- delete item->second;
+#ifndef USE_GDBUS
+ ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
+#endif
+ delete item->second;
+ }
+
+ mapClients.clear();
+ }
+
+ int ServerResource::getClientCount()
+ {
+ return (int)mapClients.size();
+ }
+
+ ServiceInstance *ServerResource::createService(int socket)
+ {
+ ServiceInstance *result = NULL;
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(socket)) != NULL)
+ {
+ if ((result = instance->createService()) == NULL)
+ {
+ _ERR("ClientInstance::createService failed [%d]", socket);
+ }
+ }
+ else
+ {
+ _ERR("client doesn't exist [%d]", socket);
+ }
+
+ return result;
+ }
+
+ ServiceInstance *ServerResource::getService(int socket, unsigned int handle)
+ {
+ ServiceInstance *result = NULL;
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(socket)) != NULL)
+ {
+ result = instance->getService(handle);
+ }
+ else
+ {
+ _ERR("client doesn't exist [%d]", socket);
+ }
+
+ return result;
+ }
+
+ void ServerResource::removeService(int socket, unsigned int handle)
+ {
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(socket)) != NULL)
+ {
+ instance->removeService(handle);
+ }
+ else
+ {
+ _ERR("client doesn't exist [%d]", socket);
+ }
+ }
+
+ void ServerResource::removeServices(int socket)
+ {
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(socket)) != NULL)
+ {
+ instance->removeServices();
+ }
+ else
+ {
+ _ERR("client doesn't exist [%d]", socket);
+ }
+ }
+
+ unsigned int ServerResource::createSession(int socket, unsigned int handle, unsigned int readerID, vector<ByteArray> &certHashes, void *caller)
+ {
+ unsigned int result = -1;
+ Terminal *temp = NULL;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(socket, handle)) != NULL)
+ {
+ if ((temp = getTerminalByReaderID(readerID)) != NULL)
+ {
+ result = instance->openSession(temp, certHashes, caller);
+ }
+ }
+ else
+ {
+ _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
+ }
+
+ return result;
+ }
+
+ ServerSession *ServerResource::getSession(int socket, unsigned int handle, unsigned int sessionID)
+ {
+ ServerSession *result = NULL;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(socket, handle)) != NULL)
+ {
+ result = instance->getSession(sessionID);
+ }
+ else
+ {
+ _ERR("Session doesn't exist : socket [%d], handle [%d], handle [%d]", socket, handle, sessionID);
+ }
+
+ return result;
+ }
+
+ bool ServerResource::isValidSessionHandle(int socket, unsigned int handle, unsigned int session)
+ {
+ ServiceInstance *instance = NULL;
+
+ return (((instance = getService(socket, handle)) != NULL) && (instance->isVaildSessionHandle(session)));
+ }
+
+ unsigned int ServerResource::getChannelCount(int socket, unsigned int handle, unsigned int sessionID)
+ {
+ unsigned int result = -1;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(socket, handle)) != NULL)
+ {
+ result = instance->getChannelCountBySession(sessionID);
+ }
+ else
+ {
+ _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
}
- mapClients.clear();
+ return result;
}
- ServiceInstance *ServerResource::createService(int socket)
+ void ServerResource::removeSession(int socket, unsigned int handle, unsigned int sessionID)
{
- ServiceInstance *result = NULL;
- ClientInstance *instance = NULL;
+ ServiceInstance *instance = NULL;
- if ((instance = getClient(socket)) != NULL)
+ if ((instance = getService(socket, handle)) != NULL)
{
- if ((result = instance->createService()) == NULL)
- {
- _ERR("ClientInstance::createService failed [%d]", socket);
- }
+ instance->closeSession(sessionID);
}
else
{
- _ERR("client doesn't exist [%d]", socket);
+ _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
}
-
- return result;
}
- ServiceInstance *ServerResource::getService(int socket, unsigned int handle)
+ unsigned int ServerResource::createChannel(int socket, unsigned int handle, unsigned int sessionID, int channelType, ByteArray aid)
+ throw(ExceptionBase &)
{
- ServiceInstance *result = NULL;
- ClientInstance *instance = NULL;
+ unsigned int result = -1;
+ ServiceInstance *service = NULL;
- if ((instance = getClient(socket)) != NULL)
+ if ((service = getService(socket, handle)) != NULL)
{
- result = instance->getService(handle);
+ if (service->isVaildSessionHandle(sessionID) == true)
+ {
+ ServerSession *session = NULL;
+ Terminal *terminal = NULL;
+
+ terminal = service->getTerminal(sessionID);
+ session = service->getSession(sessionID);
+ if (terminal != NULL && session != NULL)
+ {
+ result = _createChannel(terminal, service, channelType, sessionID, aid);
+ if (result == IntegerHandle::INVALID_HANDLE)
+ {
+ _ERR("create channel failed [%d]", sessionID);
+ }
+ }
+ else
+ {
+ _ERR("session is invalid [%d]", sessionID);
+ throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
+ }
+ }
+ else
+ {
+ _ERR("session is invalid [%d]", sessionID);
+ throw ExceptionBase(SCARD_ERROR_ILLEGAL_STATE);
+ }
}
else
{
- _ERR("client doesn't exist [%d]", socket);
+ _ERR("getService is failed [%d] [%d]", socket, handle);
+ throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
}
return result;
}
- void ServerResource::removeService(int socket, unsigned int handle)
+ Channel *ServerResource::getChannel(int socket, unsigned int handle, unsigned int channelID)
{
- ClientInstance *instance = NULL;
+ Channel *result = NULL;
+ ServiceInstance *instance = NULL;
- if ((instance = getClient(socket)) != NULL)
+ if ((instance = getService(socket, handle)) != NULL)
{
- instance->removeService(handle);
+ result = instance->getChannel(channelID);
}
else
{
- _ERR("client doesn't exist [%d]", socket);
+ _ERR("Channel doesn't exist : socket [%d], handle [%d], handle [%d]", socket, handle, channelID);
}
+
+ return result;
}
- void ServerResource::removeServices(int socket)
+ void ServerResource::removeChannel(int socket, unsigned int handle, unsigned int channelID)
{
- ClientInstance *instance = NULL;
+ ServiceInstance *instance = NULL;
- if ((instance = getClient(socket)) != NULL)
+ if ((instance = getService(socket, handle)) != NULL)
{
- instance->removeServices();
+ instance->closeChannel(channelID);
}
else
{
- _ERR("client doesn't exist [%d]", socket);
+ _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
}
}
-
+#endif
Terminal *ServerResource::getTerminal(unsigned int terminalID)
{
Terminal *result = NULL;
return result;
}
+ Terminal *ServerResource::getTerminalByIndex(int index)
+ {
+ int count = 0;
+ Terminal *result = NULL;
+ map<unsigned int, Terminal *>::iterator item;
+
+ for (item = mapTerminals.begin(), count = 0; item != mapTerminals.end(); item++, count++) {
+ if (count == index) {
+ result = item->second;
+ break;
+ }
+ }
+
+ return result;
+ }
+
Terminal *ServerResource::getTerminalByReaderID(unsigned int readerID)
{
Terminal *result = NULL;
return result;
}
- unsigned int ServerResource::createSession(int socket, unsigned int handle, unsigned int readerID, vector<ByteArray> &certHashes, void *caller)
- {
- unsigned int result = -1;
- Terminal *temp = NULL;
- ServiceInstance *instance = NULL;
-
- if ((instance = getService(socket, handle)) != NULL)
- {
- if ((temp = getTerminalByReaderID(readerID)) != NULL)
- {
- result = instance->openSession(temp, certHashes, caller);
- }
- }
- else
- {
- _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
- }
-
- return result;
- }
-
- ServerSession *ServerResource::getSession(int socket, unsigned int handle, unsigned int sessionID)
- {
- ServerSession *result = NULL;
- ServiceInstance *instance = NULL;
-
- if ((instance = getService(socket, handle)) != NULL)
- {
- result = instance->getSession(sessionID);
- }
- else
- {
- _ERR("Session doesn't exist : socket [%d], handle [%d], handle [%d]", socket, handle, sessionID);
- }
-
- return result;
- }
-
- unsigned int ServerResource::getChannelCount(int socket, unsigned int handle, unsigned int sessionID)
- {
- unsigned int result = -1;
- ServiceInstance *instance = NULL;
-
- if ((instance = getService(socket, handle)) != NULL)
- {
- result = instance->getChannelCountBySession(sessionID);
- }
- else
- {
- _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
- }
-
- return result;
- }
-
- void ServerResource::removeSession(int socket, unsigned int handle, unsigned int sessionID)
- {
- ServiceInstance *instance = NULL;
-
- if ((instance = getService(socket, handle)) != NULL)
- {
- instance->closeSession(sessionID);
- }
- else
- {
- _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
- }
- }
-
bool ServerResource::_isAuthorizedAccess(ServerChannel *channel, int pid, ByteArray aid, vector<ByteArray> &hashes)
{
bool result = true;
return result;
}
- unsigned int ServerResource::createChannel(int socket, unsigned int handle, unsigned int sessionID, int channelType, ByteArray aid)
- throw(ExceptionBase &)
- {
- unsigned int result = -1;
- ServiceInstance *service = NULL;
-
- if ((service = getService(socket, handle)) != NULL)
- {
- if (service->isVaildSessionHandle(sessionID) == true)
- {
- ServerSession *session = NULL;
- Terminal *terminal = NULL;
-
- terminal = service->getTerminal(sessionID);
- session = service->getSession(sessionID);
- if (terminal != NULL && session != NULL)
- {
- result = _createChannel(terminal, service, channelType, sessionID, aid);
- if (result == IntegerHandle::INVALID_HANDLE)
- {
- _ERR("create channel failed [%d]", sessionID);
- }
- }
- else
- {
- _ERR("session is invalid [%d]", sessionID);
- throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
- }
- }
- else
- {
- _ERR("session is invalid [%d]", sessionID);
- throw ExceptionBase(SCARD_ERROR_ILLEGAL_STATE);
- }
- }
- else
- {
- _ERR("getService is failed [%d] [%d]", socket, handle);
- throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
- }
-
- return result;
- }
-
- Channel *ServerResource::getChannel(int socket, unsigned int handle, unsigned int channelID)
- {
- Channel *result = NULL;
- ServiceInstance *instance = NULL;
-
- if ((instance = getService(socket, handle)) != NULL)
- {
- result = instance->getChannel(channelID);
- }
- else
- {
- _ERR("Channel doesn't exist : socket [%d], handle [%d], handle [%d]", socket, handle, channelID);
- }
-
- return result;
- }
-
- void ServerResource::removeChannel(int socket, unsigned int handle, unsigned int channelID)
- {
- ServiceInstance *instance = NULL;
-
- if ((instance = getService(socket, handle)) != NULL)
- {
- instance->closeChannel(channelID);
- }
- else
- {
- _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
- }
- }
-
void ServerResource::addAccessControlList(Terminal *terminal, AccessControlList *acl)
{
map<Terminal *, AccessControlList *>::iterator item;
return (getTerminalByReaderID(reader) != NULL);
}
- bool ServerResource::isValidSessionHandle(int socket, unsigned int handle, unsigned int session)
+ void ServerResource::getReaders(vector<pair<unsigned int, string> > &readers)
{
- ServiceInstance *instance = NULL;
+ Terminal *terminal;
+ map<unsigned int, unsigned int>::iterator item;
- return (((instance = getService(socket, handle)) != NULL) && (instance->isVaildSessionHandle(session)));
+ readers.clear();
+
+ for (item = mapReaders.begin(); item != mapReaders.end(); item++)
+ {
+ if (item->second != IntegerHandle::INVALID_HANDLE)
+ {
+ terminal = getTerminal(item->second);
+ if (terminal != NULL && terminal->isSecureElementPresence() == true)
+ {
+ readers.push_back(make_pair(item->first, terminal->getName()));
+ }
+ }
+ }
}
int ServerResource::getReadersInformation(ByteArray &info)
bool ServerResource::sendMessageToAllClients(Message &msg)
{
bool result = true;
+#ifdef USE_GDBUS
+#else
map<int, ClientInstance *>::iterator item;
for (item = mapClients.begin(); item != mapClients.end(); item++)
if (item->second->sendMessageToAllServices(item->second->getSocket(), msg) == false)
result = false;
}
+#endif
return result;
}
#include "Message.h"
#include "TerminalInterface.h"
#include "ServerSEService.h"
+#include "ServerIPC.h"
#include "ServerResource.h"
namespace smartcard_service_api
bool ServerSEService::dispatcherCallback(void *message, int socket)
{
+#ifndef USE_GDBUS
int count;
ByteArray info;
Message *msg = (Message *)message;
/* response to client */
ServerIPC::getInstance()->sendMessage(socket, &response);
-
+#endif
return false;
}
namespace smartcard_service_api
{
- ServerSession::ServerSession(ServerReader *reader, vector<ByteArray> &certHashes, void *caller, Terminal *terminal):SessionHelper(reader)
+ ServerSession::ServerSession(ServerReader *reader,
+ vector<ByteArray> &certHashes,
+ void *caller, Terminal *terminal) : SessionHelper(reader)
{
- this->caller = NULL;
this->terminal = NULL;
- if (caller == NULL || terminal == NULL)
+ if (terminal == NULL)
{
_ERR("invalid param");
return;
}
- this->caller = caller;
this->terminal = terminal;
this->certHashes = certHashes;
}
channels.clear();
}
- Channel *ServerSession::openBasicChannelSync(ByteArray aid)
+ Channel *ServerSession::openBasicChannelSync(ByteArray &aid)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
return openBasicChannelSync(aid, NULL);
}
- Channel *ServerSession::openBasicChannelSync(ByteArray aid, void *caller)
+ Channel *ServerSession::openBasicChannelSync(ByteArray &aid, void *caller)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
ServerChannel *channel = NULL;
Channel *ServerSession::openBasicChannelSync(unsigned char *aid, unsigned int length)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
- return openBasicChannelSync(ByteArray(aid, length));
+ ByteArray temp(aid, length);
+
+ return openBasicChannelSync(temp);
}
Channel *ServerSession::openBasicChannelSync(unsigned char *aid, unsigned int length, void *caller)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
- return openBasicChannelSync(ByteArray(aid, length), caller);
+ ByteArray temp(aid, length);
+
+ return openBasicChannelSync(temp, caller);
}
- Channel *ServerSession::openLogicalChannelSync(ByteArray aid)
+ Channel *ServerSession::openLogicalChannelSync(ByteArray &aid)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
return openLogicalChannelSync(aid, NULL);
}
- Channel *ServerSession::openLogicalChannelSync(ByteArray aid, void *caller)
+ Channel *ServerSession::openLogicalChannelSync(ByteArray &aid, void *caller)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
ServerChannel *channel = NULL;
Channel *ServerSession::openLogicalChannelSync(unsigned char *aid, unsigned int length)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
- return openLogicalChannelSync(ByteArray(aid, length), NULL);
+ ByteArray temp(aid, length);
+
+ return openLogicalChannelSync(temp, NULL);
}
Channel *ServerSession::openLogicalChannelSync(unsigned char *aid, unsigned int length, void *caller)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &)
{
- return openLogicalChannelSync(ByteArray(aid, length), caller);
+ ByteArray temp(aid, length);
+
+ return openLogicalChannelSync(temp, caller);
}
} /* namespace smartcard_service_api */
/* standard library header */
#include <map>
#include <vector>
+#ifndef USE_GDBUS
#include <glib.h>
+#endif
/* SLP library header */
{
class ClientInstance
{
- private:
+ private :
+#ifdef USE_GDBUS
+ string name;
+#else
void *ioChannel;
int socket;
int watchID;
int state;
- int pid;
+#endif
+ pid_t pid;
vector<ByteArray> certHashes;
map<unsigned int, ServiceInstance *> mapServices;
- static gboolean _getCertificationHashes(gpointer user_data);
+ public :
+#ifdef USE_GDBUS
+ ClientInstance(const char *name, pid_t pid) : name(name), pid(pid)
+ {
+ }
+#else
+ ClientInstance(void *ioChannel, int socket, int watchID,
+ int state, int pid) : ioChannel(ioChannel),
+ socket(socket), watchID(watchID), state(state), pid(pid)
+ {
+ }
- public:
- ClientInstance(void *ioChannel, int socket, int watchID, int state, int pid)
+ ClientInstance(pid_t pid) : ioChannel(NULL),
+ socket(pid), watchID(0), state(0), pid(pid)
{
- this->ioChannel = ioChannel;
- this->socket = socket;
- this->watchID = watchID;
- this->state = state;
- this->pid = pid;
}
+#endif
~ClientInstance() { removeServices(); }
-
+#ifdef USE_GDBUS
+ inline bool operator ==(const char *name) const { return (this->name.compare(name) == 0); }
+#else
inline bool operator ==(const int &socket) const { return (this->socket == socket); }
+#endif
+#ifndef USE_GDBUS
inline void *getIOChannel() { return ioChannel; }
inline int getSocket() { return socket; }
inline int getWatchID() { return watchID; }
inline int getState() { return state; }
-
+#endif
void setPID(int pid);
inline int getPID() { return pid; }
ServiceInstance *createService();
- ServiceInstance *getService(unsigned int context);
- void removeService(unsigned int context);
+ ServiceInstance *getService(unsigned int handle);
+ void removeService(unsigned int handle);
void removeServices();
-
+#ifndef USE_GDBUS
bool sendMessageToAllServices(int socket, Message &msg);
+#endif
void generateCertificationHashes();
inline vector<ByteArray> &getCertificationHashes() { return certHashes; }
-
- friend gboolean _getCertificationHashes(gpointer user_data);
};
} /* namespace smartcard_service_api */
#endif /* CLIENTINSTANCE_H_ */
int getChannelNumber() { return channelNum; }
Terminal *getTerminal() { return terminal; }
- int close(closeCallback callback, void *userParam) { return -1; }
+ int close(closeChannelCallback callback, void *userParam) { return -1; }
int transmit(ByteArray command, transmitCallback callback, void *userParam) { return -1; };
friend class ServerReader;
#ifndef SERVERDISPATCHER_H_
#define SERVERDISPATCHER_H_
-
+#ifndef USE_GDBUS
/* standard library header */
/* SLP library header */
};
} /* namespace smartcard_service_api */
+#endif /* USE_GDBUS */
#endif /* SERVERDISPATCHER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SERVERGDBUS_H_
+#define SERVERGDBUS_H_
+
+#ifdef USE_GDBUS
+#include <glib.h>
+
+#include "smartcard-service-gdbus.h"
+
+namespace smartcard_service_api
+{
+ class ServerGDBus
+ {
+ public :
+ GDBusProxy *dbus_proxy;
+
+ static ServerGDBus &getInstance();
+
+ bool init();
+ void deinit();
+
+ /* connect to dbus daemon */
+ bool _init();
+ void _deinit();
+ pid_t getPID(const char *name);
+
+ private :
+
+ GDBusConnection *connection;
+
+ SmartcardServiceSeService *seService;
+ SmartcardServiceReader *reader;
+ SmartcardServiceSession *session;
+ SmartcardServiceChannel *channel;
+
+ ServerGDBus();
+ ~ServerGDBus();
+
+ static void name_owner_changed(GDBusProxy *proxy,
+ const gchar *name, const gchar *old_owner,
+ const gchar *new_owner, void *user_data);
+
+ bool initSEService();
+ void deinitSEService();
+
+ bool initReader();
+ void deinitReader();
+
+ bool initSession();
+ void deinitSession();
+
+ bool initChannel();
+ void deinitChannel();
+ };
+} /* namespace smartcard_service_api */
+#endif
+#endif /* SERVERGDBUS_H_ */
#ifndef SERVERIPC_H_
#define SERVERIPC_H_
-
+#ifndef USE_GDBUS
/* standard library header */
#ifdef __cplusplus
#include <map>
#ifdef __cplusplus
}
#endif /* __cplusplus */
-
+#endif /* USE_GDBUS */
#endif /* SERVERIPC_H_ */
#define SERVERRESOURCE_H_
/* standard library header */
-#ifdef __cplusplus
#include <map>
#include <vector>
#include <set>
-#endif /* __cplusplus */
+#include <string>
/* SLP library header */
/* local header */
-#ifdef __cplusplus
#include "Exception.h"
#include "Terminal.h"
#include "Lock.h"
+#ifndef USE_GDBUS
#include "ServerIPC.h"
#include "ServerDispatcher.h"
+#endif
#include "ServerReader.h"
#include "ServerSession.h"
#include "ClientInstance.h"
#include "ServiceInstance.h"
-#endif /* __cplusplus */
-#ifdef __cplusplus
using namespace std;
namespace smartcard_service_api
vector<void *> libraries;
map<unsigned int, Terminal *> mapTerminals; /* terminal unique id <-> terminal instance map */
map<unsigned int, unsigned int> mapReaders; /* reader unique id <-> terminal unique id map */
+#ifdef USE_GDBUS
+ map<string, ClientInstance *> mapClients; /* client pid <-> client instance map */
+#else
map<int, ClientInstance *> mapClients; /* client pid <-> client instance map */
+#endif
map<Terminal *, AccessControlList *> mapACL; /* terminal instance <-> access control instance map */
void *mainLoop;
+#ifndef USE_GDBUS
ServerIPC *serverIPC;
ServerDispatcher *serverDispatcher;
+#endif
bool seLoaded;
ServerResource();
bool _isAuthorizedAccess(ServerChannel *channel, int pid, ByteArray aid, vector<ByteArray> &hashes);
unsigned int _createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid)
throw(ExceptionBase &);
+
public:
/* static member */
static ServerResource &getInstance();
Terminal *getTerminal(unsigned int terminalID);
Terminal *getTerminal(const char *name);
+ Terminal *getTerminalByIndex(int index);
Terminal *getTerminalByReaderID(unsigned int readerID);
unsigned int getTerminalID(const char *name);
int getReadersInformation(ByteArray &info);
+ void getReaders(vector<pair<unsigned int, string> > &readers);
bool isValidReaderHandle(unsigned int reader);
unsigned int createReader(unsigned int terminalID);
unsigned int getReaderID(const char *name);
void removeReader(unsigned int readerID);
+#ifdef USE_GDBUS
+ bool createClient(const char *name, pid_t pid);
+ ClientInstance *getClient(const char *name);
+ void removeClient(const char *name);
+ void removeClients();
+ int getClientCount();
+
+ ServiceInstance *createService(const char *name);
+ ServiceInstance *getService(const char *name, unsigned int handle);
+ void removeService(const char *name, unsigned int handle);
+ void removeServices(const char *name);
+
+ unsigned int createSession(const char *name, unsigned int handle, unsigned int readerID, vector<ByteArray> &certHashes, void *caller);
+ ServerSession *getSession(const char *name, unsigned int handle, unsigned int sessionID);
+ unsigned int getChannelCount(const char *name, unsigned int handle, unsigned int sessionID);
+ void removeSession(const char *name, unsigned int handle, unsigned int session);
+ bool isValidSessionHandle(const char *name, unsigned int handle, unsigned int sessionID);
+
+ unsigned int createChannel(const char *name, unsigned int handle,
+ unsigned int sessionID, int channelType, ByteArray aid)
+ throw(ExceptionBase &);
+ Channel *getChannel(const char *name, unsigned int handle, unsigned int channelID);
+ void removeChannel(const char *name, unsigned int handle, unsigned int channelID);
+#else
bool createClient(void *ioChannel, int socket, int watchID, int state, int pid);
+ bool createClient(int pid);
ClientInstance *getClient(int socket);
void setPID(int socket, int pid);
- int getClientCount();
void removeClient(int socket);
void removeClients();
+ int getClientCount();
ServiceInstance *createService(int socket);
ServiceInstance *getService(int socket, unsigned int handle);
throw(ExceptionBase &);
Channel *getChannel(int socket, unsigned int handle, unsigned int channelID);
void removeChannel(int socket, unsigned int handle, unsigned int channelID);
-
+#endif
void addAccessControlList(Terminal *terminal, AccessControlList *acl);
void addAccessControlList(ServerChannel *channel, AccessControlList *acl);
AccessControlList *getAccessControlList(Terminal *terminal);
};
} /* namespace smartcard_service_api */
-#endif /* __cplusplus */
-
-/* export C API */
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-void server_resource_set_main_loop_instance(void *instance);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
#endif /* SERVERRESOURCE_H_ */
class ServerSession : public SessionHelper
{
private:
- void *caller;
Terminal *terminal;
vector<ByteArray> certHashes;
int getATR(getATRCallback callback, void *userData){ return -1; }
int close(closeSessionCallback callback, void *userData){ return -1; }
- int openBasicChannel(ByteArray aid, openChannelCallback callback, void *userData){ return -1; }
+ int openBasicChannel(ByteArray &aid, openChannelCallback callback, void *userData){ return -1; }
int openBasicChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData){ return -1; }
- int openLogicalChannel(ByteArray aid, openChannelCallback callback, void *userData){ return -1; }
+ int openLogicalChannel(ByteArray &aid, openChannelCallback callback, void *userData){ return -1; }
int openLogicalChannel(unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData){ return -1; }
public:
~ServerSession();
void closeChannels()
throw(ErrorIO &, ErrorIllegalState &);
- Channel *openBasicChannelSync(ByteArray aid)
+ Channel *openBasicChannelSync(ByteArray &aid)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
Channel *openBasicChannelSync(unsigned char *aid, unsigned int length)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
- Channel *openBasicChannelSync(ByteArray aid, void *caller)
+ Channel *openBasicChannelSync(ByteArray &aid, void *caller)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
Channel *openBasicChannelSync(unsigned char *aid, unsigned int length, void *caller)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
- Channel *openLogicalChannelSync(ByteArray aid)
+ Channel *openLogicalChannelSync(ByteArray &aid)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
Channel *openLogicalChannelSync(unsigned char *aid, unsigned int length)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
- Channel *openLogicalChannelSync(ByteArray aid, void *caller)
+ Channel *openLogicalChannelSync(ByteArray &aid, void *caller)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
Channel *openLogicalChannelSync(unsigned char *aid, unsigned int length, void *caller)
throw(ErrorIO &, ErrorIllegalState &, ErrorIllegalParameter &, ErrorSecurity &);
#include <unistd.h>
#include <string.h>
#include <glib.h>
+#include <glib-object.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <signal.h>
-#ifdef __cplusplus
#include <vector>
-#endif /* __cplusplus */
-#ifdef USE_AUTOSTART
+#if defined(USE_AUTOSTART) && !defined(USE_GDBUS)
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-bindings.h>
#endif
#include "Debug.h"
#include "ServerIPC.h"
#include "ServerResource.h"
+#ifdef USE_GDBUS
+#include "smartcard-service-gdbus.h"
+#include "ServerGDBus.h"
+#else
#ifdef USE_AUTOSTART
#include "SmartcardDbus.h"
#include "smartcard-service-binding.h"
#endif
+#endif
/* definition */
-#ifdef __cplusplus
using namespace std;
using namespace smartcard_service_api;
-#endif /* __cplusplus */
/* global variable */
-#ifdef USE_AUTOSTART
+GMainLoop *main_loop = NULL;
+#if defined(USE_AUTOSTART) && !defined(USE_GDBUS)
GObject *object = NULL;
DBusGConnection *connection = NULL;
#endif
}
#endif
+#ifdef USE_GDBUS
+static void _bus_acquired_cb(GDBusConnection *connection,
+ const gchar *path, gpointer user_data)
+{
+ _DBG("bus path : %s", path);
+
+ ServerResource::getInstance().setMainLoopInstance(main_loop);
+
+ ServerGDBus::getInstance().init();
+}
+
+static void _name_acquired_cb(GDBusConnection *connection,
+ const gchar *name, gpointer user_data)
+{
+ _DBG("name : %s", name);
+}
+
+static void _name_lost_cb(GDBusConnection *connnection,
+ const gchar *name, gpointer user_data)
+{
+ _DBG("name : %s", name);
+
+ ServerGDBus::getInstance().deinit();
+}
+
+#else
#ifdef USE_AUTOSTART
G_DEFINE_TYPE(Smartcard_Service, smartcard_service, G_TYPE_OBJECT)
_END();
}
#endif
+#endif
static void __sighandler(int sig)
{
_DBG("signal!! [%d]", sig);
+#ifdef USE_GDBUS
+#else
#ifdef USE_AUTOSTART
_finalize_dbus();
#endif
+#endif
}
int main()
{
- GMainLoop *loop = NULL;
-
+#ifdef USE_GDBUS
+ guint id = 0;
+#endif
signal(SIGTERM, &__sighandler);
#ifndef USE_AUTOSTART
daemonize();
#endif
- if (!g_thread_supported())
- {
+ if (!g_thread_supported()) {
g_thread_init(NULL);
}
- loop = g_main_new(TRUE);
+ g_type_init();
-#ifdef __cplusplus
- ServerResource::getInstance().setMainLoopInstance(loop);
+ main_loop = g_main_new(TRUE);
+
+#ifdef USE_GDBUS
+ id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
+ "org.tizen.SmartcardService",
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ _bus_acquired_cb,
+ _name_acquired_cb,
+ _name_lost_cb,
+ NULL,
+ NULL);
+#else
+ ServerResource::getInstance().setMainLoopInstance(main_loop);
ServerIPC::getInstance()->createListenSocket();
-#else /* __cplusplus */
- server_resource_set_main_loop_instance(loop);
- server_ipc_create_listen_socket();
-#endif /* __cplusplus */
-
#ifdef USE_AUTOSTART
_initialize_dbus();
#endif
- g_main_loop_run(loop);
+#endif
+ g_main_loop_run(main_loop);
+#ifdef USE_GDBUS
+ if (id)
+ g_bus_unown_name(id);
+#else
#ifdef USE_AUTOSTART
_finalize_dbus();
#endif
+#endif
/* release secure element.. (pure virtual function problem..) */
ServerResource::getInstance().unloadSecureElements();
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
#AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/ SRCS)
-#SET(SRCS "${CMAKE_CURRENT_SOURCE_DIR}/test-client-async.cpp")
-SET(SRCS "${CMAKE_CURRENT_SOURCE_DIR}/test-client.cpp")
+SET(SRCS "${CMAKE_CURRENT_SOURCE_DIR}/test-client-sync.cpp")
+#SET(SRCS "${CMAKE_CURRENT_SOURCE_DIR}/test-client.cpp")
IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
SET(CMAKE_BUILD_TYPE "Release")
ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs_test_client REQUIRED glib-2.0 gthread-2.0 gobject-2.0 security-server vconf dlog)
+pkg_check_modules(pkgs_test_client REQUIRED glib-2.0 gthread-2.0 gobject-2.0 security-server vconf dlog dbus-glib-1)
FOREACH(flag ${pkgs_test_client_CFLAGS})
SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_test_client_LDFLAGS} "-L../common" "-lsmartcard-service-common" "-L../client" "-lsmartcard-service" "-pie -ldl")
-#INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
#include <stdio.h>
#include <string.h>
#include <glib.h>
+#include <dbus/dbus-glib.h>
#include "Debug.h"
#include "SEService.h"
}
};
+bool net_nfc_is_authorized_nfc_access(const char *package, uint8_t *aid, uint32_t aid_len)
+{
+ bool result = false;
+ DBusGConnection *connection;
+ GError *error = NULL;
+
+ dbus_g_thread_init();
+
+ g_type_init();
+
+ connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
+ if (error == NULL)
+ {
+ DBusGProxy *proxy;
+
+ proxy = dbus_g_proxy_new_for_name(connection, "org.tizen.smartcard_service",
+ "/org/tizen/smartcard_service", "org.tizen.smartcard_service");
+ if (proxy != NULL)
+ {
+ gint rule = 0;
+ GArray temp = { (gchar *)aid, aid_len };
+
+ if (dbus_g_proxy_call(proxy, "check_nfc_access", &error,
+ G_TYPE_STRING, package,
+ dbus_g_type_get_collection("GArray", G_TYPE_UCHAR), &temp, G_TYPE_INVALID,
+ G_TYPE_INT, rule, G_TYPE_INVALID) == false)
+ {
+ _ERR("check_nfc_access failed");
+ if (error != NULL)
+ {
+ _ERR("message : [%s]", error->message);
+ g_error_free(error);
+ }
+ }
+ else
+ {
+ _INFO("check_nfc_access returns : %d", rule);
+ result = !!rule;
+ }
+ }
+ else
+ {
+ _ERR("ERROR: Can't make dbus proxy");
+ }
+ }
+ else
+ {
+ _ERR("ERROR: Can't get on system bus [%s]", error->message);
+ g_error_free(error);
+ }
+
+ return result;
+}
+
TestEventHandler testEventHandler;
void testConnectedCallback(SEServiceHelper *service, void *userData)
{
vector<ReaderHelper *> readers;
user_context_t *context = (user_context_t *)userData;
+ uint8_t buffer[] = { 0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 };
+// uint8_t buffer[] = { 0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 };
_BEGIN();
+// net_nfc_is_authorized_nfc_access("autoutc099.SecureElementUnitTest", buffer, sizeof(buffer));
if (service != NULL)
{
_DBG("callback called, service [%p]", service);
readers = service->getReaders();
- if (readers.size() > 0)
+ size_t i;
+ for (i = 0; i < readers.size(); i++)
{
Reader *reader = NULL;
- reader = (Reader *)readers[0];
+ reader = (Reader *)readers[i];
_DBG("reader [%p]", reader);
_DBG("session [%p]", session);
ByteArray temp;
- temp = session->getATRSync();
+ try
+ {
+ temp = session->getATRSync();
+ }
+ catch (...)
+ {
+ _ERR("exception....");
+ }
_DBG("atr[%d] : %s", temp.getLength(), temp.toString());
- unsigned char MF[] = { 0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35 };
ByteArray aid;
- aid.setBuffer(MF, sizeof(MF));
- ClientChannel *channel = (ClientChannel *)session->openLogicalChannelSync(aid);
- if (channel != NULL)
+ aid.setBuffer(buffer, sizeof(buffer));
+ try
{
- _DBG("channel [%p]", channel);
- ByteArray response;
- ByteArray data, command;
- int fid = 0x00003150;
-
- response = channel->getSelectResponse();
- _INFO("response : %s", response.toString());
-
- _DBG("isBasicChannel() = %s", channel->isBasicChannel() ? "Basic" : "Logical");
- _DBG("isClosed() = %s", channel->isClosed() ? "Closed" : "Opened");
-
- data.setBuffer((unsigned char *)&fid, 2);
- command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_ID, 0, data);
- int error = channel->transmitSync(command, response);
-
- _INFO("error : %d, response : %s", error, response.toString());
-
- channel->closeSync();
+ ClientChannel *channel = (ClientChannel *)session->openLogicalChannelSync(aid);
+ if (channel != NULL)
+ {
+ _DBG("channel [%p]", channel);
+ ByteArray response;
+ ByteArray data, command;
+ int fid = 0x00003150;
+
+ response = channel->getSelectResponse();
+ _INFO("response : %s", response.toString());
+
+ _DBG("isBasicChannel() = %s", channel->isBasicChannel() ? "Basic" : "Logical");
+ _DBG("isClosed() = %s", channel->isClosed() ? "Closed" : "Opened");
+
+ data.setBuffer((unsigned char *)&fid, 2);
+ command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_ID, 0, data);
+ int error = channel->transmitSync(command, response);
+
+ _INFO("error : %d, response : %s", error, response.toString());
+
+ channel->closeSync();
+ }
+ else
+ {
+ _ERR("openLogicalChannelSync failed");
+ }
}
- else
+ catch (...)
{
- _ERR("openLogicalChannelSync failed");
+ _ERR("exception....");
}
session->closeSync();
{
_ERR("openSessionSync failed");
}
-
- service->shutdown();
- }
- else
- {
- _ERR("reader is empty");
}
+
+ ((SEService *)service)->shutdownSync();
}
else
{