SET(submodule "smartcard")
# for package file
-SET(dependents "dlog glib-2.0 gio-2.0 capi-base-common smartcard-service smartcard-service-common capi-system-info")
+SET(dependents "dlog glib-2.0 gio-2.0 capi-base-common smartcard-service-common capi-system-info")
SET(pc_dependents "capi-base-common")
SET(fw_name "${project_prefix}-${service}-${submodule}")
pkg_check_modules(${fw_name} REQUIRED ${dependents})
FOREACH(flag ${${fw_name}_CFLAGS})
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
ENDFOREACH(flag)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror")
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} -fPIC -Wall -Werror")
+SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
ADD_DEFINITIONS("-DTIZEN_DEBUG")
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=${LIBDIR}")
-SET(SOURCES src/smartcard.c)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/src SOURCES)
ADD_LIBRARY(${fw_name} SHARED ${SOURCES})
--- /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 CLIENTCHANNEL_H_
+#define CLIENTCHANNEL_H_
+
+/* standard library header */
+#include <gio/gio.h>
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "Channel.h"
+#include "Session.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+namespace smartcard_service_api
+{
+ class ClientChannel: public Channel
+ {
+ private:
+ void *context;
+ void *handle;
+ void *proxy;
+
+ ClientChannel(void *context, Session *session, int channelNum,
+ const ByteArray &selectResponse, void *handle);
+ ~ClientChannel();
+
+ 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);
+
+ public:
+ int close(closeChannelCallback callback, void *userParam);
+ int transmit(const ByteArray &command,
+ transmitCallback callback, void *userParam);
+ bool selectNext(){ return false; }
+
+ void closeSync()
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorSecurity &, ErrorIllegalParameter &);
+ int transmitSync(const ByteArray &command, ByteArray &result)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &);
+
+ void *getHandle(){ return handle; }
+
+ friend class Session;
+ };
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+
+/* export C API */
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+int channel_is_basic_channel(channel_h handle, bool* is_basic_channel);
+int channel_is_closed(channel_h handle, bool* is_closed );
+int channel_get_session(channel_h handle, int *session_handle);
+int channel_close_sync(channel_h handle);
+int channel_transmit_sync(channel_h handle, unsigned char *command,
+ unsigned int cmd_len, unsigned char **response, unsigned int *resp_len);
+int channel_get_select_response(channel_h handle,
+ unsigned char **buffer, size_t* length);
+int channel_get_transmit_response(channel_h handle,
+ unsigned char **buffer, size_t* length);
+int channel_select_next(channel_h hChannel, bool *pSuccess);
+////
+
+int channel_close(channel_h handle, channel_close_cb callback, void *userParam);
+int channel_transmit(channel_h handle, unsigned char *command,
+ unsigned int length, channel_transmit_cb callback, void *userParam);
+unsigned int channel_get_select_response_length(channel_h handle);
+void channel_destroy_instance(channel_h handle) __attribute__((deprecated));
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* CLIENTCHANNEL_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 CLIENTGDBUS_H_
+#define CLIENTGDBUS_H_
+
+/* standard library header */
+#include <glib.h>
+
+/* SLP library header */
+
+/* local header */
+#include "GDBusHelper.h"
+#include "smartcard-service-gdbus.h"
+
+namespace smartcard_service_api
+{
+ class ClientGDBus
+ {
+ };
+} /* namespace smartcard_service_api */
+
+#endif /* CLIENTGDBUS_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 READER_H_
+#define READER_H_
+
+/* standard library header */
+#include <glib.h>
+#include <gio/gio.h>
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "ReaderHelper.h"
+#include "Session.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+namespace smartcard_service_api
+{
+ class Reader: public ReaderHelper
+ {
+ private:
+ void *context;
+ void *handle;
+ void *proxy;
+
+ Reader(void *context, const char *name, void *handle);
+ ~Reader();
+
+ inline void unavailable() { present = false; }
+ static void reader_open_session_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data);
+
+ public:
+ void closeSessions()
+ throw(ErrorIO &, ErrorIllegalState &);
+
+ int openSession(openSessionCallback callback, void *userData);
+ SessionHelper *openSessionSync()
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &);
+
+ void *getHandle(){ return handle; }
+
+ friend class SEService;
+ };
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+
+/* export C API */
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+int reader_get_name(reader_h handle, char** reader_name);
+int reader_is_secure_element_present(reader_h handle, bool* is_present);
+int reader_open_session_sync(reader_h handle, int *session_handle);
+int reader_close_sessions(reader_h handle);
+///
+
+int reader_open_session(reader_h handle, reader_open_session_cb callback,
+ void *userData);
+se_service_h reader_get_se_service(reader_h handle);
+__attribute__((deprecated)) void reader_destroy_instance(reader_h handle);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* READER_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 SESERVICE_H_
+#define SESERVICE_H_
+
+/* standard library header */
+#include <glib.h>
+#include <gio/gio.h>
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "SEServiceListener.h"
+#include "SEServiceHelper.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+using namespace std;
+
+namespace smartcard_service_api
+{
+ typedef void (*serviceConnected)(SEServiceHelper *service, void *context);
+
+ class SEService : public SEServiceHelper
+ {
+ private:
+ unsigned int handle;
+ void *context;
+ serviceConnected handler;
+ SEServiceListener *listener;
+
+ se_service_event_cb event_handler;
+ void *event_handler_context;
+
+ void *proxy;
+ const char *version;
+
+ SEService();
+
+ void addReader(unsigned int handle, const char *name);
+ bool parseReaderInformation(unsigned int count, const ByteArray &data);
+ bool parseReaderInformation(GVariant *variant);
+
+ bool _initialize()
+ throw(ErrorIO &);
+ bool initialize(void *context, serviceConnected handler)
+ throw(ErrorIO &, ErrorIllegalParameter &);
+ bool initialize(void *context, SEServiceListener *listener)
+ throw(ErrorIO &, ErrorIllegalParameter &);
+ int _initialize_sync()
+ throw(ErrorIO &, ExceptionBase &);
+ int _initialize_sync_do_not_throw_exception();
+ bool initializeSync(void *context)
+ throw(ErrorIO &, ErrorIllegalParameter &, ExceptionBase &);
+
+ 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);
+
+ public:
+ SEService(void *user_data, serviceConnected handler)
+ throw(ErrorIO &, ErrorIllegalParameter &);
+ SEService(void *user_data, SEServiceListener *listener)
+ throw(ErrorIO &, ErrorIllegalParameter &);
+ SEService(void *user_data)
+ throw(ErrorIO &, ErrorIllegalParameter &, ExceptionBase &);
+ ~SEService();
+
+ static SEService *createInstance(void *user_data, SEServiceListener *listener)
+ throw(ErrorIO &, ErrorIllegalParameter &);
+ static SEService *createInstance(void *user_data, serviceConnected handler)
+ throw(ErrorIO &, ErrorIllegalParameter &);
+
+ void setEventHandler(se_service_event_cb cb, void *context);
+ void shutdown();
+ void shutdownSync();
+ const char *getVersion() const { return version; }
+ };
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+
+/* export C API */
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+se_service_h se_service_create_instance(void *user_data,
+ se_service_connected_cb callback);
+se_service_h se_service_create_instance_with_event_callback(void *user_data,
+ se_service_connected_cb connected, se_service_event_cb event,
+ se_sesrvice_error_cb error);
+
+se_service_h se_service_create_instance_sync(void *user_data, int* result);
+int se_service_get_version(se_service_h handle, char **version_str);
+int se_service_get_readers_count(se_service_h handle);
+int se_service_get_readers(se_service_h handle, int **readers, int *count);
+
+bool se_service_is_connected(se_service_h handle);
+void se_service_shutdown(se_service_h handle);
+
+void se_service_set_event_handler(se_service_h handle, se_service_event_cb event_handler, void *user_data);
+void se_service_unset_event_handler(se_service_h handle);
+
+int se_service_destroy_instance(se_service_h handle);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SESERVICE_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 SESERVICELISTENER_H_
+#define SESERVICELISTENER_H_
+
+/* standard library header */
+
+/* SLP library header */
+
+/* local header */
+
+namespace smartcard_service_api
+{
+ class SEServiceHelper;
+
+ class SEServiceListener
+ {
+ public:
+ virtual void serviceConnected(SEServiceHelper *service,
+ void *context) = 0;
+ virtual void eventHandler(SEServiceHelper *service,
+ char *seName, int event, void *context) = 0;
+ virtual void errorHandler(SEServiceHelper *service, int error,
+ void *context) = 0;
+ };
+} /* namespace open_mobile_api */
+
+#endif /* SESERVICELISTENER_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 SESSION_H_
+#define SESSION_H_
+
+/* standard library header */
+#include <gio/gio.h>
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "SessionHelper.h"
+#endif /* __cplusplus */
+
+#ifdef __cplusplus
+namespace smartcard_service_api
+{
+ class Reader;
+
+ class Session : public SessionHelper
+ {
+ private:
+ void *context;
+ void *handle;
+ void *proxy;
+
+ Session(void *context, Reader *reader, void *handle);
+ ~Session();
+
+ int openChannel(int id, const ByteArray &aid, openChannelCallback callback, void *userData);
+
+ Channel *openChannelSync(int id, const ByteArray &aid)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &);
+
+ Channel *openChannelSync(int id, const ByteArray &aid, unsigned char P2)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &);
+
+ 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);
+
+ public:
+ void closeChannels()
+ throw(ErrorIO &, ErrorIllegalState &);
+
+ int getATR(getATRCallback callback, void *userData);
+ int close(closeSessionCallback callback, void *userData);
+
+ int openBasicChannel(const ByteArray &aid, openChannelCallback callback, void *userData);
+ int openBasicChannel(const unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData);
+ int openLogicalChannel(const ByteArray &aid, openChannelCallback callback, void *userData);
+ int openLogicalChannel(const unsigned char *aid, unsigned int length, openChannelCallback callback, void *userData);
+
+ const ByteArray getATRSync()
+ throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
+ ErrorIllegalState &, ErrorIllegalParameter &);
+
+ void closeSync()
+ throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
+ ErrorIllegalState &, ErrorIllegalParameter &);
+
+ Channel *openBasicChannelSync(const ByteArray &aid)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &);
+
+ Channel *openBasicChannelSync(const unsigned char *aid, unsigned int length)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &);
+
+ Channel *openLogicalChannelSync(const ByteArray &aid)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &);
+
+ Channel *openLogicalChannelSync(const unsigned char *aid, unsigned int length)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &);
+
+ Channel *openBasicChannelSync(const ByteArray &aid, unsigned char P2)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &);
+
+ Channel *openBasicChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &);
+
+ Channel *openLogicalChannelSync(const ByteArray &aid, unsigned char P2)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &);
+
+ Channel *openLogicalChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &);
+
+ size_t getChannelCount() const;
+ void *getHandle(){ return handle; }
+
+ friend class Reader;
+ };
+} /* namespace smartcard_service_api */
+#endif /* __cplusplus */
+
+/* export C API */
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+int session_get_reader(session_h handle, int* reader_handle);
+int session_is_closed(session_h handle, bool* is_closed);
+int session_close_channels(session_h handle);
+int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length);
+int session_close_sync(session_h handle);
+int session_open_basic_channel_sync(session_h handle, unsigned char *aid,
+ unsigned int length, unsigned char P2, int* channel_handle);
+int session_open_logical_channel_sync(session_h handle, unsigned char *aid,
+ unsigned int length, unsigned char P2, int* channel_handle);
+///
+
+int session_get_atr(session_h handle, session_get_atr_cb callback,
+ void *userData);
+int session_close(session_h handle, session_close_session_cb callback,
+ void *userData);
+int session_open_basic_channel(session_h handle, unsigned char *aid,
+ unsigned int length, session_open_channel_cb callback, void *userData);
+int session_open_logical_channel(session_h handle, unsigned char *aid,
+ unsigned int length, session_open_channel_cb callback, void *userData);
+size_t session_get_channel_count(session_h handle);
+__attribute__((deprecated)) void session_destroy_instance(session_h handle);
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SESSION_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 SMARTCARD_SERVICE_H_
+#define SMARTCARD_SERVICE_H_
+
+#include "smartcard-types.h"
+#ifdef __cplusplus
+#include "Exception.h"
+#endif
+#include "SEService.h"
+#include "Reader.h"
+#include "Session.h"
+#include "ClientChannel.h"
+
+#endif /* SMARTCARD_SERVICE_H_ */
Name: capi-network-smartcard
Summary: A Smartcard library in Native API
-Version: 0.0.7
+Version: 0.0.8
Release: 1
Group: Network & Connectivity/Smartcard
License: Apache-2.0
BuildRequires: pkgconfig(dlog)
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(gobject-2.0)
-BuildRequires: pkgconfig(smartcard-service)
BuildRequires: pkgconfig(smartcard-service-common)
BuildRequires: pkgconfig(capi-base-common)
BuildRequires: pkgconfig(capi-system-info)
--- /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.
+ */
+
+/* standard library header */
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <glib.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "ClientChannel.h"
+#include "ReaderHelper.h"
+#include "APDUHelper.h"
+#include "ClientGDBus.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+ ClientChannel::ClientChannel(void *context, Session *session,
+ int channelNum, const ByteArray &selectResponse, void *handle)
+ : Channel(session)
+ {
+ this->channelNum = -1;
+ this->handle = NULL;
+ this->context = NULL;
+
+ if (handle == NULL)
+ {
+ _ERR("ClientIPC::getInstance() failed");
+
+ return;
+ }
+
+ this->channelNum = channelNum;
+ this->handle = handle;
+ this->selectResponse = selectResponse;
+ this->context = context;
+
+ /* init default context */
+ GError *error = NULL;
+
+ proxy = smartcard_service_channel_proxy_new_for_bus_sync(
+ G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE,
+ "org.tizen.SmartcardService",
+ "/org/tizen/SmartcardService/Channel",
+ NULL, &error);
+ if (proxy == NULL)
+ {
+ _ERR("Can not create proxy : %s", error->message);
+ g_error_free(error);
+ return;
+ }
+ }
+
+ ClientChannel::~ClientChannel()
+ {
+ closeSync();
+ }
+
+ void ClientChannel::channel_transmit_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+ {
+ CallbackParam *param = (CallbackParam *)user_data;
+ transmitCallback callback;
+ gint result;
+ GVariant *var_response;
+ GError *error = NULL;
+ ByteArray response;
+
+ _INFO("MSG_REQUEST_TRANSMIT");
+
+ if (param == NULL) {
+ _ERR("null parameter!!!");
+ return;
+ }
+
+ callback = (transmitCallback)param->callback;
+
+ if (smartcard_service_channel_call_transmit_finish(
+ SMARTCARD_SERVICE_CHANNEL(source_object),
+ &result, &var_response, res, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ GDBusHelper::convertVariantToByteArray(var_response, response);
+ } else {
+ _ERR("smartcard_service_channel_call_transmit failed, [%d]", result);
+ }
+ } else {
+ _ERR("smartcard_service_channel_call_transmit failed, [%s]", error->message);
+ g_error_free(error);
+
+ result = SCARD_ERROR_IPC_FAILED;
+ }
+
+ if (callback != NULL) {
+ callback(response.getBuffer(),
+ response.size(),
+ result, param->user_param);
+ }
+
+ delete param;
+ }
+
+ void ClientChannel::channel_close_cb(GObject *source_object,
+ GAsyncResult *res, gpointer user_data)
+ {
+ CallbackParam *param = (CallbackParam *)user_data;
+ ClientChannel *channel;
+ closeChannelCallback callback;
+ gint result;
+ GError *error = NULL;
+
+ _INFO("MSG_REQUEST_CLOSE_CHANNEL");
+
+ if (param == NULL) {
+ _ERR("null parameter!!!");
+ return;
+ }
+
+ channel = (ClientChannel *)param->instance;
+ callback = (closeChannelCallback)param->callback;
+
+ if (smartcard_service_channel_call_close_channel_finish(
+ SMARTCARD_SERVICE_CHANNEL(source_object),
+ &result, res, &error) == true) {
+ if (result == SCARD_ERROR_OK) {
+ channel->channelNum = -1;
+ } else {
+ _ERR("smartcard_service_channel_call_close_channel failed, [%d]", result);
+ }
+ } else {
+ _ERR("smartcard_service_channel_call_close_channel failed, [%s]", error->message);
+ g_error_free(error);
+
+ result = SCARD_ERROR_IPC_FAILED;
+ }
+
+ if (callback != NULL) {
+ callback(result, param->user_param);
+ }
+
+ delete param;
+ }
+
+ void ClientChannel::closeSync()
+ throw(ExceptionBase &, ErrorIO &, ErrorSecurity &,
+ ErrorIllegalState &, ErrorIllegalParameter &)
+ {
+ if (isClosed() == false)
+ {
+ if (getSession()->getReader()->isSecureElementPresent() == true)
+ {
+ 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) {
+ channelNum = -1;
+ } else {
+ _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
+ {
+ _INFO("unavailable channel");
+ }
+ }
+ }
+
+ int ClientChannel::close(closeChannelCallback callback, void *userParam)
+ {
+ int result = SCARD_ERROR_OK;
+
+ if (isClosed() == false)
+ {
+ if (getSession()->getReader()->isSecureElementPresent() == true)
+ {
+ 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
+ {
+ _ERR("unavailable channel");
+ result = SCARD_ERROR_ILLEGAL_STATE;
+ }
+ }
+
+ return result;
+ }
+
+ int ClientChannel::transmitSync(const ByteArray &command, ByteArray &result)
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
+ {
+ int rv = SCARD_ERROR_OK;
+
+ if (getSession()->getReader()->isSecureElementPresent() == true)
+ {
+ 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, transmitResponse);
+ result = transmitResponse;
+ } else {
+ _ERR("smartcard_service_session_call_transmit failed, [%d]", rv);
+ THROW_ERROR(rv);
+ }
+ } else {
+ _ERR("smartcard_service_session_call_transmit failed, [%s]", error->message);
+ g_error_free(error);
+
+ throw ErrorIO(SCARD_ERROR_IPC_FAILED);
+ }
+ }
+ else
+ {
+ _ERR("unavailable channel");
+ throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
+ }
+
+ return rv;
+ }
+
+ int ClientChannel::transmit(const ByteArray &command, transmitCallback callback, void *userParam)
+ {
+ int result;
+
+ if (getSession()->getReader()->isSecureElementPresent() == true)
+ {
+ 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_transmit_cb, param);
+
+ result = SCARD_ERROR_OK;
+ }
+ else
+ {
+ _ERR("unavailable channel");
+ result = SCARD_ERROR_ILLEGAL_STATE;
+ }
+
+ return result;
+ }
+} /* namespace smartcard_service_api */
+
+/* export C API */
+#define CHANNEL_EXTERN_BEGIN \
+ if (handle != NULL) \
+ { \
+ ClientChannel *channel = (ClientChannel *)handle;
+
+#define CHANNEL_EXTERN_END \
+ } \
+ else \
+ { \
+ _ERR("Invalid param"); \
+ }
+
+using namespace smartcard_service_api;
+
+EXTERN_API int channel_close_sync(channel_h handle)
+{
+ int result = SCARD_ERROR_OK;
+
+ CHANNEL_EXTERN_BEGIN;
+
+ try
+ {
+ channel->closeSync();
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int channel_transmit_sync(channel_h handle, unsigned char *command,
+ unsigned int cmd_len, unsigned char **response, unsigned int *resp_len)
+{
+ int result = SCARD_ERROR_OK;
+
+ if (command == NULL || cmd_len == 0 || response == NULL || resp_len == NULL)
+ return SCARD_ERROR_UNKNOWN;
+
+ CHANNEL_EXTERN_BEGIN;
+
+ try
+ {
+ ByteArray temp, resp;
+
+ temp.assign(command, cmd_len);
+ channel->transmitSync(temp, resp);
+
+ if (resp.size() > 0)
+ {
+ *response = (unsigned char *)calloc(resp.size(), sizeof(unsigned char));
+ *resp_len = resp.size();
+ memcpy(*response, resp.getBuffer(), *resp_len);
+ }
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ *resp_len = 0;
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ *resp_len = 0;
+ }
+
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int channel_is_basic_channel(channel_h handle, bool* is_basic_channel)
+{
+ int result = SCARD_ERROR_OK;
+
+ CHANNEL_EXTERN_BEGIN;
+
+ try
+ {
+ *is_basic_channel = channel->isBasicChannel();
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int channel_is_closed(channel_h handle, bool* is_closed)
+{
+ int result = SCARD_ERROR_OK;
+
+ CHANNEL_EXTERN_BEGIN;
+
+ try
+ {
+ *is_closed = channel->isClosed();
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int channel_get_select_response(channel_h handle,
+ unsigned char **buffer, size_t *length)
+{
+ int result = SCARD_ERROR_OK;
+
+ CHANNEL_EXTERN_BEGIN;
+
+ try
+ {
+ ByteArray response = channel->getSelectResponse();
+ uint8_t* get_buffer = response.getBuffer();
+
+ *length = response.size();
+
+ if (*length > 0)
+ {
+ *buffer = (unsigned char *)calloc(*length, sizeof(unsigned char));
+ if(*buffer == NULL || get_buffer == NULL)
+ {
+ *length = 0;
+ return SCARD_ERROR_NOT_ENOUGH_RESOURCE;
+ }
+
+ memcpy(*buffer, get_buffer, *length);
+ }
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ *length = 0;
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ *length = 0;
+ }
+
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int channel_get_transmit_response(channel_h handle,
+ unsigned char **buffer, size_t *length)
+{
+ int result = SCARD_ERROR_OK;
+
+ CHANNEL_EXTERN_BEGIN;
+
+ try
+ {
+ ByteArray response;
+
+ response = channel->getTransmitResponse();
+
+ *length = response.size();
+
+ if (*length > 0)
+ {
+ *buffer = (unsigned char *)calloc(*length, sizeof(unsigned char));
+ memcpy(*buffer, response.getBuffer(), *length);
+ }
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ *length = 0;
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ *length = 0;
+ }
+
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int channel_get_session(channel_h handle, int *session_handle)
+{
+ int result = SCARD_ERROR_OK;
+ session_h session = NULL;
+
+ CHANNEL_EXTERN_BEGIN;
+
+ try
+ {
+ session = channel->getSession();
+ *session_handle = (long)session;
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int channel_select_next(channel_h handle, bool *pSuccess)
+{
+ int result = SCARD_ERROR_OK;
+
+ CHANNEL_EXTERN_BEGIN;
+
+ try
+ {
+ *pSuccess = channel->selectNext();
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API unsigned int channel_get_select_response_length(channel_h handle)
+{
+ unsigned int result = 0;
+
+ CHANNEL_EXTERN_BEGIN;
+ result = channel->getSelectResponse().size();
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int channel_close(channel_h handle, channel_close_cb callback, void *userParam)
+{
+ int result = -1;
+
+ CHANNEL_EXTERN_BEGIN;
+ result = channel->close((closeChannelCallback)callback, userParam);
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int channel_transmit(channel_h handle, unsigned char *command,
+ unsigned int length, channel_transmit_cb callback, void *userParam)
+{
+ int result = -1;
+
+ CHANNEL_EXTERN_BEGIN;
+ ByteArray temp;
+
+ temp.assign(command, length);
+ result = channel->transmit(temp, (transmitCallback)callback, userParam);
+ CHANNEL_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API void channel_destroy_instance(channel_h handle)
+{
+ /* do nothing */
+}
--- /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.
+ */
+
+/* standard library header */
+#include <glib.h>
+
+/* SLP library header */
+
+/* local header */
+#include "smartcard-types.h"
+#include "Debug.h"
+#include "ByteArray.h"
+#include "ClientGDBus.h"
+
+using namespace std;
+
+/* below functions will be called when dlopen or dlclose is called */
+void __attribute__ ((constructor)) lib_init()
+{
+ /* remove for deprecated-declarations build warning: glib ver > 2.36 */
+#if !GLIB_CHECK_VERSION (2, 35, 0)
+ g_type_init();
+#endif
+}
+
+void __attribute__ ((destructor)) lib_fini()
+{
+}
+
+namespace smartcard_service_api
+{
+} /* namespace smartcard_service_api */
--- /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.
+ */
+
+/* standard library header */
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "Reader.h"
+#include "Session.h"
+#include "ClientGDBus.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+ Reader::Reader(void *context, const char *name, void *handle) :
+ ReaderHelper(name), context(context), handle(handle)
+ {
+ _BEGIN();
+
+ if (context == NULL || handle == NULL)
+ {
+ _ERR("invalid param");
+
+ return;
+ }
+
+ /* 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;
+ }
+
+ present = true;
+
+ _END();
+ }
+
+ Reader::~Reader()
+ {
+ size_t i;
+
+ closeSessions();
+
+ for (i = 0; i < sessions.size(); i++)
+ {
+ delete (Session *)sessions[i];
+ }
+
+ sessions.clear();
+ }
+
+ void Reader::closeSessions()
+ throw(ErrorIO &, ErrorIllegalState &)
+ {
+ size_t i;
+
+ for (i = 0; i < sessions.size(); i++)
+ {
+ sessions[i]->closeSync();
+ }
+ }
+
+ SessionHelper *Reader::openSessionSync()
+ throw(ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
+ {
+ Session *session = NULL;
+
+ if (isSecureElementPresent() == true)
+ {
+ 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
+ {
+ _ERR("unavailable reader");
+ throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
+ }
+
+ return session;
+ }
+
+ 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;
+ }
+ int Reader::openSession(openSessionCallback callback, void *userData)
+ {
+ int result;
+
+ _BEGIN();
+
+ if (isSecureElementPresent() == true)
+ {
+ 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
+ {
+ _ERR("unavailable reader");
+ result = SCARD_ERROR_ILLEGAL_STATE;
+ }
+
+ _END();
+
+ return result;
+ }
+} /* namespace smartcard_service_api */
+
+/* export C API */
+#define READER_EXTERN_BEGIN \
+ if (handle != NULL) \
+ { \
+ Reader *reader = (Reader *)handle;
+
+#define READER_EXTERN_END \
+ } \
+ else \
+ { \
+ _ERR("Invalid param"); \
+ }
+
+using namespace smartcard_service_api;
+
+EXTERN_API int reader_get_name(reader_h handle, char** reader_name)
+{
+ int result = SCARD_ERROR_OK;
+
+ READER_EXTERN_BEGIN;
+
+ try
+ {
+ *reader_name = g_strdup(reader->getName());
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
+ READER_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int reader_is_secure_element_present(reader_h handle, bool* is_present)
+{
+ int result = SCARD_ERROR_OK;
+
+ READER_EXTERN_BEGIN;
+
+ try
+ {
+ *is_present = reader->isSecureElementPresent();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
+ READER_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int reader_open_session_sync(reader_h handle, int *session_handle)
+{
+ session_h session;
+ int result = SCARD_ERROR_OK;
+
+ READER_EXTERN_BEGIN;
+
+ try
+ {
+ session = (session_h)reader->openSessionSync();
+ *session_handle = (long)session;
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ *session_handle = 0;
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ *session_handle = 0;
+ }
+
+ READER_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int reader_close_sessions(reader_h handle)
+{
+ int result = SCARD_ERROR_OK;
+
+ READER_EXTERN_BEGIN;
+
+ try
+ {
+ reader->closeSessions();
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
+ READER_EXTERN_END;
+
+ return result;
+}
+
+
+EXTERN_API se_service_h reader_get_se_service(reader_h handle)
+{
+ se_service_h service = NULL;
+
+ READER_EXTERN_BEGIN;
+ service = (se_service_h)reader->getSEService();
+ READER_EXTERN_END;
+
+ return service;
+}
+
+EXTERN_API int reader_open_session(reader_h handle, reader_open_session_cb callback, void *userData)
+{
+ int result = -1;
+
+ READER_EXTERN_BEGIN;
+ result = reader->openSession((openSessionCallback)callback, userData);
+ READER_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API void reader_destroy_instance(reader_h handle)
+{
+}
--- /dev/null
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+/* standard library header */
+#include <unistd.h>
+#include <string.h>
+#include <glib.h>
+#include <glib-object.h>
+#include <stdlib.h>
+
+/* local header */
+#include "Debug.h"
+#include "SEService.h"
+#include "ClientChannel.h"
+#include "Reader.h"
+#include "ClientGDBus.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+#define SHUTDOWN_DELAY 500000 /* us */
+#define VERSION "3.2"
+
+namespace smartcard_service_api
+{
+ SEService::SEService() : SEServiceHelper(),
+ handle(-1), context(NULL), handler(NULL), listener(NULL),
+ version(VERSION)
+ {
+ proxy = NULL;
+ }
+
+ SEService::SEService(void *user_data, serviceConnected handler)
+ throw(ErrorIO &, ErrorIllegalParameter &) :
+ SEServiceHelper(), handle(-1),
+ listener(NULL), version(VERSION)
+ {
+ initialize(user_data, handler);
+ }
+
+ SEService::SEService(void *user_data, SEServiceListener *listener)
+ throw(ErrorIO &, ErrorIllegalParameter &) :
+ SEServiceHelper(), handle(-1),
+ handler(NULL), version(VERSION)
+ {
+ initialize(user_data, listener);
+ }
+
+ SEService::SEService(void *user_data)
+ throw(ErrorIO &, ErrorIllegalParameter &, ExceptionBase &) :
+ SEServiceHelper(), handle(-1),
+ handler(NULL), version(VERSION)
+ {
+ initializeSync(user_data);
+ }
+
+ SEService::~SEService()
+ {
+ try
+ {
+ size_t i;
+
+ shutdownSync();
+
+ for (i = 0; i < readers.size(); i++)
+ {
+ delete (Reader *)readers[i];
+ }
+
+ readers.clear();
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("EXCEPTION : %s", e.what());
+ }
+ catch (...)
+ {
+ _ERR("EXCEPTION!!!");
+ }
+ }
+
+ SEService *SEService::createInstance(void *user_data,
+ SEServiceListener *listener)
+ throw(ErrorIO &, ErrorIllegalParameter &)
+ {
+ return new SEService(user_data, listener);
+ }
+
+ SEService *SEService::createInstance(void *user_data,
+ serviceConnected handler)
+ throw(ErrorIO &, ErrorIllegalParameter &)
+ {
+ return new SEService(user_data, handler);
+ }
+
+ 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 if (service->event_handler != NULL)
+ {
+ service->event_handler(reader_id, 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 if (service->event_handler != NULL)
+ {
+ service->event_handler(reader_id, 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);
+ }
+ }
+ }
+
+ void SEService::shutdown()
+ {
+ shutdownSync();
+ }
+
+ void SEService::shutdownSync()
+ {
+ if (connected == true)
+ {
+ uint32_t i;
+
+ for (i = 0; i < readers.size(); i++)
+ {
+ readers[i]->closeSessions();
+ }
+
+ 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);
+ }
+
+ /* wait at least 500ms */
+ usleep(SHUTDOWN_DELAY);
+
+ connected = false;
+ }
+ }
+
+ bool SEService::_initialize() throw(ErrorIO &)
+ {
+ bool result = false;
+
+ _BEGIN();
+
+ /* 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);
+
+ _END();
+
+ return result;
+ }
+
+ int SEService::_initialize_sync_do_not_throw_exception()
+ {
+ gint result;
+ guint handle;
+ GError *error = NULL;
+ GVariant *readers = NULL;
+ SEService *service = (SEService *)this;
+
+ _BEGIN();
+
+ /* init default context */
+
+ 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 */
+ if(smartcard_service_se_service_call_se_service_sync(
+ (SmartcardServiceSeService *)proxy, &result, &handle, &readers, NULL, &error) == true)
+ {
+ if (result == SCARD_ERROR_OK)
+ {
+ service->connected = true;
+ service->handle = handle;
+ service->parseReaderInformation(readers);
+ }
+ else
+ {
+ _ERR("Initialize error : %d", result);
+ }
+ }
+
+ 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);
+ }
+ }
+
+ _END();
+
+ return result;
+ }
+
+ int SEService::_initialize_sync() throw(ErrorIO &, ExceptionBase &)
+ {
+ gint result;
+ guint handle;
+ GError *error = NULL;
+ GVariant *readers = NULL;
+ SEService *service = (SEService *)this;
+
+ _BEGIN();
+
+ /* init default context */
+
+ 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 */
+ if(smartcard_service_se_service_call_se_service_sync(
+ (SmartcardServiceSeService *)proxy, &result, &handle, &readers, NULL, &error) == true)
+ {
+ if (result == SCARD_ERROR_OK)
+ {
+ service->connected = true;
+ service->handle = handle;
+ service->parseReaderInformation(readers);
+ }
+ else
+ {
+ throw ExceptionBase(result);
+ }
+ }
+ else
+ {
+ _ERR("smartcard_service_se_service_call_se_service failed, [%s]", error->message);
+ g_error_free(error);
+
+ result = SCARD_ERROR_IPC_FAILED;
+ }
+
+ _END();
+
+ return result;
+ }
+
+ bool SEService::initialize(void *context, serviceConnected handler)
+ throw(ErrorIO &, ErrorIllegalParameter &)
+ {
+ if (context == NULL)
+ {
+ throw ErrorIllegalParameter(SCARD_ERROR_ILLEGAL_PARAM);
+ }
+
+ this->context = context;
+ this->handler = handler;
+
+ return _initialize();
+ }
+
+ bool SEService::initialize(void *context, SEServiceListener *listener)
+ throw(ErrorIO &, ErrorIllegalParameter &)
+ {
+ if (context == NULL)
+ {
+ throw ErrorIllegalParameter(SCARD_ERROR_ILLEGAL_PARAM);
+ }
+
+ this->context = context;
+ this->listener = listener;
+
+ return _initialize_sync_do_not_throw_exception();
+ }
+
+ bool SEService::initializeSync(void *context)
+ throw(ErrorIO &, ErrorIllegalParameter &, ExceptionBase &)
+ {
+ this->context = context;
+
+ _initialize_sync();
+ return true;
+ }
+
+ void SEService::setEventHandler(se_service_event_cb cb, void *context)
+ {
+ this->event_handler = cb;
+ this->event_handler_context = context;
+ }
+
+ bool SEService::parseReaderInformation(GVariant *variant)
+ {
+ Reader *reader = NULL;
+
+ GVariantIter *iter;
+ guint handle;
+ gchar *name;
+
+ g_variant_get(variant, "a(us)", &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;
+ }
+
+ bool SEService::parseReaderInformation(unsigned int count,
+ const ByteArray &data)
+ {
+ size_t i;
+ unsigned int offset = 0;
+ unsigned int len = 0;
+ void *handle = NULL;
+ Reader *reader = NULL;
+ char name[100];
+ const uint8_t *buffer = NULL;
+
+
+ for (i = 0; i < count && offset < data.size(); i++)
+ {
+ memset(name, 0, sizeof(name));
+
+ buffer = data.getBuffer(offset);
+ if(buffer == NULL)
+ continue;
+
+ memcpy(&len, buffer, sizeof(len));
+ offset += sizeof(len);
+
+ buffer = data.getBuffer(offset);
+ if(buffer == NULL)
+ return false;
+
+ memcpy(name, buffer, len);
+ offset += len;
+
+ buffer = data.getBuffer(offset);
+ if(buffer == NULL)
+ return false;
+
+ memcpy(&handle, buffer, sizeof(handle));
+ offset += sizeof(handle);
+
+ SECURE_LOGD("Reader [%d] : name [%s], handle [%p]", i, name, handle);
+
+ /* add readers */
+ reader = new Reader(context, name, handle);
+ if (reader == NULL)
+ {
+ _ERR("alloc failed");
+ continue;
+ }
+
+ readers.push_back(reader);
+ }
+
+ return true;
+ }
+} /* namespace smartcard_service_api */
+
+/* export C API */
+#define SE_SERVICE_EXTERN_BEGIN \
+ if (handle != NULL) \
+ { \
+ SEService *service = (SEService *)handle;
+
+#define SE_SERVICE_EXTERN_END \
+ } \
+ else \
+ { \
+ _ERR("Invalid param"); \
+ }
+
+using namespace smartcard_service_api;
+
+EXTERN_API se_service_h se_service_create_instance(void *user_data,
+ se_service_connected_cb callback)
+{
+ SEService *service;
+
+ try
+ {
+ service = new SEService(user_data, (serviceConnected)callback);
+ }
+ catch (...)
+ {
+ service = NULL;
+ }
+
+ return (se_service_h)service;
+}
+
+EXTERN_API se_service_h se_service_create_instance_with_event_callback(
+ void *user_data, se_service_connected_cb connected,
+ se_service_event_cb event, se_sesrvice_error_cb error)
+{
+ SEService *service;
+
+ try
+ {
+ service = new SEService(user_data, (serviceConnected)connected);
+ }
+ catch (...)
+ {
+ service = NULL;
+ }
+
+ return (se_service_h)service;
+}
+
+EXTERN_API se_service_h se_service_create_instance_sync(void *user_data,
+ int *result)
+{
+ SEService *service;
+
+ try
+ {
+ service = new SEService(user_data);
+ }
+ catch (ExceptionBase &e)
+ {
+ *result = e.getErrorCode();
+ service = NULL;
+ }
+ catch (...)
+ {
+ *result = SCARD_ERROR_UNKNOWN;
+ service = NULL;
+ }
+
+ return (se_service_h)service;
+}
+
+EXTERN_API int se_service_get_version(se_service_h handle, char **version_str)
+{
+ int ret = 0;
+
+ SE_SERVICE_EXTERN_BEGIN;
+
+ *version_str = g_strdup(service->getVersion());
+
+ SE_SERVICE_EXTERN_END;
+
+ return ret;
+}
+
+EXTERN_API int se_service_get_readers_count(se_service_h handle)
+{
+ int count = 0;
+
+ SE_SERVICE_EXTERN_BEGIN;
+
+ vector<ReaderHelper *> temp_readers;
+
+ temp_readers = service->getReaders();
+ count = temp_readers.size();
+
+ SE_SERVICE_EXTERN_END;
+
+ return count;
+}
+
+EXTERN_API int se_service_get_readers(se_service_h handle, int **readers, int *count)
+{
+ int result = 0;
+
+ SE_SERVICE_EXTERN_BEGIN;
+
+ vector<ReaderHelper *> temp_readers;
+ size_t i;
+ int temp = 0;
+
+ temp_readers = service->getReaders();
+ if(temp_readers.size() > 0)
+ {
+ *readers = (int *)calloc(temp_readers.size(), sizeof(int));
+
+ if(*readers == NULL)
+ {
+ *count = 0;
+ return SCARD_ERROR_NOT_ENOUGH_RESOURCE;
+ }
+
+ for (i = 0; i < temp_readers.size(); i++)
+ {
+ if (temp_readers[i]->isSecureElementPresent())
+ {
+ (*readers)[i] = (long)temp_readers[i];
+ temp++;
+ }
+ }
+ *count = temp;
+ }
+ else
+ {
+ *count = 0;
+ }
+
+ SE_SERVICE_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API bool se_service_is_connected(se_service_h handle)
+{
+ bool result = false;
+
+ SE_SERVICE_EXTERN_BEGIN;
+
+ result = service->isConnected();
+
+ SE_SERVICE_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API void se_service_shutdown(se_service_h handle)
+{
+ SE_SERVICE_EXTERN_BEGIN;
+
+ service->shutdownSync();
+
+ SE_SERVICE_EXTERN_END;
+}
+
+EXTERN_API void se_service_set_event_handler(se_service_h handle,
+ se_service_event_cb event_handler, void *user_data)
+{
+ SE_SERVICE_EXTERN_BEGIN;
+
+ service->setEventHandler(event_handler, user_data);
+
+ SE_SERVICE_EXTERN_END;
+}
+
+EXTERN_API void se_service_unset_event_handler(se_service_h handle)
+{
+ SE_SERVICE_EXTERN_BEGIN;
+
+ service->setEventHandler(NULL, NULL);
+
+ SE_SERVICE_EXTERN_END;
+}
+
+EXTERN_API int se_service_destroy_instance(se_service_h handle)
+{
+ int result = 0;
+
+ SE_SERVICE_EXTERN_BEGIN;
+
+ delete service;
+
+ SE_SERVICE_EXTERN_END;
+
+ return result;
+}
--- /dev/null
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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.
+ */
+
+/* standard library header */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+/* SLP library header */
+
+/* local header */
+#include "Debug.h"
+#include "Session.h"
+#include "Reader.h"
+#include "ClientChannel.h"
+#include "ClientGDBus.h"
+
+#ifndef EXTERN_API
+#define EXTERN_API __attribute__((visibility("default")))
+#endif
+
+namespace smartcard_service_api
+{
+ Session::Session(void *context, Reader *reader, void *handle) :
+ SessionHelper(reader)
+ {
+ this->context = NULL;
+
+ if (context == NULL || handle == NULL)
+ {
+ _ERR("handle is null");
+
+ return;
+ }
+
+ this->context = context;
+ this->handle = handle;
+
+ /* 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;
+ }
+
+ closed = false;
+ }
+
+ Session::~Session()
+ {
+ size_t i;
+
+ closeSync();
+
+ for (i = 0; i < channels.size(); i++)
+ {
+ delete (ClientChannel *)channels[i];
+ }
+
+ channels.clear();
+ }
+
+ void Session::closeChannels() throw (ErrorIO &, ErrorIllegalState &)
+ {
+ size_t i;
+
+ for (i = 0; i < channels.size(); i++)
+ {
+ channels[i]->closeSync();
+ }
+ }
+
+ 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.size(), 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 = SCARD_ERROR_UNKNOWN;
+ gint channel_number;
+ guint channel_id;
+ GVariant *var_response;
+ GError *error = NULL;
+ Channel *channel = NULL;
+
+ _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, &channel_number, &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;
+ }
+
+ const ByteArray Session::getATRSync()
+ throw (ExceptionBase &, ErrorIO &, ErrorSecurity &,
+ ErrorIllegalState &, ErrorIllegalParameter &)
+ {
+ ByteArray result;
+
+ if (getReader()->isSecureElementPresent() == true)
+ {
+ if (atr.isEmpty() == true)
+ {
+ 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);
+ }
+ }
+
+ result = atr;
+ }
+ else
+ {
+ _ERR("unavailable session");
+ throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
+ }
+
+ return result;
+ }
+
+ int Session::getATR(getATRCallback callback, void *userData)
+ {
+ int result;
+
+ if (getReader()->isSecureElementPresent() == true)
+ {
+ if (atr.isEmpty() == true)
+ {
+ CallbackParam *param = new CallbackParam();
+
+ param->instance = this;
+ param->callback = (void *)callback;
+ param->user_param = userData;
+
+ 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
+ {
+ result = SCARD_ERROR_OK;
+
+ /* TODO : invoke callback directly */
+ callback(atr.getBuffer(),
+ atr.size(), 0, userData);
+ }
+ }
+ else
+ {
+ _ERR("unavailable session");
+ result = SCARD_ERROR_ILLEGAL_STATE;
+ }
+
+ return result;
+ }
+
+ void Session::closeSync()
+ throw (ExceptionBase &, ErrorIO &, ErrorSecurity &,
+ ErrorIllegalState &, ErrorIllegalParameter &)
+ {
+ if (isClosed() == false)
+ {
+ closed = true;
+ closeChannels();
+
+ 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);
+ }
+ }
+ }
+
+ int Session::close(closeSessionCallback callback, void *userData)
+ {
+ int result = SCARD_ERROR_OK;
+
+ if (isClosed() == false)
+ {
+ closed = true;
+ closeChannels();
+
+ 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);
+ }
+
+ return result;
+ }
+
+ size_t Session::getChannelCount() const
+ {
+ size_t count = 0;
+
+ if (getReader()->isSecureElementPresent() == true)
+ {
+ count = channels.size();
+ }
+ else
+ {
+ _ERR("unavailable session");
+ throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
+ }
+
+ return count;
+ }
+ Channel *Session::openChannelSync(int id, const ByteArray &aid)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
+ {
+ return openChannelSync(id, aid, 0x00);
+ }
+
+ Channel *Session::openChannelSync(int id, const ByteArray &aid, unsigned char P2)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
+ {
+ Channel *channel = NULL;
+
+ if (getReader()->isSecureElementPresent() == true)
+ {
+ gint ret;
+ GVariant *var_aid = NULL, *var_response = NULL;
+ guint channel_id;
+ gint channel_number;
+ 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, (guint8)P2, &ret, &channel_id, &channel_number,
+ &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_number,
+ 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
+ {
+ _ERR("unavailable session");
+
+ throw ErrorIllegalState(SCARD_ERROR_UNAVAILABLE);
+ }
+
+ return (Channel *)channel;
+ }
+
+ int Session::openChannel(int id, const ByteArray &aid, openChannelCallback callback, void *userData)
+ {
+ int result;
+
+ if (getReader()->isSecureElementPresent() == true)
+ {
+ 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, 0, NULL,
+ &Session::session_open_channel_cb, param);
+
+ result = SCARD_ERROR_OK;
+ }
+ else
+ {
+ _ERR("unavailable session");
+ result = SCARD_ERROR_ILLEGAL_STATE;
+ }
+
+ return result;
+ }
+
+ Channel *Session::openBasicChannelSync(const ByteArray &aid)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
+ {
+ return openChannelSync(0, aid, 0x00);
+ }
+
+ Channel *Session::openBasicChannelSync(const ByteArray &aid, unsigned char P2)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
+ {
+ return openChannelSync(0, aid, P2);
+ }
+
+ Channel *Session::openBasicChannelSync(const unsigned char *aid, unsigned int length)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
+ {
+ ByteArray temp(aid, length);
+
+ return openBasicChannelSync(temp, 0x00);
+ }
+
+ Channel *Session::openBasicChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
+ {
+ ByteArray temp(aid, length);
+
+ return openBasicChannelSync(temp, P2);
+ }
+
+ int Session::openBasicChannel(const ByteArray &aid, openChannelCallback callback, void *userData)
+ {
+ return openChannel(0, aid, callback, userData);
+ }
+
+ int Session::openBasicChannel(const unsigned char *aid, unsigned int length,
+ openChannelCallback callback, void *userData)
+ {
+ ByteArray temp(aid, length);
+
+ return openBasicChannel(temp, callback, userData);
+ }
+
+ Channel *Session::openLogicalChannelSync(const ByteArray &aid)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
+ {
+ return openChannelSync(1, aid, 0x00);
+ }
+
+ Channel *Session::openLogicalChannelSync(const ByteArray &aid, unsigned char P2)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
+ {
+ return openChannelSync(1, aid, P2);
+ }
+
+ Channel *Session::openLogicalChannelSync(const unsigned char *aid, unsigned int length)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
+ {
+ ByteArray temp(aid, length);
+
+ return openLogicalChannelSync(temp, 0x00);
+ }
+
+ Channel *Session::openLogicalChannelSync(const unsigned char *aid, unsigned int length, unsigned char P2)
+ throw (ExceptionBase &, ErrorIO &, ErrorIllegalState &,
+ ErrorIllegalParameter &, ErrorSecurity &)
+ {
+ ByteArray temp(aid, length);
+
+ return openLogicalChannelSync(temp, P2);
+ }
+
+ int Session::openLogicalChannel(const ByteArray &aid, openChannelCallback callback, void *userData)
+ {
+ return openChannel(1, aid, callback, userData);
+ }
+
+ int Session::openLogicalChannel(const unsigned char *aid, unsigned int length,
+ openChannelCallback callback, void *userData)
+ {
+ ByteArray temp(aid, length);
+
+ return openLogicalChannel(temp, callback, userData);
+ }
+} /* namespace smartcard_service_api */
+
+/* export C API */
+#define SESSION_EXTERN_BEGIN \
+ if (handle != NULL) \
+ { \
+ Session *session = (Session *)handle;
+
+#define SESSION_EXTERN_END \
+ } \
+ else \
+ { \
+ _ERR("Invalid param"); \
+ }
+
+using namespace smartcard_service_api;
+
+EXTERN_API int session_get_reader(session_h handle, int* reader_handle)
+{
+ int result = SCARD_ERROR_OK;
+ reader_h reader = NULL;
+
+ SESSION_EXTERN_BEGIN;
+
+ try
+ {
+ reader = session->getReader();
+ *reader_handle = (long)reader;
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ *reader_handle = 0;
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ *reader_handle = 0;
+ }
+
+ SESSION_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int session_is_closed(session_h handle, bool* is_closed)
+{
+ int result = SCARD_ERROR_OK;
+
+ SESSION_EXTERN_BEGIN;
+
+ try
+ {
+ *is_closed = session->isClosed();
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
+ SESSION_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int session_close_channels(session_h handle)
+{
+ int result = SCARD_ERROR_OK;
+
+ SESSION_EXTERN_BEGIN;
+
+ try
+ {
+ session->closeChannels();
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
+ SESSION_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int session_get_atr_sync(session_h handle, unsigned char **buffer, unsigned int *length)
+{
+ ByteArray temp;
+ int result = SCARD_ERROR_OK;
+
+ SESSION_EXTERN_BEGIN;
+
+ try
+ {
+ temp = session->getATRSync();
+
+ if (temp.size() > 0)
+ {
+ *buffer = (unsigned char *)calloc(temp.size(), sizeof(char));
+ *length = temp.size();
+
+ memcpy(*buffer, temp.getBuffer(), *length);
+ }
+ }
+ catch (ErrorIllegalState &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+
+ if(result == SCARD_ERROR_OPERATION_NOT_SUPPORTED)
+ {
+ *length = 0;
+ result = SCARD_ERROR_OK;
+ }
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ *length = 0;
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ *length = 0;
+ }
+
+ SESSION_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int session_close_sync(session_h handle)
+{
+ int result = SCARD_ERROR_OK;
+
+ SESSION_EXTERN_BEGIN;
+
+ try
+ {
+ session->closeSync();
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ }
+
+ SESSION_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int session_open_basic_channel_sync(session_h handle, unsigned char *aid,
+ unsigned int length, unsigned char P2, int* channel_handle)
+{
+ int result = SCARD_ERROR_OK;
+
+ SESSION_EXTERN_BEGIN;
+
+ try
+ {
+ *channel_handle = (long)session->openBasicChannelSync(aid, length, P2);
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ *channel_handle = 0;
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ *channel_handle = 0;
+ }
+
+ SESSION_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int session_open_logical_channel_sync(session_h handle, unsigned char *aid,
+ unsigned int length, unsigned char P2, int* channel_handle)
+{
+ int result = SCARD_ERROR_OK;
+
+ SESSION_EXTERN_BEGIN;
+
+ try
+ {
+ *channel_handle = (long)session->openLogicalChannelSync(aid, length, P2);
+ }
+ catch (ExceptionBase &e)
+ {
+ _ERR("Error occur : %s\n", e.what());
+ result = e.getErrorCode();
+ *channel_handle = 0;
+ }
+ catch (...)
+ {
+ _ERR("Error occur : unknown error\n");
+ result = SCARD_ERROR_UNKNOWN;
+ *channel_handle = 0;
+ }
+
+ SESSION_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int session_get_atr(session_h handle, session_get_atr_cb callback, void *userData)
+{
+ int result = -1;
+
+ SESSION_EXTERN_BEGIN;
+ result = session->getATR((getATRCallback)callback, userData);
+ SESSION_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int session_close(session_h handle, session_close_session_cb callback, void *userData)
+{
+ int result = -1;
+
+ SESSION_EXTERN_BEGIN;
+ result = session->close((closeSessionCallback)callback, userData);
+ SESSION_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int session_open_basic_channel(session_h handle, unsigned char *aid,
+ unsigned int length, session_open_channel_cb callback, void *userData)
+{
+ int result = -1;
+
+ SESSION_EXTERN_BEGIN;
+ result = session->openBasicChannel(aid, length, (openChannelCallback)callback, userData);
+ SESSION_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API int session_open_logical_channel(session_h handle, unsigned char *aid,
+ unsigned int length, session_open_channel_cb callback, void *userData)
+{
+ int result = -1;
+
+ SESSION_EXTERN_BEGIN;
+ result = session->openLogicalChannel(aid, length, (openChannelCallback)callback, userData);
+ SESSION_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API size_t session_get_channel_count(session_h handle)
+{
+ size_t result = 0;
+
+ SESSION_EXTERN_BEGIN;
+ result = session->getChannelCount();
+ SESSION_EXTERN_END;
+
+ return result;
+}
+
+EXTERN_API void session_destroy_instance(session_h handle)
+{
+}
+