Smartcard structure refactoring : capi layer 55/90055/1
authorJihoon Jung <jh8801.jung@samsung.com>
Wed, 28 Sep 2016 07:02:17 +0000 (16:02 +0900)
committerJihoon Jung <jh8801.jung@samsung.com>
Wed, 28 Sep 2016 07:04:36 +0000 (16:04 +0900)
- remove smartcard client library layer

Change-Id: Idf28232ae62c1d7f0b968448065bf9ae2b1dde5e

14 files changed:
CMakeLists.txt
include/ClientChannel.h [new file with mode: 0644]
include/ClientGDBus.h [new file with mode: 0644]
include/Reader.h [new file with mode: 0755]
include/SEService.h [new file with mode: 0644]
include/SEServiceListener.h [new file with mode: 0644]
include/Session.h [new file with mode: 0644]
include/smartcard-service.h [new file with mode: 0644]
packaging/capi-network-smartcard.spec
src/ClientChannel.cpp [new file with mode: 0644]
src/ClientGDBus.cpp [new file with mode: 0755]
src/Reader.cpp [new file with mode: 0644]
src/SEService.cpp [new file with mode: 0755]
src/Session.cpp [new file with mode: 0644]

index dc1354b..f22c146 100644 (file)
@@ -10,7 +10,7 @@ SET(service "network")
 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}")
@@ -29,10 +29,13 @@ INCLUDE(FindPkgConfig)
 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")
@@ -43,7 +46,7 @@ ENDIF(TIZEN_SMARTCARD_SUPPORT)
 
 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})
 
diff --git a/include/ClientChannel.h b/include/ClientChannel.h
new file mode 100644 (file)
index 0000000..a4e75ee
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * 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_ */
diff --git a/include/ClientGDBus.h b/include/ClientGDBus.h
new file mode 100644 (file)
index 0000000..c111874
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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_ */
diff --git a/include/Reader.h b/include/Reader.h
new file mode 100755 (executable)
index 0000000..876d0b8
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * 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_ */
diff --git a/include/SEService.h b/include/SEService.h
new file mode 100644 (file)
index 0000000..e6aa87c
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * 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_ */
diff --git a/include/SEServiceListener.h b/include/SEServiceListener.h
new file mode 100644 (file)
index 0000000..9cfc01b
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * 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_ */
diff --git a/include/Session.h b/include/Session.h
new file mode 100644 (file)
index 0000000..7d530e3
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * 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_ */
diff --git a/include/smartcard-service.h b/include/smartcard-service.h
new file mode 100644 (file)
index 0000000..354e11f
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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_ */
index 4e4c7df..2e0f2ad 100755 (executable)
@@ -1,6 +1,6 @@
 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
@@ -9,7 +9,6 @@ BuildRequires:  cmake
 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)
diff --git a/src/ClientChannel.cpp b/src/ClientChannel.cpp
new file mode 100644 (file)
index 0000000..c7e9dd4
--- /dev/null
@@ -0,0 +1,624 @@
+/*
+ * 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 */
+}
diff --git a/src/ClientGDBus.cpp b/src/ClientGDBus.cpp
new file mode 100755 (executable)
index 0000000..8a3bb8b
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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 */
diff --git a/src/Reader.cpp b/src/Reader.cpp
new file mode 100644 (file)
index 0000000..887d896
--- /dev/null
@@ -0,0 +1,370 @@
+/*
+ * 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)
+{
+}
diff --git a/src/SEService.cpp b/src/SEService.cpp
new file mode 100755 (executable)
index 0000000..d810f44
--- /dev/null
@@ -0,0 +1,756 @@
+/*
+ * 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;
+}
diff --git a/src/Session.cpp b/src/Session.cpp
new file mode 100644 (file)
index 0000000..412bc6a
--- /dev/null
@@ -0,0 +1,889 @@
+/*
+ * 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)
+{
+}
+