Merge (manually) adaptors and plugin-config from tizen_2.4 repository 74/60474/2
authorJiwon Kim <jiwon177.kim@samsung.com>
Fri, 26 Feb 2016 10:58:09 +0000 (19:58 +0900)
committerJiwon Kim <jiwon177.kim@samsung.com>
Sun, 28 Feb 2016 22:56:45 +0000 (07:56 +0900)
framework/convergence/service/adaptors/*-adaptor -> adaptor/*-adaptor
framework/convergence/service/service-plugin-client -> common/plugin_config

Change-Id: I8c92e2fd7588d99100d1d40bae0768b0cfb54854
Signed-off-by: Jiwon Kim <jiwon177.kim@samsung.com>
26 files changed:
CMakeLists.txt
adaptor/CMakeLists.txt [new file with mode: 0644]
adaptor/CMakeLists.txt.backup [deleted file]
adaptor/auth-adaptor/auth-adaptor-log.h [new file with mode: 0644]
adaptor/auth-adaptor/auth-adaptor.c [new file with mode: 0644]
adaptor/auth-adaptor/auth-adaptor.h [new file with mode: 0644]
adaptor/contact-adaptor/contact-adaptor-log.h [new file with mode: 0644]
adaptor/contact-adaptor/contact-adaptor.c [new file with mode: 0644]
adaptor/contact-adaptor/contact-adaptor.h [new file with mode: 0644]
adaptor/message-adaptor/message-adaptor-log.h [new file with mode: 0644]
adaptor/message-adaptor/message-adaptor.c [new file with mode: 0644]
adaptor/message-adaptor/message-adaptor.h [new file with mode: 0644]
adaptor/push-adaptor/push-adaptor-log.h [new file with mode: 0644]
adaptor/push-adaptor/push-adaptor.c [new file with mode: 0644]
adaptor/push-adaptor/push-adaptor.h [new file with mode: 0644]
adaptor/shop-adaptor/shop-adaptor-log.h [new file with mode: 0644]
adaptor/shop-adaptor/shop-adaptor.c [new file with mode: 0644]
adaptor/shop-adaptor/shop-adaptor.h [new file with mode: 0644]
adaptor/storage-adaptor/storage-adaptor-log.h [new file with mode: 0644]
adaptor/storage-adaptor/storage-adaptor.c [new file with mode: 0644]
adaptor/storage-adaptor/storage-adaptor.h [new file with mode: 0644]
common/CMakeLists.txt [new file with mode: 0644]
common/plugin_config/libservice_plugin_log.h [new file with mode: 0644]
common/plugin_config/plugin_message.c [new file with mode: 0644]
common/plugin_config/plugin_message.h [new file with mode: 0644]
packaging/service-adaptor.spec

index 9a4e049..954ada3 100644 (file)
@@ -16,12 +16,12 @@ MESSAGE(">>> Build type: ${CMAKE_BUILD_TYPE}")
 ##########################################################
 # Define Adaptor
 ##########################################################
-#ADD_SUBDIRECTORY(adaptor)
+ADD_SUBDIRECTORY(adaptor)
 
 ##########################################################
 # Define BASE LIB
 ##########################################################
-#ADD_SUBDIRECTORY(common)
+ADD_SUBDIRECTORY(common)
 
 ##########################################################
 # Define Adaptor API
diff --git a/adaptor/CMakeLists.txt b/adaptor/CMakeLists.txt
new file mode 100644 (file)
index 0000000..7b55e8b
--- /dev/null
@@ -0,0 +1,244 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(sal-adaptor)
+
+SET(CMAKE_SKIP_BUILD_RPATH TRUE)
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+        SET(CMAKE_BUILD_TYPE "Debug")
+ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+
+MESSAGE("")
+MESSAGE(">>> current directory: ${CMAKE_CURRENT_SOURCE_DIR}")
+MESSAGE(">>> Build type: ${CMAKE_BUILD_TYPE}")
+
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${VISIBILITY} -fvisibility=hidden")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,--gc-sections")
+
+ADD_DEFINITIONS("-DSERVICE_ADAPTOR_DEBUGGING")
+ADD_DEFINITIONS("-D_SERVICE_ADAPTOR_IPC_SERVER")
+
+##########################################################
+# Define auth adaptor lib
+##########################################################
+
+SET(AUTH-LIB "auth-adaptor")
+SET(AUTH-SRCS
+        ./auth-adaptor/auth-adaptor.c
+)
+
+INCLUDE_DIRECTORIES(
+        ${CMAKE_SOURCE_DIR}/adaptor/auth-adaptor/
+        ${CMAKE_SOURCE_DIR}/common/plugin_config
+)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(auth_pkgs REQUIRED dlog glib-2.0)
+
+set(EXTRA_CFLAGS "")
+FOREACH(flag ${auth_pkgs_CFLAGS})
+        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -std=gnu99")
+
+#message(">>> extra_cflags ${EXTRA_CFLAGS}")
+#message(">>> result ${CMAKE_C_FLAGS}")
+#message(">>> ld flag ${device_pkgs_LDFLAGS}")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+
+ADD_LIBRARY(${AUTH-LIB} SHARED ${AUTH-SRCS})
+TARGET_LINK_LIBRARIES(${AUTH-LIB} ${auth_pkgs_LDFLAGS} plugin-config)
+SET_TARGET_PROPERTIES(${AUTH-LIB} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${AUTH-LIB} PROPERTIES VERSION ${VERSION})
+
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/adaptor/auth-adaptor/auth-adaptor.h DESTINATION /usr/include/)
+INSTALL(TARGETS ${AUTH-LIB} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
+
+##########################################################
+# Define contact adaptor lib
+##########################################################
+
+SET(CONTACT-LIB "contact-adaptor")
+SET(CONTACT-SRCS
+        ./contact-adaptor/contact-adaptor.c
+)
+
+INCLUDE_DIRECTORIES(
+        ${CMAKE_SOURCE_DIR}/adaptor/contact-adaptor
+)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(contact_pkgs REQUIRED dlog glib-2.0)
+
+set(EXTRA_CFLAGS "")
+FOREACH(flag ${contact_pkgs_CFLAGS})
+        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -std=gnu99")
+
+#message(">>> extra_cflags ${EXTRA_CFLAGS}")
+#message(">>> result ${CMAKE_C_FLAGS}")
+#message(">>> ld flag ${device_pkgs_LDFLAGS}")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+
+ADD_LIBRARY(${CONTACT-LIB} SHARED ${CONTACT-SRCS})
+TARGET_LINK_LIBRARIES(${CONTACT-LIB} ${contact_pkgs_LDFLAGS})
+SET_TARGET_PROPERTIES(${CONTACT-LIB} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${CONTACT-LIB} PROPERTIES VERSION ${VERSION})
+
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/adaptor/contact-adaptor/contact-adaptor.h DESTINATION /usr/include/)
+INSTALL(TARGETS ${CONTACT-LIB} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
+
+
+##########################################################
+# Define storage adaptor lib
+##########################################################
+
+SET(STORAGE-LIB "storage-adaptor")
+SET(STORAGE-SRCS
+        ./storage-adaptor/storage-adaptor.c
+)
+
+INCLUDE_DIRECTORIES(
+        ${CMAKE_SOURCE_DIR}/adaptor/storage-adaptor
+        ${CMAKE_SOURCE_DIR}/common/plugin_config
+)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(storage_pkgs REQUIRED dlog glib-2.0)
+
+set(EXTRA_CFLAGS "")
+FOREACH(flag ${storage_pkgs_CFLAGS})
+        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -std=gnu99")
+
+#message(">>> extra_cflags ${EXTRA_CFLAGS}")
+#message(">>> result ${CMAKE_C_FLAGS}")
+#message(">>> ld flag ${storage_pkgs_LDFLAGS}")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+
+ADD_LIBRARY(${STORAGE-LIB} SHARED ${STORAGE-SRCS})
+TARGET_LINK_LIBRARIES(${STORAGE-LIB} ${storage_pkgs_LDFLAGS} plugin-config)
+SET_TARGET_PROPERTIES(${STORAGE-LIB} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${STORAGE-LIB} PROPERTIES VERSION ${VERSION})
+
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/adaptor/storage-adaptor/storage-adaptor.h DESTINATION /usr/include/)
+INSTALL(TARGETS ${STORAGE-LIB} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
+
+##########################################################
+# Define message adaptor lib
+##########################################################
+
+SET(MESSAGE-LIB "message-adaptor")
+SET(MESSAGE-SRCS
+        ./message-adaptor/message-adaptor.c
+)
+
+INCLUDE_DIRECTORIES(
+        ${CMAKE_SOURCE_DIR}/adaptor/message-adaptor
+)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(message_pkgs REQUIRED dlog glib-2.0)
+
+set(EXTRA_CFLAGS "")
+FOREACH(flag ${message_pkgs_CFLAGS})
+        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -std=gnu99")
+
+#message(">>> extra_cflags ${EXTRA_CFLAGS}")
+#message(">>> result ${CMAKE_C_FLAGS}")
+#message(">>> ld flag ${resource_pkgs_LDFLAGS}")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+
+ADD_LIBRARY(${MESSAGE-LIB} SHARED ${MESSAGE-SRCS})
+TARGET_LINK_LIBRARIES(${MESSAGE-LIB} ${message_pkgs_LDFLAGS})
+SET_TARGET_PROPERTIES(${MESSAGE-LIB} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${MESSAGE-LIB} PROPERTIES VERSION ${VERSION})
+
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/adaptor/message-adaptor/message-adaptor.h DESTINATION /usr/include/)
+INSTALL(TARGETS ${MESSAGE-LIB} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
+
+##########################################################
+# Define push adaptor lib
+##########################################################
+
+SET(PUSH-LIB "push-adaptor")
+SET(PUSH-SRCS
+        ./push-adaptor/push-adaptor.c
+)
+
+INCLUDE_DIRECTORIES(
+        ${CMAKE_SOURCE_DIR}/adaptor/push-adaptor
+)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(push_pkgs REQUIRED dlog glib-2.0)
+
+set(EXTRA_CFLAGS "")
+FOREACH(flag ${push_pkgs_CFLAGS})
+        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -std=gnu99")
+
+#message(">>> extra_cflags ${EXTRA_CFLAGS}")
+#message(">>> result ${CMAKE_C_FLAGS}")
+#message(">>> ld flag ${resource_pkgs_LDFLAGS}")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+
+ADD_LIBRARY(${PUSH-LIB} SHARED ${PUSH-SRCS})
+TARGET_LINK_LIBRARIES(${PUSH-LIB} ${push_pkgs_LDFLAGS})
+SET_TARGET_PROPERTIES(${PUSH-LIB} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${PUSH-LIB} PROPERTIES VERSION ${VERSION})
+
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/adaptor/push-adaptor/push-adaptor.h DESTINATION /usr/include/)
+INSTALL(TARGETS ${PUSH-LIB} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
+
+##########################################################
+# Define shop adaptor lib
+##########################################################
+
+SET(SHOP-LIB "shop-adaptor")
+SET(SHOP-SRCS
+        ./shop-adaptor/shop-adaptor.c
+)
+
+INCLUDE_DIRECTORIES(
+        ${CMAKE_SOURCE_DIR}/adaptor/shop-adaptor
+)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(shop_pkgs REQUIRED dlog glib-2.0)
+
+set(EXTRA_CFLAGS "")
+FOREACH(flag ${shop_pkgs_CFLAGS})
+        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -std=gnu99")
+
+#message(">>> extra_cflags ${EXTRA_CFLAGS}")
+#message(">>> result ${CMAKE_C_FLAGS}")
+#message(">>> ld flag ${resource_pkgs_LDFLAGS}")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+
+ADD_LIBRARY(${SHOP-LIB} SHARED ${SHOP-SRCS})
+TARGET_LINK_LIBRARIES(${SHOP-LIB} ${shop_pkgs_LDFLAGS})
+SET_TARGET_PROPERTIES(${SHOP-LIB} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${SHOP-LIB} PROPERTIES VERSION ${VERSION})
+
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/adaptor/shop-adaptor/shop-adaptor.h DESTINATION /usr/include/)
+INSTALL(TARGETS ${SHOP-LIB} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
diff --git a/adaptor/CMakeLists.txt.backup b/adaptor/CMakeLists.txt.backup
deleted file mode 100644 (file)
index 57d751e..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-PROJECT(sal-adaptor)
-
-SET(CMAKE_SKIP_BUILD_RPATH TRUE)
-
-IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
-        SET(CMAKE_BUILD_TYPE "Debug")
-ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
-
-MESSAGE("")
-MESSAGE(">>> current directory: ${CMAKE_CURRENT_SOURCE_DIR}")
-MESSAGE(">>> Build type: ${CMAKE_BUILD_TYPE}")
-
-
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${VISIBILITY} -fvisibility=hidden")
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,--gc-sections")
-
-ADD_DEFINITIONS("-DSERVICE_ADAPTOR_DEBUGGING")
-ADD_DEFINITIONS("-D_SERVICE_ADAPTOR_IPC_SERVER")
-
-##########################################################
-# Define auth adaptor lib
-##########################################################
-
-SET(AUTH-LIB "auth-adaptor")
-SET(AUTH-SRCS
-        ./auth-adaptor/oauth1_service.c
-        ./auth-adaptor/oauth2_service.c
-        ./auth-adaptor/auth_adaptor.c
-)
-
-INCLUDE_DIRECTORIES(
-        ${CMAKE_SOURCE_DIR}/include
-        ${CMAKE_SOURCE_DIR}/client
-        ${CMAKE_SOURCE_DIR}/adaptor/auth-adaptor
-)
-
-INCLUDE(FindPkgConfig)
-pkg_check_modules(auth_pkgs REQUIRED dlog glib-2.0 capi-appfw-application)
-
-set(EXTRA_CFLAGS "")
-FOREACH(flag ${auth_pkgs_CFLAGS})
-        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -std=gnu99")
-
-#message(">>> extra_cflags ${EXTRA_CFLAGS}")
-#message(">>> result ${CMAKE_C_FLAGS}")
-#message(">>> ld flag ${device_pkgs_LDFLAGS}")
-
-SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${AUTH-LIB} SHARED ${AUTH-SRCS})
-TARGET_LINK_LIBRARIES(${AUTH-LIB} ${auth_pkgs_LDFLAGS})
-SET_TARGET_PROPERTIES(${AUTH-LIB} PROPERTIES SOVERSION ${VERSION_MAJOR})
-SET_TARGET_PROPERTIES(${AUTH-LIB} PROPERTIES VERSION ${VERSION})
-
-INSTALL(TARGETS ${AUTH-LIB} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
-
-
-##########################################################
-# Define contact adaptor lib
-##########################################################
-
-SET(CONTACT-LIB "contact-adaptor")
-SET(CONTACT-SRCS
-        ./contact-adaptor/contact_adaptor.c
-)
-
-INCLUDE_DIRECTORIES(
-        ${CMAKE_SOURCE_DIR}/include
-        ${CMAKE_SOURCE_DIR}/adaptor/contact-adaptor
-)
-
-INCLUDE(FindPkgConfig)
-pkg_check_modules(contact_pkgs REQUIRED dlog glib-2.0 capi-appfw-application)
-
-set(EXTRA_CFLAGS "")
-FOREACH(flag ${contact_pkgs_CFLAGS})
-        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -std=gnu99")
-
-#message(">>> extra_cflags ${EXTRA_CFLAGS}")
-#message(">>> result ${CMAKE_C_FLAGS}")
-#message(">>> ld flag ${device_pkgs_LDFLAGS}")
-
-SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${CONTACT-LIB} SHARED ${CONTACT-SRCS})
-TARGET_LINK_LIBRARIES(${CONTACT-LIB} ${contact_pkgs_LDFLAGS})
-SET_TARGET_PROPERTIES(${CONTACT-LIB} PROPERTIES SOVERSION ${VERSION_MAJOR})
-SET_TARGET_PROPERTIES(${CONTACT-LIB} PROPERTIES VERSION ${VERSION})
-
-INSTALL(TARGETS ${CONTACT-LIB} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
-
-
-##########################################################
-# Define storage adaptor lib
-##########################################################
-
-SET(STORAGE-LIB "storage-adaptor")
-SET(STORAGE-SRCS
-        ./storage-adaptor/storage_adaptor.c
-        ./storage-adaptor/cloud_service.c
-)
-
-INCLUDE_DIRECTORIES(
-        ${CMAKE_SOURCE_DIR}/include
-        ${CMAKE_SOURCE_DIR}/adaptor/storage-adaptor
-)
-
-INCLUDE(FindPkgConfig)
-pkg_check_modules(storage_pkgs REQUIRED dlog glib-2.0 capi-appfw-application)
-
-set(EXTRA_CFLAGS "")
-FOREACH(flag ${storage_pkgs_CFLAGS})
-        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -std=gnu99")
-
-#message(">>> extra_cflags ${EXTRA_CFLAGS}")
-#message(">>> result ${CMAKE_C_FLAGS}")
-#message(">>> ld flag ${storage_pkgs_LDFLAGS}")
-
-SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${STORAGE-LIB} SHARED ${STORAGE-SRCS})
-TARGET_LINK_LIBRARIES(${STORAGE-LIB} ${storage_pkgs_LDFLAGS})
-SET_TARGET_PROPERTIES(${STORAGE-LIB} PROPERTIES SOVERSION ${VERSION_MAJOR})
-SET_TARGET_PROPERTIES(${STORAGE-LIB} PROPERTIES VERSION ${VERSION})
-
-INSTALL(TARGETS ${STORAGE-LIB} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
-
-##########################################################
-# Define resource adaptor lib
-##########################################################
-
-SET(RESOURCE-LIB "resource-adaptor")
-SET(RESOURCE-SRCS
-        ./resource-adaptor/resource_adaptor.c
-)
-
-INCLUDE_DIRECTORIES(
-        ${CMAKE_SOURCE_DIR}/include
-        ${CMAKE_SOURCE_DIR}/adaptor/resource-adaptor
-)
-
-INCLUDE(FindPkgConfig)
-pkg_check_modules(resource_pkgs REQUIRED dlog glib-2.0 capi-appfw-application)
-
-set(EXTRA_CFLAGS "")
-FOREACH(flag ${resource_pkgs_CFLAGS})
-        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
-ENDFOREACH(flag)
-
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -std=gnu99")
-
-#message(">>> extra_cflags ${EXTRA_CFLAGS}")
-#message(">>> result ${CMAKE_C_FLAGS}")
-#message(">>> ld flag ${resource_pkgs_LDFLAGS}")
-
-SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
-
-ADD_LIBRARY(${RESOURCE-LIB} SHARED ${RESOURCE-SRCS})
-TARGET_LINK_LIBRARIES(${RESOURCE-LIB} ${resource_pkgs_LDFLAGS})
-SET_TARGET_PROPERTIES(${RESOURCE-LIB} PROPERTIES SOVERSION ${VERSION_MAJOR})
-SET_TARGET_PROPERTIES(${RESOURCE-LIB} PROPERTIES VERSION ${VERSION})
-
-INSTALL(TARGETS ${RESOURCE-LIB} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
diff --git a/adaptor/auth-adaptor/auth-adaptor-log.h b/adaptor/auth-adaptor/auth-adaptor-log.h
new file mode 100644 (file)
index 0000000..eef4d26
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+* Copyright (c) 2011 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 __AUTH_ADAPTOR_LOG_H__
+#define __AUTH_ADAPTOR_LOG_H__
+
+/**
+ *  HOW TO USE IT:
+ *  First you need to set platform logging on the device:
+ *
+ *    # dlogctrl set platformlog 1
+ *
+ *  After reboot you are able to see logs from this application, when you launch dlogutil with a proper filter e.g.:
+ *
+ *    # dlogutil AUTH_ADAPTOR:D
+ *
+ *  You may use different logging levels as: D (debug), I (info), W (warning), E (error) or F (fatal).
+ *  Higher level messages are included by default e.g. dlogutil CLOUDBOX:W prints warnings but also errors and fatal messages.
+ */
+
+#include <unistd.h>
+#include <linux/unistd.h>
+
+/* These defines must be located before #include <dlog.h> */
+#define TIZEN_ENGINEER_MODE
+// TODO: Investigate why this macro is defined somewhere else
+#ifndef TIZEN_DEBUG_ENABLE
+#define TIZEN_DEBUG_ENABLE
+#endif
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+/* Literal to filter logs from dlogutil */
+#define LOG_TAG "AUTH_ADAPTOR"
+
+#include <dlog.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+       /**
+        *  Colors of font
+        */
+#define FONT_COLOR_RESET      "\033[0m"
+#define FONT_COLOR_BLACK      "\033[30m"             /* Black */
+#define FONT_COLOR_RED        "\033[31m"             /* Red */
+#define FONT_COLOR_GREEN      "\033[32m"             /* Green */
+#define FONT_COLOR_YELLOW     "\033[33m"             /* Yellow */
+#define FONT_COLOR_BLUE       "\033[34m"             /* Blue */
+#define FONT_COLOR_PURPLE     "\033[35m"             /* Purple */
+#define FONT_COLOR_CYAN       "\033[36m"             /* Cyan */
+#define FONT_COLOR_WHITE      "\033[37m"             /* White */
+#define FONT_COLOR_BOLDBLACK  "\033[1m\033[30m"      /* Bold Black */
+#define FONT_COLOR_BOLDRED    "\033[1m\033[31m"      /* Bold Red */
+#define FONT_COLOR_BOLDGREEN  "\033[1m\033[32m"      /* Bold Green */
+#define FONT_COLOR_BOLDYELLOW "\033[1m\033[33m"      /* Bold Yellow */
+#define FONT_COLOR_BOLDBLUE   "\033[1m\033[34m"      /* Bold Blue */
+#define FONT_COLOR_BOLDPURPLE "\033[1m\033[35m"      /* Bold Purple */
+#define FONT_COLOR_BOLDCYAN   "\033[1m\033[36m"      /* Bold Cyan */
+#define FONT_COLOR_BOLDWHITE  "\033[1m\033[37m"      /* Bold White */
+
+       /**
+        *  Gets thread ID
+        */
+#define auth_adaptor_gettid() syscall(__NR_gettid)
+
+/**
+ *  @brief Macro for returning value if expression is satisfied
+ *  @param[in]  expr Expression to be checked
+ *  @param[out] val  Value to be returned when expression is true
+ */
+#define auth_adaptor_retv_if(expr, val) do { \
+            if(expr) { \
+                LOGE(FONT_COLOR_PURPLE"[%d]"FONT_COLOR_RESET, auth_adaptor_gettid());    \
+                return (val); \
+            } \
+        } while (0)
+
+/**
+ * @brief Prints debug messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define auth_adaptor_debug(fmt, arg...) do { \
+            LOGD(FONT_COLOR_GREEN"[%d]"fmt""FONT_COLOR_RESET, auth_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints info messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define auth_adaptor_info(fmt, arg...) do { \
+            LOGI(FONT_COLOR_BLUE"[%d]"fmt""FONT_COLOR_RESET, auth_adaptor_gettid() ,##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints warning messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define auth_adaptor_warning(fmt, arg...) do { \
+            LOGW(FONT_COLOR_YELLOW"[%d]"fmt""FONT_COLOR_RESET,auth_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints error messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define auth_adaptor_error(fmt, arg...) do { \
+            LOGE(FONT_COLOR_RED"[%d]"fmt""FONT_COLOR_RESET,auth_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints fatal messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define auth_adaptor_fatal(fmt, arg...) do { \
+            LOGF(FONT_COLOR_BOLDRED"[%d]"fmt""FONT_COLOR_RESET,auth_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints debug message on entry to particular function
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define auth_adaptor_debug_func(fmt, arg...) do { \
+            LOGD(FONT_COLOR_CYAN"[%d]"fmt""FONT_COLOR_RESET, auth_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+#define plugin_req_enter()                     do { \
+               auth_adaptor_info("[ENTER] plugin API call -)) -)) -)) -)) -)) -)) -)) -)) -)) -))"); \
+       } while (0)
+
+#define plugin_req_exit(ret, plugin, error)    do { \
+               auth_adaptor_info("[EXIT] plugin API called (%d) ((- ((- ((- ((- ((- ((- ((- ((- ((- ((-", (int)(ret)); \
+               if ((error)) { \
+                       if ((*error)) { \
+                               auth_adaptor_error("plugin issued error (%lld) (%s)", (long long int)((*error)->code), (char *)((*error)->msg)); \
+                               char *tem = g_strdup_printf("[PLUGIN_ERROR] URI(%s), MSG(%s)", (char *)((plugin)->handle->plugin_uri), (char *)((*error)->msg)); \
+                               if (tem) { \
+                                       free((*error)->msg); \
+                                       (*error)->msg = tem; \
+                               } \
+                       } \
+               } \
+       } while (0)
+
+#define plugin_req_exit_void()                 do { \
+               auth_adaptor_info("[EXIT] plugin API called ((- ((- ((- ((- ((- ((- ((- ((- ((- ((-"); \
+       } while (0)
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __AUTH_ADAPTOR_LOG_H__ */
diff --git a/adaptor/auth-adaptor/auth-adaptor.c b/adaptor/auth-adaptor/auth-adaptor.c
new file mode 100644 (file)
index 0000000..a70ccaf
--- /dev/null
@@ -0,0 +1,2614 @@
+/*
+* Copyright (c) 2011 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.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <glib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <plugin_message.h>
+
+#include "auth-adaptor.h"
+#include "auth-adaptor-log.h"
+
+#define PLUGIN_MESSAGE_LISTENER_CMD_APPEND_FD          "append;"
+#define PLUGIN_MESSAGE_LISTENER_CMD_STOP               "stop;"
+#define PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE           8192
+
+#define AUTH_PLUGIN_INTERFACE_CREATE_CONTEXT            "create_context"
+#define AUTH_PLUGIN_INTERFACE_DESTROY_CONTEXT           "destroy_context"
+#define AUTH_PLUGIN_INTERFACE_DESTROY_HANDLE            "destroy_handle"
+#define AUTH_PLUGIN_INTERFACE_IS_AUTH                   "is_auth"
+#define AUTH_PLUGIN_INTERFACE_JOIN                      "join"
+#define AUTH_PLUGIN_INTERFACE_LOGIN                     "login"
+#define AUTH_PLUGIN_INTERFACE_REFRESH_ACCESS_TOKEN     "refresh"
+
+
+#define IF_IS_PLUGIN_THAN_RETURN_NULL()                do {if (!g_process_identity) return NULL; } while (0)
+
+#define SAFE_ADD_STRING(x)     ((x) ? (x) : "")
+
+typedef enum {
+       PLUGIN_TYPE_INHOUSE     = 0,
+       PLUGIN_TYPE_3RD_PARTY   = 1,
+} auth_plugin_type_e;
+
+/**
+ * @brief Describes Auth adaptor plugin
+ */
+typedef struct auth_adaptor_plugin_s {
+       auth_adaptor_h                          adaptor;                /* Adaptor */
+       char                                    *path;                  /* Plugin library path */
+       auth_adaptor_plugin_handle_h            handle;                 /* Plugin handle */
+       void                                    *dl_handle;             /* Plugin library handle */
+       int                                     ref_counter;            /* Plugin reference counter */
+       GMutex                                  ref_counter_mutex;      /* Plugin reference counter mutex */
+       auth_adaptor_plugin_listener_h          plugin_listener;        /* Plugin callback listener */
+       GMutex                                  plugin_listener_mutex;  /* Plugin callback listener mutex */
+
+       GMutex                                  message_mutex;
+       auth_plugin_type_e                      type;
+       int                                     pid;
+       int                                     rd;
+       int                                     wd;
+       GList                                   *contexts;
+       GMutex                                  contexts_mutex;
+/*     GQueue                                  sended; */
+} auth_adaptor_plugin_t;
+
+typedef struct _plugin_message_context_s {
+       int hooker;
+       char *message;
+} plugin_message_context_t;
+
+/**
+ * @brief Describes Auth adaptor
+ */
+typedef struct auth_adaptor_s {
+       GMutex  auth_adaptor_mutex;             /* Adaptor mutex */
+       int     started;                        /* Started flag */
+       char    *plugins_dir;                   /* Plugins directory path */
+       GList   *plugins;                       /* List of loaded plugins */
+       GMutex  plugins_mutex;                  /* Plugin list mutex */
+       GList   *adaptor_listeners;             /* List of vservice channel listener (for now not effective) */
+       GMutex  adaptor_listeners_mutex;        /* Listener list mutex */
+
+       int     rd_cmd[2];
+       GList   *rd_list;
+       GMutex  rd_mutex;
+       pthread_t       plugin_listener;
+} auth_adaptor_t;
+
+static int g_process_identity = -1;
+
+/**
+ * @brief Creates plugin
+ */
+static auth_adaptor_plugin_h auth_adaptor_create_plugin(const char *plugin_path);
+
+/**
+ * @brief Destroys plugin and deletes all resources associated with it
+ */
+static void auth_adaptor_destroy_plugin(auth_adaptor_plugin_h plugin);
+
+/**
+ * @brief Loads plugins from selected directory
+ */
+static int auth_adaptor_load_plugins_from_directory(auth_adaptor_h adaptor,
+                                               const char *dir_path);
+
+/**
+ * @brief Checks if plugin is loaded by selected plugin adaptor
+ */
+static int auth_adaptor_has_plugin(auth_adaptor_h adaptor,
+                                               auth_adaptor_plugin_h plugin);
+
+static auth_adaptor_error_code_h auth_adaptor_create_error_code(const int64_t code,
+                                               const char *msg);
+/**
+ * Increases adaptor's plugin references counter
+ */
+static void auth_adaptor_plugin_ref(auth_adaptor_plugin_h);
+
+/**
+ * @brief Decreases adaptor's plugin references counter
+ */
+static void auth_adaptor_plugin_unref(auth_adaptor_plugin_h);
+
+/*
+void auth_adaptor_login_reply_cb(auth_adaptor_plugin_context_h context,
+                                               auth_adaptor_error_code_h error_code,
+                                               void *response)
+{
+       if (_service_adaptor_login_reply != NULL)
+               _service_adaptor_login_reply(imsi, plugin_uri, app_id, msisdn, response);
+}
+*/
+
+/* ////////////////////////////////////////////////////////////////////////////// */
+/* ////////////  Internal function prototype (for forked plugin)  /////////////// */
+/* ////////////////////////////////////////////////////////////////////////////// */
+
+
+/* To be used by adaptor */
+void *_auth_adaptor_plugin_message_collector(void *data);
+void __auth_adaptor_transfer_message(const char *msg);
+int __auth_adaptor_parse_message_cmd(auth_adaptor_h adaptor, char *msg);
+void _auth_adaptor_send_cmd_add_fd(auth_adaptor_h adaptor, int fd);
+void _auth_adaptor_send_cmd_stop_listen(auth_adaptor_h adaptor);
+
+static int auth_adaptor_send_message_to_plugin_sync(auth_adaptor_plugin_h plugin,
+                                               plugin_message_h send_message,
+                                               plugin_message_h *receive_message);
+
+/* To be used by adaptor (virtual plugin handle) */
+auth_adaptor_plugin_handle_h __auth_adaptor_create_3rd_party_plugin_handle(const char *plugin_uri);
+
+auth_error_code_t auth_plugin_send_create_context(auth_adaptor_plugin_context_h *context,
+                                                       const char *user_id,
+                                                       const char *user_password,
+                                                       const char *app_id,
+                                                       const char *app_secret,
+                                                       const char *service_name);
+
+auth_error_code_t auth_plugin_send_destroy_context(auth_adaptor_plugin_context_h context);
+
+auth_error_code_t auth_plugin_send_is_auth(auth_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       int *is_auth,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response);
+
+auth_error_code_t auth_plugin_send_join(auth_adaptor_plugin_context_h context,
+                                                       const char *device_id,
+                                                       void *request,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response);
+
+auth_error_code_t auth_plugin_send_login(auth_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response);
+
+auth_error_code_t auth_plugin_send_refresh_access_token(auth_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response);
+
+
+auth_error_code_t auth_plugin_send_set_service_status(auth_adaptor_plugin_context_h context,
+                                                       const int service_id,
+                                                       const int status,
+                                                       void *request,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response);
+
+auth_error_code_t auth_plugin_send_get_msisdn(auth_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       char **msisdn,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response);
+
+auth_error_code_t auth_plugin_send_get_service_status(auth_adaptor_plugin_context_h context,
+               const int service_id,
+               void *request,
+               int *status,
+               auth_adaptor_error_code_h *error,
+               void *response);
+
+auth_error_code_t auth_plugin_send_get_service_policy(auth_adaptor_plugin_context_h context,
+               const int service_id,
+               void *request,
+               char **default_status,
+               char **policy_feature,
+               char **policy_version,
+               char **policy_doc_url,
+               auth_adaptor_error_code_h *error,
+               void *response);
+
+auth_error_code_t auth_plugin_send_get_server_info(auth_adaptor_plugin_context_h context,
+               void *request,
+               GHashTable **server_info,
+               auth_adaptor_error_code_h *error,
+               void *response);
+
+
+/* To be used by forked plugin */
+void *_auth_plugin_request_collector(void *data);
+auth_adaptor_plugin_context_h __auth_plugin_get_context_by_context_id(auth_adaptor_plugin_h plugin, int context_id);
+void __auth_plugin_progress_command(auth_adaptor_plugin_h plugin, char *order, char **result);
+
+
+/* ------------------------------------------------------------------------
+// Functions implementations
+// ------------------------------------------------------------------------ */
+
+/* ////////////////////////////////////////////////////// */
+/* // Mandatory: External adaptor management function /// */
+/* ////////////////////////////////////////////////////// */
+auth_adaptor_h auth_adaptor_create(const char *plugins_dir)
+{
+       if (NULL == plugins_dir) {
+               auth_adaptor_error("Invalid argument""(plugins_dir: %s)", plugins_dir);
+               return NULL;
+       }
+
+       auth_adaptor_h auth_adaptor = (auth_adaptor_h) calloc(1, sizeof(auth_adaptor_t));
+
+       if (NULL == auth_adaptor) {
+               auth_adaptor_error("Critical : Memory allocation failed");
+               return NULL;
+       }
+
+       /* for forked plugin */
+       if (pipe(auth_adaptor->rd_cmd) == -1) {
+               free(auth_adaptor);
+               auth_adaptor = NULL;
+               return NULL;
+       }
+       g_mutex_init(&auth_adaptor->rd_mutex);
+       auth_adaptor->rd_list = NULL;
+/*     auth_adaptor->rd_list = g_list_append(auth_adaptor->rd_list, (gpointer)auth_adaptor->rd_cmd[0]); */
+
+       auth_adaptor->started = 0;
+       auth_adaptor->plugins_dir = strdup(plugins_dir);
+
+       g_mutex_init(&auth_adaptor->auth_adaptor_mutex);
+       g_mutex_init(&auth_adaptor->plugins_mutex);
+       g_mutex_init(&auth_adaptor->adaptor_listeners_mutex);
+
+       g_mutex_lock(&auth_adaptor->adaptor_listeners_mutex);
+       auth_adaptor->adaptor_listeners = NULL;
+       g_mutex_unlock(&auth_adaptor->adaptor_listeners_mutex);
+
+       g_mutex_lock(&auth_adaptor->plugins_mutex);
+       auth_adaptor->plugins = NULL;
+       g_mutex_unlock(&auth_adaptor->plugins_mutex);
+
+
+       return auth_adaptor;
+}
+
+void auth_adaptor_destroy(auth_adaptor_h adaptor)
+{
+       if (NULL == adaptor) {
+               auth_adaptor_error("Invalid argument""(adaptor: %p)", adaptor);
+               return;
+       }
+
+       g_mutex_lock(&adaptor->auth_adaptor_mutex);
+       if (adaptor->started) {
+               auth_adaptor_error("Auth adaptor is running. Forcing stop before destroy");
+               auth_adaptor_stop(adaptor);
+       }
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       if (NULL != adaptor->plugins) {
+               g_list_free_full(adaptor->plugins, (GDestroyNotify) auth_adaptor_plugin_unref);
+               adaptor->plugins = NULL;
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+       if (NULL != adaptor->adaptor_listeners) {
+               g_list_free(adaptor->adaptor_listeners);
+               adaptor->adaptor_listeners = NULL;
+       }
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+/*
+       _service_adaptor_login_reply = NULL;
+*/
+       free(adaptor->plugins_dir);
+       adaptor->plugins_dir = NULL;
+
+       /* For forked plugin */
+       g_list_free(adaptor->rd_list);
+       close(adaptor->rd_cmd[0]);
+       close(adaptor->rd_cmd[1]);
+
+       free(adaptor);
+}
+
+int auth_adaptor_start(auth_adaptor_h adaptor)
+{
+       auth_adaptor_debug("Starting auth adaptor");
+       if (NULL == adaptor) {
+               auth_adaptor_error("Invalid argument""(adaptor: %p)", adaptor);
+               return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->auth_adaptor_mutex);
+       int result = AUTH_ADAPTOR_ERROR_NONE;
+       if (adaptor->started) {
+               auth_adaptor_error("Auth adaptor is already started");
+       } else {
+               adaptor->started = 1;
+
+               pthread_t pid;
+               if (pthread_create(&pid, NULL, _auth_adaptor_plugin_message_collector, (void *)adaptor)) {
+                       adaptor->started = 0;
+                       auth_adaptor_error("Could not create 3rd party plugin listener");
+                       result = AUTH_ADAPTOR_ERROR_NOT_FOUND;
+               } else if (AUTH_ADAPTOR_ERROR_NONE != (result = auth_adaptor_load_plugins_from_directory(adaptor, adaptor->plugins_dir))) {
+                       _auth_adaptor_send_cmd_stop_listen(adaptor);
+                       adaptor->started = 0;
+                       auth_adaptor_error("Could not load plugins from directory");
+                       result = AUTH_ADAPTOR_ERROR_NOT_FOUND;
+               } else {
+                       adaptor->plugin_listener = pid;
+                       auth_adaptor_info("Auth adaptor started successfully");
+               }
+       }
+       g_mutex_unlock(&adaptor->auth_adaptor_mutex);
+
+       return result;
+}
+
+int auth_adaptor_stop(auth_adaptor_h adaptor)
+{
+       if (NULL == adaptor) {
+               auth_adaptor_error("Invalid argument""(adaptor: %p)", adaptor);
+               return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->auth_adaptor_mutex);
+
+       auth_adaptor_debug("stop plugin listener");
+       _auth_adaptor_send_cmd_stop_listen(adaptor);
+       pthread_join(adaptor->plugin_listener, NULL);
+       int result = AUTH_ADAPTOR_ERROR_NONE;
+       if (0 == adaptor->started) {
+               result = AUTH_ADAPTOR_ERROR_STOP;
+       } else {
+               if (NULL != adaptor->plugins) {
+                       g_mutex_lock(&adaptor->plugins_mutex);
+                       g_list_free_full(adaptor->plugins, (GDestroyNotify) auth_adaptor_plugin_unref);
+                       adaptor->plugins = NULL;
+                       g_mutex_unlock(&adaptor->plugins_mutex);
+               }
+               adaptor->started = 0;
+               auth_adaptor_debug("Auth adaptor stopped");
+       }
+
+       g_mutex_unlock(&adaptor->auth_adaptor_mutex);
+
+       return result;
+}
+
+int auth_adaptor_register_listener(auth_adaptor_h adaptor,
+                                               auth_adaptor_listener_h listener)
+{
+       if ((NULL == adaptor) || (NULL == listener)) {
+               auth_adaptor_error("Invalid argument""(adaptor: %p, listener: %p)", adaptor, listener);
+               return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+
+       adaptor->adaptor_listeners = g_list_append(adaptor->adaptor_listeners, listener);
+
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+/*
+       _service_adaptor_login_reply =
+                       (auth_adaptor_service_login_reply_cb)listener->login_reply;
+*/
+       return AUTH_ADAPTOR_ERROR_NONE;
+}
+
+int auth_adaptor_unregister_listener(auth_adaptor_h adaptor,
+                                               auth_adaptor_listener_h listener)
+{
+       if ((NULL == adaptor) || (NULL == listener)) {
+               auth_adaptor_error("Invalid argument""(adaptor: %p, listener: %p)", adaptor, listener);
+               return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+
+       if (NULL == g_list_find(adaptor->adaptor_listeners, listener)) {
+               g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+               auth_adaptor_error("Could not find listener");
+               return AUTH_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       adaptor->adaptor_listeners = g_list_remove(adaptor->adaptor_listeners, listener);
+
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+/*
+       _service_adaptor_login_reply = NULL;
+*/
+       return AUTH_ADAPTOR_ERROR_NONE;
+}
+
+/* /////////////////////////////////////////////////////////////
+   // Plugin create / destroy / ref. count / get plugin name
+   ///////////////////////////////////////////////////////////// */
+static auth_adaptor_plugin_h auth_adaptor_create_plugin(const char *plugin_path)
+{
+       if (NULL == plugin_path) {
+               auth_adaptor_error("Invalid argument""(plugin_path: %p)", plugin_path);
+               return NULL;
+
+       }
+
+       void *dl_handle = dlopen(plugin_path, RTLD_LAZY);
+       if (NULL == dl_handle) {
+               auth_adaptor_error("Could not load plugin %s: %s", plugin_path, dlerror());
+               return NULL;
+       }
+
+       auth_adaptor_plugin_handle_h (*get_adaptee_handle)(void) = NULL;
+
+       get_adaptee_handle = (auth_adaptor_plugin_handle_h (*)(void))(dlsym(dl_handle, "create_plugin_handle"));
+       if (NULL == get_adaptee_handle) {
+               dlclose(dl_handle);
+               auth_adaptor_error("Could not get function pointer to create_plugin_handle");
+               return NULL;
+       }
+
+       plugin_req_enter();
+       auth_adaptor_plugin_handle_h handle = get_adaptee_handle();
+       plugin_req_exit_void();
+       if (NULL == handle) {
+               dlclose(dl_handle);
+               auth_adaptor_error("Could not get adaptee handle");
+               return NULL;
+       }
+
+       auth_adaptor_plugin_h plugin = (auth_adaptor_plugin_h) calloc(1, sizeof(auth_adaptor_plugin_t));
+       if (NULL == plugin) {
+               dlclose(dl_handle);
+               auth_adaptor_error("Could not create plugin object");
+               return NULL;
+       }
+
+       plugin->path = g_strdup(plugin_path);
+       plugin->handle = handle;
+       plugin->dl_handle = dl_handle;
+       plugin->ref_counter = 0;
+
+       plugin->type = PLUGIN_TYPE_INHOUSE;
+
+       g_mutex_init(&plugin->ref_counter_mutex);
+       g_mutex_init(&plugin->plugin_listener_mutex);
+       g_mutex_init(&plugin->contexts_mutex);
+       plugin->contexts = NULL;
+
+       auth_adaptor_plugin_listener_h listener =
+               (auth_adaptor_plugin_listener_h) calloc(1, sizeof(auth_adaptor_plugin_listener_t));
+/*
+       listener->auth_adaptor_login_reply              = auth_adaptor_login_reply_cb;
+*/
+       plugin_req_enter();
+       plugin->handle->set_listener(listener);
+       plugin_req_exit_void();
+
+       g_mutex_lock(&plugin->plugin_listener_mutex);
+       plugin->plugin_listener = listener;
+       g_mutex_unlock(&plugin->plugin_listener_mutex);
+
+       return plugin;
+}
+
+static void auth_adaptor_destroy_plugin(auth_adaptor_plugin_h plugin)
+{
+       if (NULL == plugin) {
+               auth_adaptor_error("Invalid argument""(plugin: %p)", plugin);
+               return;
+       }
+
+       if (NULL != plugin->handle) {
+               plugin->handle->destroy_handle(plugin->handle);
+
+               g_mutex_lock(&plugin->plugin_listener_mutex);
+               plugin_req_enter();
+               plugin->handle->unset_listener();
+               plugin_req_exit_void();
+               g_mutex_unlock(&plugin->plugin_listener_mutex);
+
+               plugin->handle = NULL;
+       }
+
+       if (NULL != plugin->dl_handle) {
+               dlclose(plugin->dl_handle);
+               plugin->dl_handle = NULL;
+       }
+
+       g_free(plugin->path);
+       plugin->path = NULL;
+
+       free(plugin);
+}
+
+static int auth_adaptor_load_plugins_from_directory(auth_adaptor_h adaptor,
+                                               const char *dir_path)
+{
+       char *plugin_path = NULL;
+       DIR *dir = NULL;
+       struct dirent dir_entry, *result = NULL;
+
+       auth_adaptor_debug("Starting load plugins from directory");
+
+       if ((NULL == adaptor) || (NULL == dir_path)) {
+               auth_adaptor_error("Invalid argument""(adaptor: %p, dir_path: %p)", adaptor, dir_path);
+               return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       dir = opendir(dir_path);
+       if (NULL == dir) {
+               auth_adaptor_error("Could not open dir path (%s)", dir_path);
+               return AUTH_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       int ret = AUTH_ADAPTOR_ERROR_NONE;
+       while (0 == (readdir_r(dir, &dir_entry, &result))) {
+
+               if (NULL == result) {
+                       auth_adaptor_error("Could not open directory %s", plugin_path);
+                       break;
+               }
+
+               if (dir_entry.d_type & DT_DIR) {
+                       continue;
+               }
+
+               plugin_path = g_strconcat(dir_path, "/", dir_entry.d_name, NULL);
+               auth_adaptor_plugin_h plugin = auth_adaptor_create_plugin(plugin_path);
+
+               if (NULL != plugin) {
+                       auth_adaptor_debug("Loaded plugin: %s", plugin_path);
+                       plugin->adaptor = adaptor;
+                       auth_adaptor_plugin_ref(plugin);
+                       g_mutex_lock(&adaptor->plugins_mutex);
+                       adaptor->plugins = g_list_append(adaptor->plugins, plugin);
+                       g_mutex_unlock(&adaptor->plugins_mutex);
+               } else {
+                       auth_adaptor_error("Could not load plugin %s", plugin_path);
+               }
+
+               free(plugin_path);
+               plugin_path = NULL;
+       }
+
+       auth_adaptor_debug("End load plugins from directory");
+       closedir(dir);
+       return ret;
+}
+
+static int auth_adaptor_has_plugin(auth_adaptor_h adaptor,
+                                               auth_adaptor_plugin_h plugin)
+{
+       if ((NULL == adaptor) || (NULL == plugin)) {
+               auth_adaptor_error("Invalid argument""(adaptor: %p, plugin: %p)", adaptor, plugin);
+               return 0;
+       }
+
+       int result = 0;
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       if (NULL != g_list_find(adaptor->plugins, plugin)) {
+               result = 1;
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return result;
+}
+
+static void auth_adaptor_plugin_ref(auth_adaptor_plugin_h plugin)
+{
+       if (NULL == plugin) {
+               auth_adaptor_error("Invalid argument""(plugin: %p)", plugin);
+               return;
+       }
+
+       g_mutex_lock(&plugin->ref_counter_mutex);
+       plugin->ref_counter = plugin->ref_counter + 1;
+       if (NULL != plugin->handle) {
+               auth_adaptor_info("plugin name: %s, ref_counter: %d",
+                               plugin->handle->plugin_uri, plugin->ref_counter);
+       } else {
+               auth_adaptor_info("ref_counter: %d", plugin->ref_counter);
+       }
+       g_mutex_unlock(&plugin->ref_counter_mutex);
+}
+
+static void auth_adaptor_plugin_unref(auth_adaptor_plugin_h plugin)
+{
+       if (NULL == plugin) {
+               auth_adaptor_error("Invalid argument""(plugin: %p)", plugin);
+               return;
+       }
+
+       int should_destroy = 0;
+
+       g_mutex_lock(&plugin->ref_counter_mutex);
+       plugin->ref_counter = plugin->ref_counter - 1;
+       if (NULL != plugin->handle) {
+               auth_adaptor_info("plugin name: %s, ref_counter: %d",
+                               plugin->handle->plugin_uri, plugin->ref_counter);
+       } else {
+               auth_adaptor_info("ref_counter: %d", plugin->ref_counter);
+       }
+       if (0 >= plugin->ref_counter) {
+               should_destroy = 1;
+       }
+       g_mutex_unlock(&plugin->ref_counter_mutex);
+
+       if (should_destroy) {
+               auth_adaptor_debug("Plugin is being destroyed");
+               auth_adaptor_destroy_plugin(plugin);
+       }
+}
+
+/* For 3rd party plugin packages */
+int auth_adaptor_load_plugin_from_package(auth_adaptor_h adaptor,
+                                               const char *package_id,
+                                               const char *plugin_path)
+{
+       int adaptor_fd[2];
+       int plugin_fd[2];
+
+       if (pipe(adaptor_fd) == -1) {
+               auth_adaptor_debug("pipe creation error, can not load plugin package");
+       } else if (pipe(plugin_fd) == -1) {
+               close(adaptor_fd[0]);
+               close(adaptor_fd[1]);
+               auth_adaptor_debug("pipe creation error[2], can not load plugin package");
+       } else {
+               g_process_identity = fork();
+               if (0 == g_process_identity) {  /* child */
+                       auth_adaptor_debug_func("[CHILD PROCESS] forked success (PID : %d, id : %d)", (int)getpid());
+
+                       auth_adaptor_plugin_h plugin = NULL;
+                       plugin = auth_adaptor_create_plugin(plugin_path);
+
+                       if (NULL == plugin) {
+                               auth_adaptor_error("[CHILD PROCESS] Load plugin failed");
+                               exit(1);
+                       }
+
+                       plugin->rd = plugin_fd[0];
+                       close(plugin_fd[1]);
+                       plugin->wd = adaptor_fd[1];
+                       close(adaptor_fd[0]);
+                       void *temp = _auth_plugin_request_collector((void *)plugin);
+                       auth_adaptor_debug_func("[CHILD PROCESS] exit %p", temp);
+                       exit(0);
+               } else if (0 < g_process_identity) {    /* parent */
+                       auth_adaptor_debug_func("[PARENT PROCESS] forked success (PID : %d)", (int)getpid());
+                       auth_adaptor_plugin_h _plugin = (auth_adaptor_plugin_h) calloc(1, sizeof(auth_adaptor_plugin_t));
+                       if (NULL != _plugin) {
+                               _plugin->ref_counter = 0;
+                               g_mutex_init(&_plugin->ref_counter_mutex);
+                               g_mutex_init(&_plugin->message_mutex);
+
+                               _plugin->handle = __auth_adaptor_create_3rd_party_plugin_handle(package_id);
+
+                               _plugin->type = PLUGIN_TYPE_3RD_PARTY;
+                               _plugin->pid = g_process_identity;
+                               _plugin->rd = adaptor_fd[0];
+                               close(adaptor_fd[1]);
+                               _plugin->wd = plugin_fd[1];
+                               close(plugin_fd[0]);
+
+                               _auth_adaptor_send_cmd_add_fd(adaptor, _plugin->rd);
+
+                               _plugin->adaptor = adaptor;
+                               auth_adaptor_plugin_ref(_plugin);
+                               g_mutex_lock(&adaptor->plugins_mutex);
+                               adaptor->plugins = g_list_append(adaptor->plugins, _plugin);
+                               g_mutex_unlock(&adaptor->plugins_mutex);
+                       }
+               } else {
+                       close(adaptor_fd[0]);
+                       close(adaptor_fd[1]);
+                       close(plugin_fd[0]);
+                       close(plugin_fd[1]);
+                       auth_adaptor_debug("fork error, can not load plugin package");
+               }
+       }
+
+       return 0;
+}
+
+/* //////////////////////////////////////////////////////
+   // Get plugin name by plugin
+   ////////////////////////////////////////////////////// */
+void auth_adaptor_get_plugin_uri(auth_adaptor_plugin_h plugin,
+                                               char **plugin_uri)
+{
+       if ((NULL == plugin) || (NULL == plugin_uri)) {
+               auth_adaptor_error("Invalid argument""(plugin: %p, uri: %p)", plugin, plugin_uri);
+               return;
+       }
+       if (NULL != plugin->handle) {
+               *plugin_uri = strdup(plugin->handle->plugin_uri);
+       }
+}
+
+/* //////////////////////////////////////////////////////
+   // Create / Destroy error code
+   ////////////////////////////////////////////////////// */
+static auth_adaptor_error_code_h auth_adaptor_create_error_code(const int64_t code,
+                                               const char *msg)
+{
+       if (NULL == msg) {
+               return NULL;
+       }
+
+       auth_adaptor_error_code_h error_code =
+                       (auth_adaptor_error_code_h) malloc(sizeof(auth_adaptor_error_code_t));
+
+       if (NULL != error_code) {
+               error_code->code = code;
+               error_code->msg = strdup(msg);
+       }
+
+       return error_code;
+}
+
+void auth_adaptor_destroy_error_code(auth_adaptor_error_code_h *error_code)
+{
+       if ((NULL != error_code) && (NULL != (*error_code))) {
+               free((*error_code)->msg);
+               (*error_code)->msg = NULL;
+               free(*error_code);
+               *error_code = NULL;
+       }
+}
+
+/* //////////////////////////////////////////////////////
+   // Plugin context create / destroy
+   ////////////////////////////////////////////////////// */
+auth_adaptor_plugin_context_h auth_adaptor_create_plugin_context(auth_adaptor_plugin_h plugin,
+                                               const char *user_id,
+                                               const char *user_password,
+                                               const char *app_id,
+                                               const char *app_secret,
+                                               const char *imsi,
+                                               const char *service_name)
+{
+       auth_adaptor_debug("Starting auth_adaptor_create_plugin_context");
+
+       if ((NULL == plugin) || (NULL == service_name)) {
+               auth_adaptor_error("Invalid argument""(plugin: %p, service_name: %s)",
+                               plugin, service_name);
+               return NULL;
+       }
+
+       if (NULL != plugin->handle) {
+               auth_adaptor_plugin_context_h plugin_context = NULL;
+               if (plugin->type == PLUGIN_TYPE_3RD_PARTY) {
+                       plugin_context = (auth_adaptor_plugin_context_h) calloc(1, sizeof(auth_adaptor_plugin_context_t));
+                       if (NULL == plugin_context) {
+                               auth_adaptor_error("Create context failed");
+                               return NULL;
+                       } else {
+                               plugin_context->plugin_handle = plugin;
+                       }
+               }
+
+               plugin_req_enter();
+               plugin->handle->create_context(&plugin_context, SAFE_ADD_STRING(user_id), SAFE_ADD_STRING(user_password), SAFE_ADD_STRING(app_id), SAFE_ADD_STRING(app_secret), SAFE_ADD_STRING(imsi));
+               plugin_req_exit_void();
+
+               if (NULL == plugin_context) {
+                       auth_adaptor_error("Create context failed");
+                       return NULL;
+               } else {
+                       plugin_context->plugin_uri = strdup(plugin->handle->plugin_uri);
+                       plugin_context->service_name = strdup(service_name);
+               }
+
+               /* For forked plugin */
+               g_mutex_lock(&plugin->contexts_mutex);
+               plugin->contexts = g_list_append(plugin->contexts, (gpointer)plugin_context);
+               g_mutex_unlock(&plugin->contexts_mutex);
+
+               return plugin_context;
+       } else {
+               auth_adaptor_error("Plugin handle is null");
+       }
+
+       auth_adaptor_debug("End auth_adaptor_create_plugin_context");
+       return NULL;
+}
+
+void auth_adaptor_destroy_plugin_context(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h plugin_context)
+{
+       if ((NULL == plugin) || (NULL == plugin_context)) {
+               auth_adaptor_error("Invalid argument""(plugin: %p, plugin_context: %p)", plugin, plugin_context);
+               return;
+       }
+
+       if (NULL != plugin->handle) {
+               /* For forked plugin */
+               g_mutex_lock(&plugin->contexts_mutex);
+               plugin->contexts = g_list_remove(plugin->contexts, (gpointer)plugin_context);
+               g_mutex_unlock(&plugin->contexts_mutex);
+
+               plugin_req_enter();
+               plugin->handle->destroy_context(plugin_context);
+               plugin_req_exit_void();
+       } else {
+               auth_adaptor_error("Plugin handle is null");
+       }
+
+       return;
+}
+
+/* //////////////////////////////////////////////////////
+   // Get plugin by plugin name
+   ////////////////////////////////////////////////////// */
+auth_adaptor_plugin_h auth_adaptor_get_plugin_by_name(auth_adaptor_h adaptor,
+                                               const char *plugin_uri)
+{
+       auth_adaptor_debug("Starting auth_adaptor_get_plugin_by_name");
+
+       if ((NULL == adaptor) || (NULL == plugin_uri)) {
+               auth_adaptor_error("Invalid argument""(adaptor: %p, plugin_uri: %p)", adaptor, plugin_uri);
+               return NULL;
+       }
+
+       auth_adaptor_plugin_h plugin = NULL;
+       g_mutex_lock(&adaptor->plugins_mutex);
+
+       int count = g_list_length(adaptor->plugins);
+       int i = 0;
+       for (i = 0; i < count; i++) {
+               auth_adaptor_plugin_h temp_plugin = g_list_nth_data(adaptor->plugins, i);
+               if (NULL != temp_plugin) {
+                       if (0 == strcmp(temp_plugin->handle->plugin_uri, plugin_uri)) {
+                               auth_adaptor_plugin_ref(temp_plugin);
+                               plugin = temp_plugin;
+                               g_mutex_unlock(&adaptor->plugins_mutex);
+                               return plugin;
+                       }
+               }
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return plugin;
+}
+
+/* //////////////////////////////////////////////////////
+   // Plugin load / unload / get plugin list
+   ////////////////////////////////////////////////////// */
+int auth_adaptor_load_plugin(auth_adaptor_h adaptor,
+                                               const char *plugin_path)
+{
+       if ((NULL == adaptor) || (NULL == plugin_path)) {
+               auth_adaptor_error("Invalid argument""(adaptor: %p, plugin_path: %p)", adaptor, plugin_path);
+               return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (0 == adaptor->started) {
+               auth_adaptor_error("Auth adaptor is not started");
+               return AUTH_ADAPTOR_ERROR_START;
+       }
+
+       auth_adaptor_plugin_h plugin = auth_adaptor_create_plugin(plugin_path);
+       if (NULL == plugin) {
+               auth_adaptor_error("Could not load plugin %s", plugin_path);
+               return AUTH_ADAPTOR_ERROR_CREATE;
+       }
+
+       plugin->adaptor = adaptor;
+       auth_adaptor_plugin_ref(plugin);
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       adaptor->plugins = g_list_append(adaptor->plugins, plugin);
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return AUTH_ADAPTOR_ERROR_NONE;
+}
+
+int auth_adaptor_unload_plugin(auth_adaptor_h adaptor,
+                                               auth_adaptor_plugin_h plugin)
+{
+       if ((NULL == adaptor) || (NULL == plugin)) {
+               auth_adaptor_error("Invalid argument""(adaptor: %p, plugin: %p)", adaptor, plugin);
+               return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (0 == adaptor->started) {
+               auth_adaptor_error("Auth adaptor is not started");
+               return AUTH_ADAPTOR_ERROR_START;
+       }
+
+       if (0 == auth_adaptor_has_plugin(adaptor, plugin)) {
+               auth_adaptor_error("Auth adaptor has no plugin");
+               return AUTH_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       plugin->adaptor = NULL;
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       adaptor->plugins = g_list_remove(adaptor->plugins, plugin);
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       auth_adaptor_plugin_unref(plugin);
+
+       return AUTH_ADAPTOR_ERROR_NONE;
+}
+
+GList *auth_adaptor_get_plugins(auth_adaptor_h adaptor)
+{
+       if (NULL == adaptor) {
+               auth_adaptor_error("Invalid argument""(adaptor: %p)", adaptor);
+               return NULL;
+       }
+
+       GList *plugins = NULL;
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       int plugins_count = g_list_length(adaptor->plugins);
+       int i;
+       for (i = 0; i < plugins_count; i++) {
+               auth_adaptor_plugin_h plugin = g_list_nth_data(adaptor->plugins, i);
+               if (NULL != plugin) {
+                       auth_adaptor_plugin_ref(plugin);
+                       plugins = g_list_append(plugins, plugin);
+               }
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return plugins;
+}
+
+/* ////////////////////////////////////////////////////////////
+   // Adaptor get Element Functions
+   //////////////////////////////////////////////////////////// */
+
+/*
+ * @return : Need free
+ */
+EXPORT_API
+char *auth_adaptor_get_access_token_dup(auth_adaptor_plugin_context_h context)
+{
+       if (NULL == context) {
+               auth_adaptor_warning("Invalid argument""(context: %p", context);
+               return NULL;
+       }
+
+       if (NULL == context->access_token) {
+               auth_adaptor_warning("Invalid argument""(context->access_token: %p", context->access_token);
+               return NULL;
+       }
+
+       if (0 >= strlen(context->access_token)) {
+               auth_adaptor_warning("Invalid argument""(context->access_token length: %d", strlen(context->access_token));
+               return NULL;
+       }
+
+       return strdup(context->access_token);
+}
+
+/*
+ * @return : Need free
+ */
+EXPORT_API
+char *auth_adaptor_get_uid_dup(auth_adaptor_plugin_context_h context)
+{
+       if (NULL == context) {
+               auth_adaptor_warning("Invalid argument""(context: %p", context);
+               return NULL;
+       }
+
+       if (NULL == context->uid) {
+               auth_adaptor_warning("Invalid argument""(context->uid: %p", context->uid);
+               return NULL;
+       }
+
+       if (0 >= strlen(context->uid)) {
+               auth_adaptor_warning("Invalid argument""(context->uid length: %d", strlen(context->uid));
+               return NULL;
+       }
+
+       return strdup(context->uid);
+}
+
+/*
+ * @return : Need free
+ */
+EXPORT_API
+char *auth_adaptor_get_msisdn_dup(auth_adaptor_plugin_context_h context)
+{
+       if (NULL == context) {
+               auth_adaptor_warning("Invalid argument""(context: %p", context);
+               return NULL;
+       }
+
+       if (NULL == context->msisdn) {
+               auth_adaptor_warning("Invalid argument""(context->msisdn: %p", context->msisdn);
+               return NULL;
+       }
+
+       if (0 >= strlen(context->msisdn)) {
+               auth_adaptor_warning("Invalid argument""(context->msisdn length: %d", strlen(context->msisdn));
+               return NULL;
+       }
+
+       return strdup(context->msisdn);
+}
+
+/* ////////////////////////////////////////////////////////////
+   // Adaptor Plugin call Functions
+   //////////////////////////////////////////////////////////// */
+
+auth_error_code_t _auth_adaptor_mandatory_param_check(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               auth_adaptor_error_code_h *error_code)
+{
+       auth_error_code_t ret = AUTH_ADAPTOR_ERROR_NONE;
+
+       if ((NULL == plugin) || (NULL == context)) {
+               auth_adaptor_error("Invalid argument""(plugin: %p, context: %p)", plugin, context);
+               if (NULL != error_code) {
+                       *error_code = auth_adaptor_create_error_code(
+                                       (int64_t) AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                       "Invalid argument (plugin or context)");
+               }
+
+               return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               auth_adaptor_error("Plugin handle is null");
+
+               if (NULL != error_code) {
+                       *error_code = auth_adaptor_create_error_code(
+                                       (int64_t) AUTH_ADAPTOR_ERROR_INVALID_HANDLE,
+                                       "Plugin handle is null");
+               }
+
+               return AUTH_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       return ret;
+}
+
+/**
+* @brief Check Account Registration [Sync API]
+*
+* @param[in]   plugin          specifies Auth-adaptor Plugin handle
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   request         specifies Optional value for specific Plugin (Recommend Json Object format)
+* @param[out]  is_auth         specifies Registered Flag (Registered : 1, Not registered : 0)
+* @param[out]  error_code      specifies Error code
+* @param[out]  response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
+*/
+auth_error_code_t auth_adaptor_is_auth(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               void *request,
+                                               int *is_auth,
+                                               auth_adaptor_error_code_h *error_code, void *response)
+{
+       auth_error_code_t ret = _auth_adaptor_mandatory_param_check(plugin, context, error_code);
+       if (AUTH_ADAPTOR_ERROR_NONE != ret) {
+               return ret;
+       }
+
+       if ((NULL == is_auth)) {
+               auth_adaptor_error("Invalid argument""(is_auth: %p)", is_auth);
+               if (NULL != error_code) {
+                       *error_code = auth_adaptor_create_error_code(
+                                       (int64_t) AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                       "Invalid argument (is_auth pointer is null)");
+               }
+
+               return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle->is_auth) {
+               auth_adaptor_error("Plugin does not support this API");
+               if (NULL != error_code) {
+                       *error_code = auth_adaptor_create_error_code(
+                                       (int64_t) AUTH_ADAPTOR_ERROR_UNSUPPORTED,
+                                       "Plugin does not support this API (is_auth)");
+               }
+               return AUTH_ADAPTOR_ERROR_UNSUPPORTED;
+       }
+
+       plugin_req_enter();
+       ret = plugin->handle->is_auth(context, request, is_auth, error_code, response);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+/**
+* @brief Request Access Token (included auth_adaptor_context) [Sync API]
+*
+* @param[in]   plugin          specifies Auth-adaptor Plugin handle
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   is_auth         specifies Registration Flag (Must be issued from "auth_adaptor_is_auth" Function)
+* @param[in]   request         specifies Optional value for specific Plugin (Recommend Json Object format)
+* @param[out]  error_code      specifies Error code
+* @param[out]  response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
+*/
+auth_error_code_t auth_adaptor_login(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               int is_auth,
+                                               void *request,
+                                               auth_adaptor_error_code_h *error_code,
+                                               void *response)
+{
+       auth_error_code_t ret = _auth_adaptor_mandatory_param_check(plugin, context, error_code);
+       if (AUTH_ADAPTOR_ERROR_NONE != ret) {
+               return ret;
+       }
+
+       if ((0 > is_auth) || (1 < is_auth)) {
+               auth_adaptor_error("\"is_auth\" value must be issued from \"auth_adaptor_is_auth\"");
+
+               if (NULL != error_code) {
+                       *error_code = auth_adaptor_create_error_code(
+                                       (int64_t) AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                       "Invalid argument (is_auth)");
+               }
+
+               return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (0 == is_auth) {
+               auth_adaptor_error("Device is not joined. Please register to ESU");
+
+               if (NULL != error_code) {
+                       *error_code = auth_adaptor_create_error_code(
+                                       (int64_t) AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL,
+                                       "Device is not joined");
+               }
+
+               return AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+
+
+       char *old_access_token = auth_adaptor_get_access_token_dup(context);
+       char *old_uid = auth_adaptor_get_uid_dup(context);
+       free(context->uid);
+       free(context->access_token);
+       context->access_token = NULL;
+       context->uid = NULL;
+
+       plugin_req_enter();
+       ret = plugin->handle->login(context, request, error_code, response);
+       plugin_req_exit(ret, plugin, error_code);
+
+       if (AUTH_ADAPTOR_ERROR_NONE == ret) {
+               auth_adaptor_info("Login Successed");
+
+               if (NULL == context->access_token)
+               /* || (NULL == context->uid)) */
+               {
+                       auth_adaptor_error("Critical missmatching Error!!\n");
+                       auth_adaptor_error("Login returns success but access_token is NULL");
+                       ret = AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+
+                       if (NULL != error_code)
+                       {
+                               *error_code = auth_adaptor_create_error_code((int64_t) AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL,
+                                               "Plugin returns Login success but access_token is Empty");
+                       }
+               }
+
+       }
+       if (NULL != context->access_token) {
+               free(old_access_token);
+       } else {
+               auth_adaptor_error("Fill old access token by error");
+               context->access_token = old_access_token;
+       }
+       if (NULL != context->uid) {
+               free(old_uid);
+       } else {
+               auth_adaptor_error("Fill old uid by error");
+               context->uid = old_uid;
+       }
+
+       return ret;
+}
+
+/**
+* @brief Request for Refreshing Access Token (included auth_adaptor_context) [Sync API]
+*
+* @param[in]   plugin          specifies Auth-adaptor Plugin handle
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   request         specifies Optional value for specific Plugin (Recommend Json Object format)
+* @param[out]  error_code      specifies Error code
+* @param[out]  response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
+*/
+auth_error_code_t auth_adaptor_login_refresh(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               void *request,
+                                               auth_adaptor_error_code_h *error_code,
+                                               void *response)
+{
+       auth_error_code_t ret = _auth_adaptor_mandatory_param_check(plugin, context, error_code);
+       if (AUTH_ADAPTOR_ERROR_NONE != ret) {
+               return ret;
+       }
+
+       if ((NULL == context->access_token) || (0 >= strlen(context->access_token))) {
+               auth_adaptor_error("Access_token is empty. Please login first");
+
+               if (NULL != error_code) {
+                       *error_code = auth_adaptor_create_error_code(
+                                       (int64_t) AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                       "Invalid argument (context->access_token)");
+               }
+
+               return AUTH_ADAPTOR_ERROR_NOT_AUTHORIZED;
+       }
+
+       char *old_access_token = auth_adaptor_get_access_token_dup(context);
+       char *old_uid = auth_adaptor_get_uid_dup(context);
+/*     free(context->uid); */
+/*     free(context->access_token); */
+/*     context->access_token = NULL; */
+/*     context->uid = NULL; */
+       plugin_req_enter();
+       ret = plugin->handle->refresh_access_token(context, request, error_code, response);
+       plugin_req_exit(ret, plugin, error_code);
+
+       if (AUTH_ADAPTOR_ERROR_NONE == ret) {
+               auth_adaptor_info("Login refresh Successed");
+/*
+               if ((NULL == context->access_token) || (NULL == context->uid))
+               {
+                       auth_adaptor_error("Critical missmatching Error!!\n");
+                       auth_adaptor_error("Login_refresh returns success but access_token or uid is NULL");
+                       ret = AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+
+                       if (NULL != error_code)
+                       {
+                               *error_code = auth_adaptor_create_error_code((int64_t) AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL,
+                                               "Plugin returns Login_refresh success but access_token or uid is Empty");
+                       }
+               }
+*/
+       }
+
+       if (NULL != context->access_token) {
+               free(old_access_token);
+       } else {
+               auth_adaptor_error("Fill old access token by error");
+               context->access_token = old_access_token;
+       }
+       if (NULL != context->uid) {
+               free(old_uid);
+       } else {
+               auth_adaptor_error("Fill old uid by error");
+               context->uid = old_uid;
+       }
+
+       return ret;
+}
+
+/**
+* @brief Request Account Registration [Sync API]
+*
+* @param[in]   plugin          specifies Auth-adaptor Plugin handle
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   device_id       specifies Device Unique ID
+* @param[in]   request         specifies Optional value for specific Plugin (Recommend Json Object format)
+* @param[out]  error_code      specifies Error code
+* @param[out]  response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
+*/
+auth_error_code_t auth_adaptor_join(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               const char *device_id,
+                                               void *request,
+                                               auth_adaptor_error_code_h *error_code,
+                                               void *response)
+{
+       auth_error_code_t ret = _auth_adaptor_mandatory_param_check(plugin, context, error_code);
+       if (AUTH_ADAPTOR_ERROR_NONE != ret) {
+               return ret;
+       }
+
+       if (NULL == plugin->handle->join) {
+               auth_adaptor_error("Plugin does not support this API");
+               if (NULL != error_code) {
+                       *error_code = auth_adaptor_create_error_code(
+                                       (int64_t) AUTH_ADAPTOR_ERROR_UNSUPPORTED,
+                                       "Plugin does not support this API (is_auth)");
+               }
+               return AUTH_ADAPTOR_ERROR_UNSUPPORTED;
+       }
+
+       plugin_req_enter();
+       ret = plugin->handle->join(context, device_id, request, error_code, response);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+/**
+* @brief Request Account Information (MSISDN) [Sync API]
+*
+* @param[in]   plugin          specifies Auth-adaptor Plugin handle
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   request         specifies Optional value for specific Plugin (Recommend Json Object format)
+* @param[out]  msisdn          specifies MSISDN
+* @param[out]  error_code      specifies Error code
+* @param[out]  response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
+*/
+auth_error_code_t auth_adaptor_get_msisdn(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               void *request,
+                                               char **msisdn,
+                                               auth_adaptor_error_code_h *error_code,
+                                               void *response)
+{
+       auth_error_code_t ret = _auth_adaptor_mandatory_param_check(plugin, context, error_code);
+       if (AUTH_ADAPTOR_ERROR_NONE != ret) {
+               return ret;
+       }
+
+       plugin_req_enter();
+       ret = plugin->handle->get_msisdn(context, request, msisdn, error_code, response);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+/**
+* @brief Request Changing Service Status (Enable, Disable or etc...) [Sync API]
+*
+* @param[in]   plugin          specifies Auth-adaptor Plugin handle
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   service_id      specifies Service ID (The value is depended by Server)
+* @param[in]   status          specifies Service Status (The value is depended by Server)
+* @param[in]   request         specifies Optional value for specific Plugin (Recommend Json Object format)
+* @param[out]  error_code      specifies Error code
+* @param[out]  response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
+*/
+auth_error_code_t auth_adaptor_set_service_status(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               const int service_id,
+                                               const int status,
+                                               void *request,
+                                               auth_adaptor_error_code_h *error_code,
+                                               void *response)
+{
+       auth_error_code_t ret = _auth_adaptor_mandatory_param_check(plugin, context, error_code);
+       if (AUTH_ADAPTOR_ERROR_NONE != ret) {
+               return ret;
+       }
+
+       plugin_req_enter();
+       ret = plugin->handle->set_service_status(context, service_id, status, request, error_code, response);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+/**
+* @brief Request Service Status [Sync API]
+*
+* @param[in]   plugin          specifies Auth-adaptor Plugin handle
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   service_id      specifies Service ID (The value is depended by Server)
+* @param[in]   request         specifies Optional value for specific Plugin (Recommend Json Object format)
+* @param[out]  status          specifies Service Status (The value is depended by Server)
+* @param[out]  error_code      specifies Error code
+* @param[out]  response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
+*/
+auth_error_code_t auth_adaptor_get_service_status(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               const int service_id,
+                                               void *request,
+                                               int *status,
+                                               auth_adaptor_error_code_h *error_code,
+                                               void *response)
+{
+       auth_error_code_t ret = _auth_adaptor_mandatory_param_check(plugin, context, error_code);
+       if (AUTH_ADAPTOR_ERROR_NONE != ret) {
+               return ret;
+       }
+
+       plugin_req_enter();
+       ret = plugin->handle->get_service_status(context, service_id, request, status, error_code, response);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+/**
+* @brief Request Service Policy [Sync API]
+*
+* @param[in]   plugin          specifies Auth-adaptor Plugin handle
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   service_id      specifies Service ID (The value is depended by Server)
+* @param[in]   request         specifies Optional value for specific Plugin (Recommend Json Object format)
+* @param[in]   default_status  specifies Service default Status Policy
+* @param[in]   policy_feature  specifies Service Policy Feature
+* @param[in]   policy_version  specifies Service Policy Version
+* @param[in]   policy_doc_url  specifies Service Policy Document URL
+* @param[out]  error_code      specifies Error code
+* @param[out]  response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
+*/
+auth_error_code_t auth_adaptor_get_service_policy(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               const int service_id,
+                                               void *request,
+                                               char **default_status,
+                                               char **policy_feature,
+                                               char **policy_version,
+                                               char **policy_doc_url,
+                                               auth_adaptor_error_code_h *error_code,
+                                               void *response)
+{
+       auth_error_code_t ret = _auth_adaptor_mandatory_param_check(plugin, context, error_code);
+       if (AUTH_ADAPTOR_ERROR_NONE != ret) {
+               return ret;
+       }
+
+       plugin_req_enter();
+       ret = plugin->handle->get_service_policy(context, service_id, request, default_status,
+                       policy_feature, policy_version, policy_doc_url, error_code, response);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+/**
+* @brief Request Permitted Server information for Account [Sync API]
+*
+* @param[in]   plugin          specifies Auth-adaptor Plugin handle
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   request         specifies Optional value for specific Plugin (Recommend Json Object format)
+* @param[out]  server_info     specifies server information (URL, Scheme, Port)
+* @param[out]  error_code      specifies Error code
+* @param[out]  response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+auth_error_code_t auth_adaptor_get_server_info(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               void *request,
+                                               GHashTable **server_info,
+                                               auth_adaptor_error_code_h *error_code,
+                                               void *response)
+{
+       auth_error_code_t ret = _auth_adaptor_mandatory_param_check(plugin, context, error_code);
+       if (AUTH_ADAPTOR_ERROR_NONE != ret) {
+               return ret;
+       }
+
+       plugin_req_enter();
+       ret = plugin->handle->get_server_info(context, request, server_info, error_code, response);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+auth_error_code_t auth_adaptor_external_request(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               const char *api_uri,
+                                               const unsigned char *req_bundle_raw,
+                                               int req_len,
+                                               unsigned char **res_bundle_raw,
+                                               int *res_len,
+                                               auth_adaptor_error_code_h *error_code)
+{
+       auth_error_code_t ret = AUTH_ADAPTOR_ERROR_NONE;
+
+       if (NULL == plugin) {
+               auth_adaptor_error("Invalid argument""(plugin: %p)", plugin);
+               if (NULL != error_code) {
+                       *error_code = auth_adaptor_create_error_code(
+                                       (int64_t) AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                       "Invalid argument (plugin)");
+               }
+
+               return AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               auth_adaptor_error("Plugin handle is null");
+
+               if (NULL != error_code) {
+                       *error_code = auth_adaptor_create_error_code(
+                                       (int64_t) AUTH_ADAPTOR_ERROR_INVALID_HANDLE,
+                                       "Plugin handle is null");
+               }
+
+               return AUTH_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       if (NULL ==  plugin->handle->external_request) {
+               if (NULL != error_code) {
+                       *error_code = auth_adaptor_create_error_code(AUTH_ADAPTOR_ERROR_UNSUPPORTED,
+                                       "API does not supported by plugin");
+               }
+               return AUTH_ADAPTOR_ERROR_UNSUPPORTED;
+       }
+
+       plugin_req_enter();
+       ret = plugin->handle->external_request(context, api_uri,
+                       req_bundle_raw, req_len,
+                       res_bundle_raw, res_len, error_code);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+/* ///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+////////////  Internal function description (for forked plugin)  //////////////
+///////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////// */
+
+void *_auth_adaptor_plugin_message_collector(void *data)
+{
+       auth_adaptor_h adaptor = (auth_adaptor_h) data;
+
+       auth_adaptor_info("3rd party plugin listener run");
+       int i, lagest_fd = -1;
+       fd_set read_set;
+       struct timeval tv;
+       tv.tv_sec = 10L;                /* TODO change to define or meaningful value */
+       char msg_buf[PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE] = {0, };
+       int buf_size, rcv_len;
+       GList *dead_list = NULL;
+
+       while (1) {
+               /* Clears and sets fds for select */
+               FD_ZERO(&read_set);
+               FD_SET(adaptor->rd_cmd[0], &read_set);
+               lagest_fd = adaptor->rd_cmd[0];
+
+               /* Sets plugin fds for select */
+               for (i = 0; i < g_list_length(adaptor->rd_list); i++) {
+                       int fd = (int) g_list_nth_data(adaptor->rd_list, i);
+                       FD_SET(fd, &read_set);
+                       if (lagest_fd < fd) {
+                               lagest_fd = fd;
+                       }
+               }
+
+               /* Select with timeout (for avoid blocking issue) */
+               int stmt = select((lagest_fd + 1), &read_set, NULL, NULL, &tv);
+               IF_IS_PLUGIN_THAN_RETURN_NULL();
+               if (stmt == 0) {
+/*                     auth_adaptor_debug("select refrech by timeout(%ld sec) [id : %d]", tv.tv_sec, g_process_identity); */
+                       if (0L >= tv.tv_sec) {
+/*                             auth_adaptor_debug("Resets selector timeout sec"); */
+                               tv.tv_sec = 10L;
+                       }
+                       IF_IS_PLUGIN_THAN_RETURN_NULL();
+               } else if (stmt > 0) {
+                       /* Checking message queue with Plugin processes. */
+                       for (i = 0; i < g_list_length(adaptor->rd_list); i++) {
+                               IF_IS_PLUGIN_THAN_RETURN_NULL();
+                               int fd = (int) g_list_nth_data(adaptor->rd_list, i);
+                               if (FD_ISSET(fd, &read_set)) {
+                                       IF_IS_PLUGIN_THAN_RETURN_NULL();
+                                       /* pre-read buf size */
+                                       rcv_len = read(fd, &buf_size, sizeof(int));
+                                       if (0 >= rcv_len) {
+                                               auth_adaptor_debug("Child process dead (Remove from listening queue)");
+                                               dead_list = g_list_append(dead_list, (gpointer)fd);
+                                               continue;
+                                       }
+                                       /* allocates and read buf data */
+                                       memset(msg_buf, 0, PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE);
+                                       buf_size %= PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE - 1;
+                                       rcv_len = read(fd, msg_buf, buf_size);
+                                       auth_adaptor_debug("read message [%s][%d]", msg_buf, rcv_len);
+
+                                       if (0 < rcv_len) {
+                                               /* transfer data to adaptor */
+                                               __auth_adaptor_transfer_message(msg_buf);
+                                       } else {
+                                               auth_adaptor_debug("Child process dead (Remove from listening queue)");
+                                               dead_list = g_list_append(dead_list, (gpointer)fd);
+                                       }
+                               }
+                       }
+
+                       /* Checking message queue with Adaptor internal command. */
+                       IF_IS_PLUGIN_THAN_RETURN_NULL();
+                       if (FD_ISSET(adaptor->rd_cmd[0], &read_set)) {
+                               int fd = adaptor->rd_cmd[0];
+                               IF_IS_PLUGIN_THAN_RETURN_NULL();
+                               /* pre-read buf size */
+                               rcv_len = read(fd, &buf_size, sizeof(int));
+
+                               if (0 >= rcv_len) {
+                                       auth_adaptor_debug("Parent process dead : Listener break");
+                                       break;
+                               }
+
+                               /* allocates and read buf data */
+                               memset(msg_buf, 0, PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE);
+                               buf_size %= PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE - 1;
+                               rcv_len = read(fd, msg_buf, buf_size);
+                               auth_adaptor_debug("read message [%s][%d]", msg_buf, rcv_len);
+
+                               if (0 >= rcv_len) {
+                                       auth_adaptor_debug("Parent process dead : Listener break");
+                                       break;
+                               }
+
+                               /* parse cmd message (e.g. append read_fd / change timeout sec / stop listener) */
+                               int cmd_ret = __auth_adaptor_parse_message_cmd(adaptor, msg_buf);
+                               if (0 > cmd_ret) {
+                                       auth_adaptor_info("3rd party plugin listener stopped by adaptor cmd");
+                                       break;
+                               }
+                       }
+
+                       /* Remove fd with disconnected plugin. */
+                       for (i = 0; i < g_list_length(dead_list); i++) {
+                               adaptor->rd_list = g_list_remove(adaptor->rd_list, (gpointer) g_list_nth_data(dead_list, i));
+                       }
+                       g_list_free(dead_list);
+                       dead_list = NULL;
+               } else {
+                       auth_adaptor_error("plugin message listener error (errno : %d)", errno);
+               }
+       }
+       auth_adaptor_info("3rd party plugin listener stopped");
+
+       return data;
+}
+
+void __auth_adaptor_transfer_message(const char *msg)
+{
+       plugin_message_h t_msg = NULL;
+       int ret = 0;
+       ret = plugin_message_deserialize(msg, &t_msg);
+       if (!ret) {
+               pmnumber req_type, req_id;
+               ret = plugin_message_get_value_number(t_msg, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE, &req_type);
+
+               if (!ret && (PLUGIN_MESSAGE_TYPE_FUNCTION == req_type)) {
+                       auth_adaptor_debug("MEssage function type : function");
+                       ret = plugin_message_get_value_number(t_msg, PLUGIN_MESSAGE_ELEMENT_REQUEST_ID, &req_id);
+                       if (!ret) {
+                               auth_adaptor_debug("Send plugin data to requester");
+                               int hooked_fd = (int) req_id;
+                               int len = strlen(msg);
+                               ret = write(hooked_fd, &len, sizeof(int));
+                               if (0 < len) {
+                                       ret = write(hooked_fd, msg, sizeof(char) * len);
+                               }
+                       } else {
+                               auth_adaptor_debug("Couldn't get request id");
+                       }
+               } else if (!ret && (PLUGIN_MESSAGE_TYPE_CALLBACK == req_type)) {
+                       auth_adaptor_warning("Auth adaptor unsupport callback yet");
+               } else {
+                       auth_adaptor_warning("Received message parsing fail.");
+               }
+               plugin_message_destroy(t_msg);
+       }
+}
+
+int __auth_adaptor_parse_message_cmd(auth_adaptor_h adaptor, char *msg)
+{
+       char *cmd_data = NULL;
+       if (0 == strncmp(PLUGIN_MESSAGE_LISTENER_CMD_APPEND_FD, msg, strlen(PLUGIN_MESSAGE_LISTENER_CMD_APPEND_FD))) {
+               cmd_data = msg + strlen(PLUGIN_MESSAGE_LISTENER_CMD_APPEND_FD);
+               int fd = atoi(cmd_data);
+
+               adaptor->rd_list = g_list_append(adaptor->rd_list, (gpointer)fd);
+       } else if (0 == strncmp(PLUGIN_MESSAGE_LISTENER_CMD_STOP, msg, strlen(PLUGIN_MESSAGE_LISTENER_CMD_STOP))) {
+               return -1;
+       }
+
+       return 0;
+}
+
+
+void _auth_adaptor_send_cmd_add_fd(auth_adaptor_h adaptor, int fd)
+{
+       char cmd_buf[256] = {0, };
+       snprintf(cmd_buf, 255, "%s%d", PLUGIN_MESSAGE_LISTENER_CMD_APPEND_FD, fd);
+       int len = strlen(cmd_buf);
+       int wr_ret;
+
+       g_mutex_lock(&adaptor->rd_mutex);
+       wr_ret = write(adaptor->rd_cmd[1], &len, sizeof(int));
+       wr_ret = write(adaptor->rd_cmd[1], cmd_buf, sizeof(char) * len);
+       g_mutex_unlock(&adaptor->rd_mutex);
+       auth_adaptor_debug("writed (%d)(%s)", wr_ret, cmd_buf);
+}
+
+void _auth_adaptor_send_cmd_stop_listen(auth_adaptor_h adaptor)
+{
+       char cmd_buf[256] = {0, };
+       snprintf(cmd_buf, 255, "%s", PLUGIN_MESSAGE_LISTENER_CMD_STOP);
+       int len = strlen(cmd_buf);
+       int wr_ret;
+
+       g_mutex_lock(&adaptor->rd_mutex);
+       wr_ret = write(adaptor->rd_cmd[1], &len, sizeof(int));
+       wr_ret = write(adaptor->rd_cmd[1], cmd_buf, sizeof(char) * len);
+       g_mutex_unlock(&adaptor->rd_mutex);
+       auth_adaptor_debug("writed (%d)(%s)", wr_ret, cmd_buf);
+}
+
+static int auth_adaptor_send_message_to_plugin_sync(auth_adaptor_plugin_h plugin,
+                                               plugin_message_h send_message,
+                                               plugin_message_h *receive_message)
+{
+       int io_ret = 0;
+       int wfd = plugin->wd;
+       int sync_hook[2];
+
+       if (pipe(sync_hook) != -1) {
+               char read_buf[PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE] = {0, };
+
+               plugin_message_set_value_number(send_message, PLUGIN_MESSAGE_ELEMENT_REQUEST_ID, (pmnumber) sync_hook[1]);
+               char *stream = NULL;
+               io_ret = plugin_message_serialize(send_message, &stream);
+               int len = strlen(stream);
+
+               g_mutex_lock(&plugin->message_mutex);
+               io_ret = write(wfd, &len, sizeof(len));
+               io_ret = write(wfd, stream, sizeof(char) * len);
+               g_mutex_unlock(&plugin->message_mutex);
+               free(stream);
+               stream = NULL;
+               len = 0;
+
+               io_ret = read(sync_hook[0], &len, sizeof(len));
+
+               if (0 < len) {
+                       memset(read_buf, 0, PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE);
+                       len %= PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE - 1;
+                       io_ret = read(sync_hook[0], read_buf, len);
+               }
+               auth_adaptor_debug("io ret : %d", io_ret);
+               close(sync_hook[0]);
+               close(sync_hook[1]);
+
+               plugin_message_h _rcv;
+               if (0 < strlen(read_buf)) {
+                       io_ret = plugin_message_deserialize(read_buf, &_rcv);
+                       if (!io_ret) {
+                               *receive_message = _rcv;
+                       }
+               }
+       } else {
+               io_ret = -1;
+       }
+
+       return io_ret;
+}
+
+auth_adaptor_plugin_handle_h __auth_adaptor_create_3rd_party_plugin_handle(const char *plugin_uri)
+{
+       auth_adaptor_plugin_handle_h handle = (auth_adaptor_plugin_handle_h) calloc(1, sizeof(auth_adaptor_plugin_handle_t));
+
+       if (NULL != handle) {
+               handle->create_context = auth_plugin_send_create_context;
+               handle->destroy_context = auth_plugin_send_destroy_context;
+               handle->is_auth = auth_plugin_send_is_auth;
+               handle->login = auth_plugin_send_login;
+               handle->refresh_access_token = auth_plugin_send_refresh_access_token;
+
+               handle->set_service_status = auth_plugin_send_set_service_status;
+               handle->get_msisdn = auth_plugin_send_get_msisdn;
+               handle->get_service_status = auth_plugin_send_get_service_status;
+               handle->get_service_policy = auth_plugin_send_get_service_policy;
+               handle->get_server_info = auth_plugin_send_get_server_info;
+
+
+               handle->plugin_uri = strdup(plugin_uri);
+       }
+
+       return handle;
+}
+
+auth_error_code_t auth_plugin_send_create_context(auth_adaptor_plugin_context_h *context,
+                                                       const char *user_id,
+                                                       const char *user_password,
+                                                       const char *app_id,
+                                                       const char *app_secret,
+                                                       const char *imsi)
+{
+       auth_adaptor_plugin_h plugin = NULL;
+       plugin = (*context)->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               (*context)->context_id = (int) (intptr_t)(*context);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) (*context)->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               AUTH_PLUGIN_INTERFACE_CREATE_CONTEXT);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               int param_index = 1;
+               plugin_message_set_param_string(message, param_index++, user_id);
+               plugin_message_set_param_string(message, param_index++, user_password);
+               plugin_message_set_param_string(message, param_index++, app_id);
+               plugin_message_set_param_string(message, param_index++, app_secret);
+               plugin_message_set_param_string(message, param_index++, imsi);
+
+               plugin_message_h result_message = NULL;
+               ret = auth_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+
+                       char *ret_msg = NULL;
+                       if (AUTH_ADAPTOR_ERROR_NONE == ret) {
+                               auth_adaptor_debug("Create context successed");
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               auth_adaptor_debug("Create context failed (%d)(%s)", ret, ret_msg);
+                               free(ret_msg);
+                               ret_msg = NULL;
+
+                               free(*context);
+                               (*context) = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+
+
+}
+
+auth_error_code_t auth_plugin_send_destroy_context(auth_adaptor_plugin_context_h context)
+{
+       auth_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               AUTH_PLUGIN_INTERFACE_DESTROY_CONTEXT);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               plugin_message_h result_message = NULL;
+               ret = auth_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+
+                       char *ret_msg = NULL;
+                       if (AUTH_ADAPTOR_ERROR_NONE == ret) {
+                               auth_adaptor_debug("Destroy context successed");
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               auth_adaptor_debug("Destroy context failed (%d)(%s)", ret, ret_msg);
+                               free(ret_msg);
+                               ret_msg = NULL;
+
+                               auth_adaptor_debug("Force release memory by adaptor process");
+                               free(context->access_token);
+                               free(context);
+                               context = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+
+
+}
+
+
+
+
+auth_error_code_t auth_plugin_send_is_auth(auth_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       int *is_auth,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response)
+{
+       auth_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID, (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME, AUTH_PLUGIN_INTERFACE_IS_AUTH);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE, (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               plugin_message_h result_message = NULL;
+               ret = auth_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber _is_auth, ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+
+                       char *ret_msg = NULL;
+                       if (AUTH_ADAPTOR_ERROR_NONE == ret) {
+                               auth_adaptor_debug("Is_auth successed");
+                               plugin_message_get_param_number(result_message, 1, &_is_auth);
+                               *is_auth = (int)_is_auth;
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               auth_adaptor_debug("Is_auth failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       auth_adaptor_error_code_h error_code = auth_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+auth_error_code_t auth_plugin_send_join(auth_adaptor_plugin_context_h context,
+                                                       const char *device_id,
+                                                       void *request,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response)
+{
+       auth_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID, (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME, AUTH_PLUGIN_INTERFACE_JOIN);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE, (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               plugin_message_h result_message = NULL;
+               ret = auth_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+
+                       char *ret_msg = NULL;
+                       if (AUTH_ADAPTOR_ERROR_NONE == ret) {
+                               auth_adaptor_debug("Join successed");
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               auth_adaptor_debug("Join failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       auth_adaptor_error_code_h error_code = auth_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+
+
+auth_error_code_t auth_plugin_send_login(auth_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response)
+{
+       auth_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               AUTH_PLUGIN_INTERFACE_LOGIN);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               plugin_message_h result_message = NULL;
+               ret = auth_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (AUTH_ADAPTOR_ERROR_NONE == ret) {
+                               auth_adaptor_debug("Login successed");
+                               char *access_token = NULL;
+                               char *uid = NULL;
+                               int param_idx = 1;
+                               plugin_message_get_param_string(result_message, param_idx++, &access_token);
+                               plugin_message_get_param_string(result_message, param_idx++, &uid);
+                               auth_adaptor_debug("access token : %s", access_token);
+                               auth_adaptor_debug("uid : %s", uid);
+
+                               context->access_token = access_token;
+                               context->uid = uid;
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               auth_adaptor_debug("Login failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       auth_adaptor_error_code_h error_code = auth_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+
+}
+
+auth_error_code_t auth_plugin_send_refresh_access_token(auth_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response)
+{
+       auth_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               AUTH_PLUGIN_INTERFACE_REFRESH_ACCESS_TOKEN);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               plugin_message_h result_message = NULL;
+               ret = auth_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (AUTH_ADAPTOR_ERROR_NONE == ret) {
+                               auth_adaptor_debug("Login refresh successed");
+                               char *access_token = NULL;
+                               char *uid = NULL;
+                               int param_idx = 1;
+                               plugin_message_get_param_string(result_message, param_idx++, &access_token);
+                               plugin_message_get_param_string(result_message, param_idx++, &uid);
+                               auth_adaptor_debug("access token : %s", access_token);
+                               auth_adaptor_debug("uid : %s", uid);
+
+                               context->access_token = access_token;
+                               context->uid = uid;
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               auth_adaptor_debug("Login refresh failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       auth_adaptor_error_code_h error_code = auth_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+
+}
+/*
+auth_error_code_t auth_plugin_send_get_server_info(auth_adaptor_plugin_context_h context,
+               void *request,
+               GHashTable **server_info,
+               auth_adaptor_error_code_h *error,
+               void *response)
+
+{
+       auth_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0)
+       {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               AUTH_PLUGIN_INTERFACE_LOGIN);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               plugin_message_h result_message = NULL;
+               ret = auth_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret)
+               {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (AUTH_ADAPTOR_ERROR_NONE == ret)
+                       {
+                               auth_adaptor_debug("Get server info successed");
+                               char *server_info_raw = NULL;
+                               int param_idx = 1;
+                               plugin_message_get_param_string(result_message, param_idx++, &server_info_raw);
+
+                               if ((NULL != server_info) && (NULL != server_info_raw))
+                               {
+                                       bundle *info_data = bundle_decode((bundle_raw)server_info_raw, strlen(server_info_raw));
+                                       if (NULL != info_data)
+                                       {
+                                               GHashTable *ht = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);
+                                               bundle_foreach(info_data, server_info_iter, (void *) ht);
+                                               *server_info = ht;
+                                       }
+                               }
+
+                               free(server_info_raw);
+                       }
+                       else
+                       {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               auth_adaptor_debug("Login failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error)
+                               {
+                                       auth_adaptor_error_code_h error_code = auth_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       }
+       else
+       {
+               ret = AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+
+}
+*/
+
+
+auth_error_code_t auth_plugin_send_set_service_status(auth_adaptor_plugin_context_h context,
+                                                       const int service_id,
+                                                       const int status,
+                                                       void *request,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response)
+{
+       return AUTH_ADAPTOR_ERROR_UNSUPPORTED;
+}
+
+auth_error_code_t auth_plugin_send_get_msisdn(auth_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       char **msisdn,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response)
+{
+       return AUTH_ADAPTOR_ERROR_UNSUPPORTED;
+}
+
+auth_error_code_t auth_plugin_send_get_service_status(auth_adaptor_plugin_context_h context,
+               const int service_id,
+               void *request,
+               int *status,
+               auth_adaptor_error_code_h *error,
+               void *response)
+{
+       return AUTH_ADAPTOR_ERROR_UNSUPPORTED;
+}
+
+auth_error_code_t auth_plugin_send_get_service_policy(auth_adaptor_plugin_context_h context,
+               const int service_id,
+               void *request,
+               char **default_status,
+               char **policy_feature,
+               char **policy_version,
+               char **policy_doc_url,
+               auth_adaptor_error_code_h *error,
+               void *response)
+{
+       return AUTH_ADAPTOR_ERROR_UNSUPPORTED;
+}
+
+auth_error_code_t auth_plugin_send_get_server_info(auth_adaptor_plugin_context_h context,
+               void *request,
+               GHashTable **server_info,
+               auth_adaptor_error_code_h *error,
+               void *response)
+{
+       return AUTH_ADAPTOR_ERROR_UNSUPPORTED;
+}
+
+
+/* For forked plugin */
+void *_auth_plugin_request_collector(void *data)
+{
+       auth_adaptor_plugin_h plugin = (auth_adaptor_plugin_h) data;
+
+       int rcv_len, buf_size;
+       char msg_buf[PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE] = {0, };
+
+       while (1) {
+               /* pre-read buf size */
+               rcv_len = read(plugin->rd, &buf_size, sizeof(int));
+
+               if (rcv_len <= 0) {
+                       LOGD("shutdown by adaptor disconnected");
+                       return NULL;
+               }
+
+               /* allocates and read buf data */
+               memset(msg_buf, 0, PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE);
+               buf_size %= PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE - 1;
+               rcv_len = read(plugin->rd, msg_buf, buf_size);
+               LOGD("read message [%s][len: %d]", msg_buf, rcv_len);
+
+               if (rcv_len <= 0) {
+                       LOGD("shutdown by adaptor disconnected");
+                       return NULL;
+               }
+
+               char *result = NULL;
+               __auth_plugin_progress_command(plugin, msg_buf, &result);
+
+               if (NULL != result) {
+                       int res_len = strlen(result);
+                       rcv_len = write(plugin->wd, &res_len, sizeof(int));
+                       rcv_len = write(plugin->wd, result, sizeof(char) * res_len);
+               }
+               /* transfer data to adaptor */
+               /*              __auth_adaptor_transfer_message(adaptor, msg_buf); */
+       }
+       return data;
+}
+
+auth_adaptor_plugin_context_h __auth_plugin_get_context_by_context_id(auth_adaptor_plugin_h plugin, int context_id)
+{
+       if (NULL == plugin) {
+               return NULL;
+       }
+
+       /* For forked plugin */
+       auth_adaptor_plugin_context_h ctx = NULL;
+       int i, len;
+       len = g_list_length(plugin->contexts);
+
+       for (i = 0; i < len; i++) {
+               ctx = (auth_adaptor_plugin_context_h) g_list_nth_data(plugin->contexts, i);
+
+               if (context_id == ctx->context_id) {
+                       return ctx;
+               }
+       }
+       return NULL;
+}
+
+void __auth_plugin_progress_command(auth_adaptor_plugin_h plugin, char *order, char **result)
+{
+       int ret = 0;
+       plugin_message_h m_order = NULL;
+       plugin_message_h m_result = NULL;
+
+       if ((NULL == order) || (plugin_message_deserialize(order, &m_order))) {
+               LOGE("[%s/%d] Message parse error", __FUNCTION__, __LINE__);
+               return;
+       } else if (plugin_message_create(&m_result)) {
+               plugin_message_destroy(m_order);
+               m_order = NULL;
+
+               LOGE("[%s/%d] Message parse error", __FUNCTION__, __LINE__);
+               return;
+       }
+
+       char *func_name = NULL;
+       int context_id = 0;
+
+       pmnumber ctx, req, type;
+
+       plugin_message_get_value_number(m_order, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID, &ctx);
+       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID, ctx);
+       plugin_message_get_value_number(m_order, PLUGIN_MESSAGE_ELEMENT_REQUEST_ID, &req);
+       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_REQUEST_ID, req);
+       plugin_message_get_value_string(m_order, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME, &func_name);
+       plugin_message_set_value_string(m_result, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME, func_name);
+       plugin_message_get_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE, &type);
+       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE, type);
+       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)AUTH_ADAPTOR_ERROR_NONE);
+       context_id = (int) ctx;
+       auth_adaptor_plugin_context_h context = __auth_plugin_get_context_by_context_id(plugin, context_id);
+
+       auth_adaptor_error_code_h error_code = NULL;
+
+       if (0 == strncmp(AUTH_PLUGIN_INTERFACE_CREATE_CONTEXT,
+                       func_name, strlen(AUTH_PLUGIN_INTERFACE_CREATE_CONTEXT))) {
+               LOGD(">>>>>> %s func start", func_name);
+               char *user_id = NULL;
+               char *user_password = NULL;
+               char *app_id = NULL;
+               char *app_secret = NULL;
+               char *service_name = NULL;
+               char *imsi = NULL;
+
+               int param_idx = 1;
+               plugin_message_get_param_string(m_order, param_idx++, &user_id);
+               plugin_message_get_param_string(m_order, param_idx++, &user_password);
+               plugin_message_get_param_string(m_order, param_idx++, &app_id);
+               plugin_message_get_param_string(m_order, param_idx++, &app_secret);
+               plugin_message_get_param_string(m_order, param_idx++, &imsi);
+
+               LOGD("Call library function");
+               context = auth_adaptor_create_plugin_context(plugin,
+                               user_id, user_password, app_id, app_secret, imsi, "");
+               if (NULL == context) {
+                       LOGE("[%s<%s>/%d] Could not create context", __FUNCTION__, func_name, __LINE__);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       "Could not create context");
+               } else {
+                       LOGD("[%s<%s>/%d] Created context successfuly", __FUNCTION__, func_name, __LINE__);
+                       context->context_id = context_id;
+
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)AUTH_ADAPTOR_ERROR_NONE);
+               }
+
+               free(user_id);
+               free(user_password);
+               free(app_id);
+               free(app_secret);
+               free(service_name);
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(AUTH_PLUGIN_INTERFACE_DESTROY_CONTEXT,
+                       func_name, strlen(AUTH_PLUGIN_INTERFACE_DESTROY_CONTEXT))) {
+               LOGD(">>>>>> %s func start", func_name);
+               if (NULL == context) {
+                       LOGE("[%s<%s>/%d] Could not found context", __FUNCTION__, func_name, __LINE__);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       "Invalid argument (context is NULL)");
+               } else {
+                       LOGD("[%s<%s>/%d] function success", __FUNCTION__, func_name, __LINE__);
+                       auth_adaptor_destroy_plugin_context(plugin, context);
+
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)AUTH_ADAPTOR_ERROR_NONE);
+               }
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(AUTH_PLUGIN_INTERFACE_IS_AUTH,
+                       func_name, strlen(AUTH_PLUGIN_INTERFACE_IS_AUTH))) {
+               LOGD(">>>>>> %s func start", func_name);
+               int is_auth = 0;
+               LOGD("Call library function");
+               if (NULL == context) {
+                       LOGE("[%s<%s>/%d] Could not found context", __FUNCTION__, func_name, __LINE__);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       "Invalid argument (context is NULL)");
+               } else {
+                       ret = plugin->handle->is_auth(context, NULL, &is_auth, &error_code, NULL);
+                       if (AUTH_ADAPTOR_ERROR_NONE == ret) {
+                               int param_idx = 1;
+                               plugin_message_set_param_number(m_result, param_idx++, (pmnumber)is_auth);
+                               plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+                       } else if (NULL != error_code) {
+                               plugin_message_set_value_number(m_result,
+                                               PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                               (pmnumber)error_code->code);
+                               plugin_message_set_value_string(m_result,
+                                               PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                               error_code->msg ? error_code->msg : "");
+                               free(error_code->msg);
+                               free(error_code);
+                       } else {
+                               plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+                       }
+               }
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(AUTH_PLUGIN_INTERFACE_LOGIN,
+                       func_name, strlen(AUTH_PLUGIN_INTERFACE_LOGIN))) {
+               LOGD(">>>>>> %s func start", func_name);
+               LOGD("Call library function");
+               if (NULL == context) {
+                       LOGE("[%s<%s>/%d] Could not found context", __FUNCTION__, func_name, __LINE__);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       "Invalid argument (context is NULL)");
+               } else {
+                       ret = plugin->handle->login(context, NULL, &error_code, NULL);
+                       if (AUTH_ADAPTOR_ERROR_NONE == ret) {
+                               int param_idx = 1;
+                               plugin_message_set_param_string(m_result, param_idx++, context->access_token ? context->access_token : "");
+                               plugin_message_set_param_string(m_result, param_idx++, context->uid ? context->uid : "");
+                               plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+                       } else if (NULL != error_code) {
+                               plugin_message_set_value_number(m_result,
+                                               PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                               (pmnumber)error_code->code);
+                               plugin_message_set_value_string(m_result,
+                                               PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                               error_code->msg ? error_code->msg : "");
+                               free(error_code->msg);
+                               free(error_code);
+                       } else {
+                               plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+                       }
+               }
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(AUTH_PLUGIN_INTERFACE_REFRESH_ACCESS_TOKEN,
+                       func_name, strlen(AUTH_PLUGIN_INTERFACE_REFRESH_ACCESS_TOKEN))) {
+               LOGD(">>>>>> %s func start", func_name);
+               LOGD("Call library function");
+               if (NULL == context) {
+                       LOGE("[%s<%s>/%d] Could not found context", __FUNCTION__, func_name, __LINE__);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       "Invalid argument (context is NULL)");
+               } else {
+                       ret = plugin->handle->refresh_access_token(context, NULL, &error_code, NULL);
+                       if (AUTH_ADAPTOR_ERROR_NONE == ret) {
+                               int param_idx = 1;
+                               plugin_message_set_param_string(m_result, param_idx++, context->access_token ? context->access_token : "");
+                               plugin_message_set_param_string(m_result, param_idx++, context->uid ? context->uid : "");
+                               plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+                       } else if (NULL != error_code) {
+                               plugin_message_set_value_number(m_result,
+                                               PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                               (pmnumber)error_code->code);
+                               plugin_message_set_value_string(m_result,
+                                               PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                               error_code->msg ? error_code->msg : "");
+                               free(error_code->msg);
+                               free(error_code);
+                       } else {
+                               plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+                       }
+               }
+               LOGD("<<<<<< %s func end", func_name);
+       } else {
+               plugin_message_set_value_number(m_result,
+                               PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                               (pmnumber)AUTH_ADAPTOR_ERROR_UNSUPPORTED);
+               plugin_message_set_value_string(m_result,
+                               PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                               "Unsupported operation");
+       }
+
+       free(func_name);
+
+       char *result_data = NULL;
+       plugin_message_serialize(m_result, &result_data);
+       plugin_message_destroy(m_result);
+       plugin_message_destroy(m_order);
+
+       *result = result_data;
+}
+
+
diff --git a/adaptor/auth-adaptor/auth-adaptor.h b/adaptor/auth-adaptor/auth-adaptor.h
new file mode 100644 (file)
index 0000000..2db99f8
--- /dev/null
@@ -0,0 +1,654 @@
+/*
+* Copyright (c) 2011 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 __AUTH_ADAPTOR_H__
+#define __AUTH_ADAPTOR_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+#include <glib.h>
+#include <stdint.h>
+
+/**
+ * @brief Enumerations of error code for Auth Adaptor
+ */
+typedef enum auth_error_code_e
+{
+       AUTH_ADAPTOR_ERROR_NONE                      = 0,
+       AUTH_ADAPTOR_ERROR_LAUNCH                    = 1,    /**< 1 ~ 99: internal error*/
+       AUTH_ADAPTOR_ERROR_INIT                      = 2,
+       AUTH_ADAPTOR_ERROR_DEINIT                    = 3,
+       AUTH_ADAPTOR_ERROR_CREATE                    = 4,
+       AUTH_ADAPTOR_ERROR_DESTROY                   = 5,
+       AUTH_ADAPTOR_ERROR_START                     = 6,
+       AUTH_ADAPTOR_ERROR_STOP                      = 7,
+       AUTH_ADAPTOR_ERROR_CONNECT                   = 8,
+       AUTH_ADAPTOR_ERROR_DISCONNECT                = 9,
+       AUTH_ADAPTOR_ERROR_NOT_FOUND                 = 10,
+       AUTH_ADAPTOR_ERROR_CORRUPTED                 = 11,
+       AUTH_ADAPTOR_ERROR_UNSUPPORTED               = 12,
+       AUTH_ADAPTOR_ERROR_INVALID_HANDLE            = 13,
+       AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT          = 14,
+       AUTH_ADAPTOR_ERROR_INVALID_ARGUMENT_TYPE     = 15,
+       AUTH_ADAPTOR_ERROR_NOT_AUTHORIZED            = 16,
+       AUTH_ADAPTOR_ERROR_ADAPTOR_INTERNAL          = 17,
+       AUTH_ADAPTOR_ERROR_PLUGIN_INTERNAL           = 18,
+       AUTH_ADAPTOR_ERROR_SERVER_INTERNAL           = 19,
+       AUTH_ADAPTOR_ERROR_DBUS                      = 20,
+       AUTH_ADAPTOR_ERROR_CALLBACK_TIME_OUT         = 21,
+       AUTH_ADAPTOR_ERROR_MAX
+} auth_error_code_t;
+
+/**
+ * @brief Enumerations of error code for Auth Plugin Internal Error
+ */
+typedef enum _auth_plugin_internal_error_code_e
+{
+        AUTH_PLUGIN_ERROR_HTTP_BAD_REQUEST           = 400,
+        AUTH_PLUGIN_ERROR_HTTP_UNAUTHORIZED          = 401,
+        AUTH_PLUGIN_ERROR_HTTP_FORBIDDEN             = 403,
+        AUTH_PLUGIN_ERROR_HTTP_NOT_FOUND             = 404,
+        AUTH_PLUGIN_ERROR_HTTP_METHOD_NOT_ALLOWED    = 405,
+        AUTH_PLUGIN_ERROR_HTTP_BAD_GATEWAY           = 502,
+        AUTH_PLUGIN_ERROR_HTTP_SERVICE_UNAVAILBLE    = 503,
+        AUTH_PLUGIN_ERROR_HTTP_INSUFFICIENT_AUTH     = 507,
+        AUTH_PLUGIN_ERROR_HTTP_ETC                   = 598,
+        AUTH_PLUGIN_ERROR_HTTP_UNKNOWN               = 599,
+
+        AUTH_PLUGIN_ERROR_CURL_COULDNT_CONNECT       = 601,
+        AUTH_PLUGIN_ERROR_CURL_TIMEOUT               = 602,
+        AUTH_PLUGIN_ERROR_CURL_ETC                   = 698,
+        AUTH_PLUGIN_ERROR_CURL_UNKNOWN               = 699,
+
+        AUTH_PLUGIN_ERROR_FILE_OPEN_FAILED           = 701,
+        AUTH_PLUGIN_ERROR_FILE_NOT_EXIST             = 702,
+        AUTH_PLUGIN_ERROR_FILE_ETC                   = 798,
+        AUTH_PLUGIN_ERROR_FILE_UNKNOWN               = 799,
+
+        AUTH_PLUGIN_ERROR_MEMORY_ALLOCATION_FAILED   = 801,
+        AUTH_PLUGIN_ERROR_MEMORY_ETC                 = 898,
+        AUTH_PLUGIN_ERROR_MEMORY_UNKNOWN             = 899,
+
+        AUTH_PLUGIN_ERROR_THREAD_CREATE_FAILED       = 901,
+        AUTH_PLUGIN_ERROR_THREAD_STOPPED             = 902,
+        AUTH_PLUGIN_ERROR_THREAD_ETC                 = 908,
+        AUTH_PLUGIN_ERROR_THREAD_UNNOWN              = 909,
+
+       AUTH_PLUGIN_ERROR_CALLBACK_TIME_OUT          = 997,
+        AUTH_PLUGIN_ERROR_ETC                        = 998,
+        AUTH_PLUGIN_ERROR_UNKNOWN                    = 999,
+}auth_plugin_internal_error_code_e;
+
+/**
+* @brief The handle for Auth Plugin
+*/
+typedef struct auth_adaptor_plugin_s *auth_adaptor_plugin_h;
+
+/**
+* @brief The handle for Auth Adaptor
+*/
+typedef struct auth_adaptor_s *auth_adaptor_h;
+
+/**
+* @brief Describes infromation about Plugin Context
+*/
+typedef struct auth_adaptor_plugin_context_s
+{
+       // Context variables
+       int context_id;
+       auth_adaptor_plugin_h plugin_handle;
+
+       // User define (input by service-adaptor)
+        char    *user_id;
+        char    *user_password;
+        char    *app_id;
+        char    *app_secret;
+       char    *service_name;
+
+       // Plugin define (input by plugin)
+        char    *plugin_uri;   // mandatory (package id)
+       void    *plugin_data;   // optional
+
+       // Plugin define (input by server response after autholization)
+        char    *access_token;
+       char    *refresh_token;
+       char    *uid;
+
+       // For product feature
+       char    *msisdn;
+       char    *imsi;
+        char    *plugin_name;
+//        char    *cluster_name;
+} auth_adaptor_plugin_context_t;
+typedef struct auth_adaptor_plugin_context_s *auth_adaptor_plugin_context_h;
+
+/**
+* @brief Describes infromation about error code from plugin internal
+*/
+typedef struct auth_adaptor_error_code_s
+{
+        int64_t code;
+        char    *msg;
+} auth_adaptor_error_code_t;
+/**
+* @brief The handle for error code
+*/
+typedef struct auth_adaptor_error_code_s *auth_adaptor_error_code_h;
+
+/**
+* @brief The handle for Auth Plugin Listener
+*/
+typedef struct auth_adaptor_plugin_listener_s *auth_adaptor_plugin_listener_h;
+
+/**
+* @brief Describes infromation about Plugin Handle
+*/
+typedef struct auth_adaptor_plugin_handle_s
+{
+       // Mandatory functions to handle plugin in adaptor
+       auth_error_code_t (*create_context)(auth_adaptor_plugin_context_h *context,
+                                                       const char *user_id,
+                                                       const char *user_password,
+                                                       const char *app_id,
+                                                       const char *app_secret,
+                                                       const char *imsi);
+
+       auth_error_code_t (*destroy_context)(auth_adaptor_plugin_context_h context);
+       auth_error_code_t (*destroy_handle)(struct auth_adaptor_plugin_handle_s *handle);
+       auth_error_code_t (*set_listener)(auth_adaptor_plugin_listener_h listener);
+       auth_error_code_t (*unset_listener)(void);
+       // Mandatory end
+
+       // Optional
+        auth_error_code_t (*is_auth)(auth_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       int *is_auth,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response);
+
+        auth_error_code_t (*join)(auth_adaptor_plugin_context_h context,
+                                                       const char *device_id,
+                                                       void *request,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response);
+
+        auth_error_code_t (*login)(auth_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response);
+
+        auth_error_code_t (*refresh_access_token)(auth_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response);
+
+        auth_error_code_t (*set_service_status)(auth_adaptor_plugin_context_h context,
+                                                       const int service_id,
+                                                       const int status,
+                                                       void *request,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response);
+
+       auth_error_code_t (*get_msisdn)(auth_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       char **msisdn,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response);
+
+        auth_error_code_t (*get_service_status)(auth_adaptor_plugin_context_h context,
+                                                       const int service_id,
+                                                       void *request,
+                                                       int *status,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response);
+
+        auth_error_code_t (*get_service_policy)(auth_adaptor_plugin_context_h context,
+                                                       const int service_id,
+                                                       void *request,
+                                                       char **default_status,
+                                                       char **policy_feature,
+                                                       char **policy_version,
+                                                       char **policy_doc_url,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response);
+
+       auth_error_code_t (*get_server_info)(auth_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       GHashTable **server_info,
+                                                       auth_adaptor_error_code_h *error,
+                                                       void *response);
+
+       auth_error_code_t (*external_request)(auth_adaptor_plugin_context_h context,
+                                                       const char *api_uri,
+                                                       const unsigned char *req_bundle_raw,
+                                                       int req_len,
+                                                       unsigned char **res_bundle_raw,
+                                                       int *res_len,
+                                                       auth_adaptor_error_code_h *error);
+       // Optional end
+
+       // Mandatory
+       char *plugin_uri;       // package id
+       // Mandatory end
+
+} auth_adaptor_plugin_handle_t;
+typedef struct auth_adaptor_plugin_handle_s *auth_adaptor_plugin_handle_h;
+
+/**
+ * Callback function variable for service adaptor
+ */
+
+/*
+typedef void (*auth_adaptor_service_login_reply_cb)(char *imsi,
+                                               char *plugin_uri,
+                                               char *app_id,
+                                               char *msisdn,
+                                               void *response);
+*/
+
+/**
+* @brief Describes infromation about Callback Listener (referenced by Service Adaptor)
+*/
+typedef struct auth_adaptor_listener_s
+{
+/*
+       void (*login_reply)(char *imsi,
+                                                       char *plugin_uri,
+                                                       char *app_id,
+                                                       char *msisdn,
+                                                       void *response);
+*/
+} auth_adaptor_listener_t;
+/**
+* @brief The handle for Auth Adaptor Listener
+*/
+typedef struct auth_adaptor_listener_s *auth_adaptor_listener_h;
+
+
+/**
+ * Callback function variables for plugins
+ * These callbacks are expected to be support by plugins
+ */
+
+/**
+* @brief Callback for auth_adaptor_plugin_handle->login API (referenced by Auth Plugin)
+*
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   error_code      specifies Error code
+* @param[in]   response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return      void.
+* @pre  auth_adaptor_plugin_handle->login() will invoke this callback.
+* @see
+*/
+/*
+typedef void (*auth_adaptor_plugin_login_reply_cb)(auth_adaptor_plugin_context_h context,
+                                               auth_adaptor_error_code_h error_code,
+                                               void *response);
+*/
+/**
+* @brief Describes infromation about Callback Listener (referenced by Auth Plugin)
+*/
+typedef struct auth_adaptor_plugin_listener_s
+{
+       /*
+       auth_adaptor_plugin_login_reply_cb              auth_adaptor_login_reply;
+       */
+} auth_adaptor_plugin_listener_t;
+
+/**
+ * @brief Loads plugin from selected path
+ */
+EXPORT_API
+int auth_adaptor_load_plugin(auth_adaptor_h adaptor,
+                                               const char *plugin_path);
+
+
+// For 3rd party plugin packages
+EXPORT_API
+int auth_adaptor_load_plugin_from_package(auth_adaptor_h adaptor,
+                                               const char *package_id,
+                                               const char *plugin_path);
+
+/**
+ * @brief Unloads selected plugin
+ */
+EXPORT_API
+int auth_adaptor_unload_plugin(auth_adaptor_h adaptor,
+                                               auth_adaptor_plugin_h plugin);
+
+/**
+ * @brief Gets plugin name
+ */
+EXPORT_API
+void auth_adaptor_get_plugin_uri(auth_adaptor_plugin_h plugin, char **plugin_uri);
+
+/**
+ * @brief Destroy error code
+ */
+EXPORT_API
+void auth_adaptor_destroy_error_code(auth_adaptor_error_code_h *error_code);
+
+/**
+ * @brief Creates auth adaptor
+ */
+EXPORT_API
+auth_adaptor_h auth_adaptor_create(const char *plugins_dir);
+
+/**
+ * @brief Destroys auth adaptor. If auth adaptor was started it is stopped first.
+ */
+EXPORT_API
+void auth_adaptor_destroy(auth_adaptor_h adaptor);
+
+/**
+ * @brief Starts auth adaptor and loads plugins that were found in plugins search dir
+ * @brief specified in auth_adaptor_create
+ */
+EXPORT_API
+int auth_adaptor_start(auth_adaptor_h adaptor);
+
+/**
+ * @brief Stops auth adaptor.
+ */
+EXPORT_API
+int auth_adaptor_stop(auth_adaptor_h adaptor);
+
+/**
+ * @brief Registers plugin state listener
+ */
+EXPORT_API
+int auth_adaptor_register_listener(auth_adaptor_h adaptor,
+                                               auth_adaptor_listener_h listener);
+
+/**
+ * @brief Unregisters plugin state listener
+ */
+EXPORT_API
+int auth_adaptor_unregister_listener(auth_adaptor_h adaptor,
+                                               auth_adaptor_listener_h listener);
+
+/**
+ * @brief Creates plugin context.
+ */
+EXPORT_API
+auth_adaptor_plugin_context_h auth_adaptor_create_plugin_context(auth_adaptor_plugin_h plugin,
+                                               const char *user_id,
+                                               const char *user_password,
+                                               const char *app_id,
+                                               const char *app_secret,
+                                               const char *imsi,
+                                               const char *service_name);
+
+/**
+ * @brief Destroys plugin context.
+ */
+EXPORT_API
+void auth_adaptor_destroy_plugin_context(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context);
+
+/**
+ * @brief Gets plugin with specified unique name
+ */
+EXPORT_API
+auth_adaptor_plugin_h auth_adaptor_get_plugin_by_name(auth_adaptor_h adaptor,
+                                               const char *plugin_uri);
+
+/**
+ * @brief Gets plugins
+ */
+EXPORT_API
+GList *auth_adaptor_get_plugins(auth_adaptor_h adaptor);
+
+////////////////////////////////////////////////////////////
+// Adaptor get Element Functions
+////////////////////////////////////////////////////////////
+
+/*
+ * @brief      Get Access token allocated by 'strdup'(Use after 'auth_adaptor_login' function)
+ * @return : NULL or string(need free)
+ */
+EXPORT_API
+char *auth_adaptor_get_access_token_dup(auth_adaptor_plugin_context_h context);
+
+/*
+ * @brief      Get duid allocated by 'strdup' (Use after 'auth_adaptor_login' function)
+ * @return     NULL or string(need free)
+ */
+EXPORT_API
+char *auth_adaptor_get_uid_dup(auth_adaptor_plugin_context_h context);
+
+/*
+ * @brief      Get MSISDN allocated by 'strdup' (Use after 'auth_adaptor_login' function)
+ * @return     NULL or string(need free)
+ */
+EXPORT_API
+char *auth_adaptor_get_msisdn_dup(auth_adaptor_plugin_context_h context);
+
+////////////////////////////////////////////////////////////
+// Adaptor Plugin call Functions
+////////////////////////////////////////////////////////////
+
+/**
+* @brief Check Account Registration [Sync API]
+*
+* @param[in]   plugin          specifies Auth-adaptor Plugin handle
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   request         specifies Optional value for specific Plugin (Recommend Json Object format)
+* @param[out]  is_auth         specifies Registered Flag (Registered : 1, Not registered : 0)
+* @param[out]  error_code      specifies Error code
+* @param[out]  response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+auth_error_code_t auth_adaptor_is_auth(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               void *request,
+                                               int *is_auth,
+                                               auth_adaptor_error_code_h *error_code,
+                                               void *response);
+/**
+* @brief Request Access Token (included auth_adaptor_context) [Sync API]
+*
+* @param[in]   plugin          specifies Auth-adaptor Plugin handle
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   is_auth         specifies Registration Flag (Must be issued from "auth_adaptor_is_auth" Function)
+* @param[in]   request         specifies Optional value for specific Plugin (Recommend Json Object format)
+* @param[out]  error_code      specifies Error code
+* @param[out]  response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+auth_error_code_t auth_adaptor_login(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               int is_auth,
+                                               void *request,
+                                               auth_adaptor_error_code_h *error_code,
+                                               void *response);
+
+/**
+* @brief Request for Refreshing Access Token (included auth_adaptor_context) [Sync API]
+*
+* @param[in]   plugin          specifies Auth-adaptor Plugin handle
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   request         specifies Optional value for specific Plugin (Recommend Json Object format)
+* @param[out]  error_code      specifies Error code
+* @param[out]  response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+auth_error_code_t auth_adaptor_login_refresh(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               void *request,
+                                               auth_adaptor_error_code_h *error_code,
+                                               void *response);
+
+/**
+* @brief Request Account Registration [Sync API]
+*
+* @param[in]   plugin          specifies Auth-adaptor Plugin handle
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   device_id       specifies Device Unique ID
+* @param[in]   request         specifies Optional value for specific Plugin (Recommend Json Object format)
+* @param[out]  error_code      specifies Error code
+* @param[out]  response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+auth_error_code_t auth_adaptor_join(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               const char *device_id,
+                                               void *request,
+                                               auth_adaptor_error_code_h *error_code,
+                                               void *response);
+
+/**
+* @brief Request Account Information (MSISDN) [Sync API]
+*
+* @param[in]   plugin          specifies Auth-adaptor Plugin handle
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   request         specifies Optional value for specific Plugin (Recommend Json Object format)
+* @param[out]  msisdn          specifies MSISDN
+* @param[out]  error_code      specifies Error code
+* @param[out]  response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+auth_error_code_t auth_adaptor_get_msisdn(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               void *request,
+                                               char **msisdn,
+                                               auth_adaptor_error_code_h *error_code,
+                                               void *response);
+
+/**
+* @brief Request Changing Service Status (Enable, Disable or etc...) [Sync API]
+*
+* @param[in]   plugin          specifies Auth-adaptor Plugin handle
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   service_id      specifies Service ID (The value is depended by Server)
+* @param[in]   status          specifies Service Status (The value is depended by Server)
+* @param[in]   request         specifies Optional value for specific Plugin (Recommend Json Object format)
+* @param[out]  error_code      specifies Error code
+* @param[out]  response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+auth_error_code_t auth_adaptor_set_service_status(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               const int service_id,
+                                               const int status,
+                                               void *request,
+                                               auth_adaptor_error_code_h *error_code,
+                                               void *response);
+
+/**
+* @brief Request Service Status [Sync API]
+*
+* @param[in]   plugin          specifies Auth-adaptor Plugin handle
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   service_id      specifies Service ID (The value is depended by Server)
+* @param[in]   request         specifies Optional value for specific Plugin (Recommend Json Object format)
+* @param[out]  status          specifies Service Status (The value is depended by Server)
+* @param[out]  error_code      specifies Error code
+* @param[out]  response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+auth_error_code_t auth_adaptor_get_service_status(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               const int service_id,
+                                               void *request,
+                                               int *status,
+                                               auth_adaptor_error_code_h *error_code,
+                                               void *response);
+
+/**
+* @brief Request Service Policy [Sync API]
+*
+* @param[in]   plugin          specifies Auth-adaptor Plugin handle
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   service_id      specifies Service ID (The value is depended by Server)
+* @param[in]   request         specifies Optional value for specific Plugin (Recommend Json Object format)
+* @param[in]   default_status  specifies Service default Status Policy
+* @param[in]   policy_feature  specifies Service Policy Feature
+* @param[in]   policy_version  specifies Service Policy Version
+* @param[in]   policy_doc_url  specifies Service Policy Document URL
+* @param[out]  error_code      specifies Error code
+* @param[out]  response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+auth_error_code_t auth_adaptor_get_service_policy(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               const int service_id,
+                                               void *request,
+                                               char **default_status,
+                                               char **policy_feature,
+                                               char **policy_version,
+                                               char **policy_doc_url,
+                                               auth_adaptor_error_code_h *error_code,
+                                               void *response);
+
+/**
+* @brief Request Permitted Server information for Account [Sync API]
+*
+* @param[in]   plugin          specifies Auth-adaptor Plugin handle
+* @param[in]   context         specifies Auth-adaptor Plugin context
+* @param[in]   request         specifies Optional value for specific Plugin (Recommend Json Object format)
+* @param[out]  server_info     specifies server information (URL, Scheme, Port)
+* @param[out]  error_code      specifies Error code
+* @param[out]  response        specifies Optional value from specific Plugin (Recommend Json Object format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in auth_error_code_e - AUTH_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+auth_error_code_t auth_adaptor_get_server_info(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               void *request,
+                                               GHashTable **server_info,
+                                               auth_adaptor_error_code_h *error_code,
+                                               void *response);
+
+EXPORT_API
+auth_error_code_t auth_adaptor_external_request(auth_adaptor_plugin_h plugin,
+                                               auth_adaptor_plugin_context_h context,
+                                               const char *api_uri,
+                                               const unsigned char *req_bundle_raw,
+                                               int req_len,
+                                               unsigned char **res_bundle_raw,
+                                               int *res_len,
+                                               auth_adaptor_error_code_h *error_code);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AUTH_ADAPTOR_H__ */
diff --git a/adaptor/contact-adaptor/contact-adaptor-log.h b/adaptor/contact-adaptor/contact-adaptor-log.h
new file mode 100644 (file)
index 0000000..6a93541
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+* Copyright (c) 2011 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 __CONTACT_ADAPTOR_LOG_H__
+#define __CONTACT_ADAPTOR_LOG_H__
+
+/**
+ *  HOW TO USE IT:
+ *  First you need to set platform logging on the device:
+ *
+ *    # dlogctrl set platformlog 1
+ *
+ *  After reboot you are able to see logs from this application, when you launch dlogutil with a proper filter e.g.:
+ *
+ *    # dlogutil CONTACT_ADAPTOR:D
+ *
+ *  You may use different logging levels as: D (debug), I (info), W (warning), E (error) or F (fatal).
+ *  Higher level messages are included by default e.g. dlogutil CLOUDBOX:W prints warnings but also errors and fatal messages.
+ */
+
+#include <unistd.h>
+#include <linux/unistd.h>
+
+/* These defines must be located before #include <dlog.h> */
+#define TIZEN_ENGINEER_MODE
+// TODO: Investigate why this macro is defined somewhere else
+#ifndef TIZEN_DEBUG_ENABLE
+#define TIZEN_DEBUG_ENABLE
+#endif
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+/* Literal to filter logs from dlogutil */
+#define LOG_TAG "CONTACT_ADAPTOR"
+
+#include <dlog.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+       /**
+        *  Colors of font
+        */
+#define FONT_COLOR_RESET      "\033[0m"
+#define FONT_COLOR_BLACK      "\033[30m"             /* Black */
+#define FONT_COLOR_RED        "\033[31m"             /* Red */
+#define FONT_COLOR_GREEN      "\033[32m"             /* Green */
+#define FONT_COLOR_YELLOW     "\033[33m"             /* Yellow */
+#define FONT_COLOR_BLUE       "\033[34m"             /* Blue */
+#define FONT_COLOR_PURPLE     "\033[35m"             /* Purple */
+#define FONT_COLOR_CYAN       "\033[36m"             /* Cyan */
+#define FONT_COLOR_WHITE      "\033[37m"             /* White */
+#define FONT_COLOR_BOLDBLACK  "\033[1m\033[30m"      /* Bold Black */
+#define FONT_COLOR_BOLDRED    "\033[1m\033[31m"      /* Bold Red */
+#define FONT_COLOR_BOLDGREEN  "\033[1m\033[32m"      /* Bold Green */
+#define FONT_COLOR_BOLDYELLOW "\033[1m\033[33m"      /* Bold Yellow */
+#define FONT_COLOR_BOLDBLUE   "\033[1m\033[34m"      /* Bold Blue */
+#define FONT_COLOR_BOLDPURPLE "\033[1m\033[35m"      /* Bold Purple */
+#define FONT_COLOR_BOLDCYAN   "\033[1m\033[36m"      /* Bold Cyan */
+#define FONT_COLOR_BOLDWHITE  "\033[1m\033[37m"      /* Bold White */
+
+       /**
+        *  Gets thread ID
+        */
+#define contact_adaptor_gettid() syscall(__NR_gettid)
+
+/**
+ *  @brief Macro for returning value if expression is satisfied
+ *  @param[in]  expr Expression to be checked
+ *  @param[out] val  Value to be returned when expression is true
+ */
+#define contact_adaptor_retv_if(expr, val) do { \
+            if(expr) { \
+                LOGE(FONT_COLOR_PURPLE"[%d]"FONT_COLOR_RESET, contact_adaptor_gettid());    \
+                return (val); \
+            } \
+        } while (0)
+
+/**
+ * @brief Prints debug messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define contact_adaptor_debug(fmt, arg...) do { \
+            LOGD(FONT_COLOR_GREEN"[%d]"fmt""FONT_COLOR_RESET, contact_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints info messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define contact_adaptor_info(fmt, arg...) do { \
+            LOGI(FONT_COLOR_BLUE"[%d]"fmt""FONT_COLOR_RESET, contact_adaptor_gettid() ,##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints warning messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define contact_adaptor_warning(fmt, arg...) do { \
+            LOGW(FONT_COLOR_YELLOW"[%d]"fmt""FONT_COLOR_RESET,contact_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints error messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define contact_adaptor_error(fmt, arg...) do { \
+            LOGE(FONT_COLOR_RED"[%d]"fmt""FONT_COLOR_RESET,contact_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints fatal messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define contact_adaptor_fatal(fmt, arg...) do { \
+            LOGF(FONT_COLOR_BOLDRED"[%d]"fmt""FONT_COLOR_RESET,contact_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints debug message on entry to particular function
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define contact_adaptor_debug_func(fmt, arg...) do { \
+            LOGD(FONT_COLOR_CYAN"[%d]"fmt""FONT_COLOR_RESET, contact_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+#define plugin_req_enter()                     do { \
+               contact_adaptor_info("[ENTER] plugin API call -)) -)) -)) -)) -)) -)) -)) -)) -)) -))"); \
+       } while (0)
+
+#define plugin_req_exit(ret, plugin, error)    do { \
+               contact_adaptor_info("[EXIT] plugin API called (%d) ((- ((- ((- ((- ((- ((- ((- ((- ((- ((-", (int)(ret)); \
+               if ((error)) { \
+                       if ((*error)) { \
+                               contact_adaptor_error("plugin issued error (%lld) (%s)", (long long int)((*error)->code), (char *)((*error)->msg)); \
+                               char *tem = g_strdup_printf("[PLUGIN_ERROR] URI(%s), MSG(%s)", (char *)((plugin)->handle->plugin_uri), (char *)((*error)->msg)); \
+                               if (tem) { \
+                                       free((*error)->msg); \
+                                       (*error)->msg = tem; \
+                               } \
+                       } \
+               } \
+       } while (0)
+
+#define plugin_req_exit_void()                 do { \
+               contact_adaptor_info("[EXIT] plugin API called ((- ((- ((- ((- ((- ((- ((- ((- ((- ((-"); \
+       } while (0)
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __CONTACT_ADAPTOR_LOG_H__ */
diff --git a/adaptor/contact-adaptor/contact-adaptor.c b/adaptor/contact-adaptor/contact-adaptor.c
new file mode 100644 (file)
index 0000000..2cf858c
--- /dev/null
@@ -0,0 +1,1749 @@
+/*
+* Copyright (c) 2011 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.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <glib.h>
+
+#include "contact-adaptor.h"
+#include "contact-adaptor-log.h"
+
+/**
+ * Contact adaptor plugin
+ */
+typedef struct contact_adaptor_plugin_s {
+       contact_adaptor_h                       adaptor;                /* Adaptor */
+       char                                    *path;                  /* Plugin library path */
+       contact_adaptor_plugin_handle_h         handle;                 /* Plugin handle */
+       void                                    *dl_handle;             /* Plugin library handle */
+       int                                     ref_counter;            /* Plugin reference counter */
+       GMutex                                  ref_counter_mutex;      /* Plugin reference counter mutex */
+       contact_adaptor_plugin_listener_h       plugin_listener;        /* Plugin callback listener */
+       GMutex                                  plugin_listener_mutex;  /* Plugin callback listener mutex */
+} contact_adaptor_plugin_t;
+
+/**
+ * Contact adaptor
+ */
+typedef struct contact_adaptor_s {
+       GMutex  contact_adaptor_mutex;          /* Adaptor mutex */
+       int     started;                        /* Started flag */
+       char    *plugins_dir;                   /* Plugins directory path */
+       GList   *plugins;                       /* List of loaded plugins */
+       GMutex  plugins_mutex;                  /* Plugin list mutex */
+       GList   *adaptor_listeners;             /* List of vservice channel listener (for now not effective) */
+       GMutex  adaptor_listeners_mutex;        /* Listener list mutex */
+} contact_adaptor_t;
+
+/**
+ * Creates plugin
+ */
+static contact_adaptor_plugin_h contact_adaptor_create_plugin(const char *plugin_path);
+
+/**
+ * Destroys plugin and deletes all resources associated with it
+ */
+static void contact_adaptor_destroy_plugin(contact_adaptor_plugin_h plugin);
+
+/**
+ * Loads plugins from selected directory
+ */
+static int contact_adaptor_load_plugins_from_directory(contact_adaptor_h adaptor,
+                                               const char *dir_path);
+
+/**
+ * Checks if plugin is loaded by selected plugin adaptor
+ */
+static int contact_adaptor_has_plugin(contact_adaptor_h adaptor,
+                                               contact_adaptor_plugin_h plugin);
+
+/**
+ * Increases adaptor's plugin references counter
+ */
+static void contact_adaptor_plugin_ref(contact_adaptor_plugin_h);
+
+/**
+ * Decreases adaptor's plugin references counter
+ */
+static void contact_adaptor_plugin_unref(contact_adaptor_plugin_h);
+
+/**
+ * On message received callback for service adaptor
+ */
+contact_adaptor_service_on_message_received_cb _service_adaptor_on_message_received = NULL;
+
+/**
+ * Callback on message received from plugin
+ */
+void
+contact_adaptor_on_message_received(void *user_data)
+{
+       if (NULL != _service_adaptor_on_message_received) {
+               _service_adaptor_on_message_received(user_data);
+       }
+}
+
+/* /////////////////////////////////////////////////////////////
+   // Plugin create / destroy / ref. count / get plugin name
+   ///////////////////////////////////////////////////////////// */
+
+/**
+* Creates plugin
+*/
+static contact_adaptor_plugin_h contact_adaptor_create_plugin(const char *plugin_path)
+{
+       contact_adaptor_debug("Create plugin");
+
+       if (NULL == plugin_path) {
+               contact_adaptor_error("Invalid argument");
+               return NULL;
+       }
+
+       void *dl_handle = dlopen(plugin_path, RTLD_LAZY);
+       if (NULL == dl_handle) {
+               contact_adaptor_error("Could not load plugin %s: %s", plugin_path, dlerror());
+               return NULL;
+       }
+
+       contact_adaptor_plugin_handle_h (*get_adaptee_handle)(void) = NULL;
+
+       get_adaptee_handle = (contact_adaptor_plugin_handle_h (*)(void))(dlsym(dl_handle, "create_plugin_handle"));
+       if (NULL == get_adaptee_handle) {
+               dlclose(dl_handle);
+               contact_adaptor_error("Could not get function pointer to create_plugin_handle");
+               return NULL;
+       }
+
+       plugin_req_enter();
+       contact_adaptor_plugin_handle_h handle = get_adaptee_handle();
+       plugin_req_exit_void();
+
+       if (NULL == handle) {
+               dlclose(dl_handle);
+               contact_adaptor_error("Could not get adaptee handle");
+               return NULL;
+       }
+
+       contact_adaptor_plugin_h plugin = (contact_adaptor_plugin_h) calloc(1, sizeof(contact_adaptor_plugin_t));
+       if (NULL == plugin) {
+               dlclose(dl_handle);
+               contact_adaptor_error("Could not create plugin object");
+               return NULL;
+       }
+
+       contact_adaptor_plugin_listener_h listener =
+               (contact_adaptor_plugin_listener_h) calloc(1, sizeof(contact_adaptor_plugin_listener_t));
+       if (NULL == listener) {
+               free(plugin);
+               dlclose(dl_handle);
+               contact_adaptor_error("Could not create listener object");
+               return NULL;
+       }
+
+       plugin->path = g_strdup(plugin_path);
+       plugin->handle = handle;
+       plugin->dl_handle = dl_handle;
+       plugin->ref_counter = 0;
+
+       g_mutex_init(&plugin->ref_counter_mutex);
+       g_mutex_init(&plugin->plugin_listener_mutex);
+
+       listener->_on_message_received  = contact_adaptor_on_message_received;
+
+       plugin_req_enter();
+       plugin->handle->set_listener(listener);
+       plugin_req_exit_void();
+
+       g_mutex_lock(&plugin->plugin_listener_mutex);
+       plugin->plugin_listener = listener;
+       g_mutex_unlock(&plugin->plugin_listener_mutex);
+
+       return plugin;
+}
+
+/**
+* Destroys plugin and deletes all resources associated with it
+*/
+static void contact_adaptor_destroy_plugin(contact_adaptor_plugin_h plugin)
+{
+       contact_adaptor_debug("Destroy plugin");
+
+       if (NULL == plugin) {
+               contact_adaptor_error("Invalid argument");
+               return;
+       }
+
+       if (NULL != plugin->handle) {
+               plugin->handle->destroy_handle(plugin->handle);
+
+               g_mutex_lock(&plugin->plugin_listener_mutex);
+               plugin_req_enter();
+               plugin->handle->unset_listener();
+               plugin_req_exit_void();
+               g_mutex_unlock(&plugin->plugin_listener_mutex);
+
+               plugin->handle = NULL;
+       }
+
+       if (NULL != plugin->dl_handle) {
+               dlclose(plugin->dl_handle);
+               plugin->dl_handle = NULL;
+       }
+
+       free(plugin->path);
+       plugin->path = NULL;
+
+       free(plugin);
+}
+
+/**
+* Loads plugins from selected directory
+*/
+static int contact_adaptor_load_plugins_from_directory(contact_adaptor_h adaptor,
+                                               const char *dir_path)
+{
+       contact_adaptor_debug("Load plugins from directory");
+
+       char *plugin_path = NULL;
+       DIR *dir = NULL;
+       struct dirent dir_entry, *result = NULL;
+
+       if ((NULL == adaptor) || (NULL == dir_path)) {
+               contact_adaptor_error("Invalid argument");
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       dir = opendir(dir_path);
+       if (NULL == dir) {
+               contact_adaptor_error("Could not open dir path (%s)", dir_path);
+               return CONTACT_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       int ret = CONTACT_ADAPTOR_ERROR_NONE;
+       while (0 == (readdir_r(dir, &dir_entry, &result))) {
+
+               if (NULL == result) {
+                       contact_adaptor_error("Could not open directory %s", plugin_path);
+                       break;
+               }
+
+               if (dir_entry.d_type & DT_DIR) {
+                       continue;
+               }
+
+               plugin_path = g_strconcat(dir_path, "/", dir_entry.d_name, NULL);
+               contact_adaptor_plugin_h plugin = contact_adaptor_create_plugin(plugin_path);
+
+               if (NULL != plugin) {
+                       contact_adaptor_debug("Loaded plugin: %s", plugin_path);
+                       plugin->adaptor = adaptor;
+                       contact_adaptor_plugin_ref(plugin);
+                       g_mutex_lock(&adaptor->plugins_mutex);
+                       adaptor->plugins = g_list_append(adaptor->plugins, plugin);
+                       g_mutex_unlock(&adaptor->plugins_mutex);
+               } else {
+                       contact_adaptor_error("Could not load plugin %s", plugin_path);
+               }
+
+               free(plugin_path);
+               plugin_path = NULL;
+       }
+
+       contact_adaptor_debug("End load plugins from directory");
+       closedir(dir);
+       return ret;
+}
+
+/**
+* Checks if plugin is loaded by selected plugin adaptor
+*/
+static int contact_adaptor_has_plugin(contact_adaptor_h adaptor,
+                                               contact_adaptor_plugin_h plugin)
+{
+       contact_adaptor_debug("Find plugin in plugin list");
+
+       if ((NULL == adaptor) || (NULL == plugin)) {
+               contact_adaptor_error("Invalid argument");
+               return 0;
+       }
+
+       int result = 0;
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       if (NULL != g_list_find(adaptor->plugins, plugin)) {
+               result = 1;
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return result;
+}
+
+/**
+* Increases adaptor's plugin references counter
+*/
+static void contact_adaptor_plugin_ref(contact_adaptor_plugin_h plugin)
+{
+       contact_adaptor_debug("Increase plugin reference count");
+
+       if (NULL == plugin) {
+               contact_adaptor_error("Invalid argument");
+               return;
+       }
+
+       g_mutex_lock(&plugin->ref_counter_mutex);
+       plugin->ref_counter = plugin->ref_counter + 1;
+       contact_adaptor_info("ref_counter: %d", plugin->ref_counter);
+       g_mutex_unlock(&plugin->ref_counter_mutex);
+}
+
+/**
+* Decreases adaptor's plugin references counter
+*/
+static void contact_adaptor_plugin_unref(contact_adaptor_plugin_h plugin)
+{
+       contact_adaptor_debug("Decrease plugin reference count");
+
+       if (NULL == plugin) {
+               contact_adaptor_error("Invalid argument");
+               return ;
+       }
+
+       int should_destroy = 0;
+
+       g_mutex_lock(&plugin->ref_counter_mutex);
+       plugin->ref_counter = plugin->ref_counter - 1;
+       contact_adaptor_info("ref_counter: %d", plugin->ref_counter);
+       if (0 >= plugin->ref_counter) {
+               should_destroy = 1;
+       }
+       g_mutex_unlock(&plugin->ref_counter_mutex);
+
+       if (should_destroy) {
+               contact_adaptor_debug("Plugin is being destroyed");
+               contact_adaptor_destroy_plugin(plugin);
+       }
+}
+
+/* //////////////////////////////////////////////////////
+   // Mandatory: External adaptor management function
+   ////////////////////////////////////////////////////// */
+
+/**
+* @brief Creates Contact Adaptor.
+*
+* @param[in]    plugin_dir      specifies directory path where plugins are stored
+* @return       contact_adaptor_h on success, otherwise NULL value
+*/
+contact_adaptor_h contact_adaptor_create(const char *plugins_dir)
+{
+       contact_adaptor_warning("Create contact adaptor");
+
+       contact_adaptor_h contact_adaptor = (contact_adaptor_h) malloc(sizeof(contact_adaptor_t));
+       if (NULL == contact_adaptor) {
+               return NULL;
+       }
+
+       contact_adaptor->started = 0;
+       contact_adaptor->plugins_dir = strdup(plugins_dir);
+
+       g_mutex_init(&contact_adaptor->contact_adaptor_mutex);
+       g_mutex_init(&contact_adaptor->plugins_mutex);
+       g_mutex_init(&contact_adaptor->adaptor_listeners_mutex);
+
+       g_mutex_lock(&contact_adaptor->adaptor_listeners_mutex);
+       contact_adaptor->adaptor_listeners = NULL;
+       g_mutex_unlock(&contact_adaptor->adaptor_listeners_mutex);
+
+       g_mutex_lock(&contact_adaptor->plugins_mutex);
+       contact_adaptor->plugins = NULL;
+       g_mutex_unlock(&contact_adaptor->plugins_mutex);
+
+       return contact_adaptor;
+}
+
+/**
+* @brief Destroys contact adaptor. If contact adaptor was started it is stopped first.
+*
+* @param[in]   adaptor         specifies contact adaptor handle to be destroyed
+* @return      void
+*/
+void contact_adaptor_destroy(contact_adaptor_h adaptor)
+{
+       contact_adaptor_warning("Destroy contact adaptor");
+
+       if (NULL == adaptor) {
+               contact_adaptor_error("Invalid argument");
+               return ;
+       }
+
+       g_mutex_lock(&adaptor->contact_adaptor_mutex);
+       if (adaptor->started) {
+               contact_adaptor_error("Contact adaptor is running. Forcing stop before destroy");
+               contact_adaptor_stop(adaptor);
+       }
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       if (NULL != adaptor->plugins) {
+               g_list_free_full(adaptor->plugins, (GDestroyNotify) contact_adaptor_plugin_unref);
+               adaptor->plugins = NULL;
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+       if (NULL != adaptor->adaptor_listeners) {
+               g_list_free(adaptor->adaptor_listeners);
+               adaptor->adaptor_listeners = NULL;
+       }
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+
+       _service_adaptor_on_message_received    = NULL;
+
+       free(adaptor->plugins_dir);
+       adaptor->plugins_dir = NULL;
+
+       g_mutex_unlock(&adaptor->contact_adaptor_mutex);
+
+       free(adaptor);
+}
+
+/**
+* @brief Starts contact adaptor and loads plugins that are found in contact_adaptor_create().
+*
+* @param[in]    adaptor                specifies contact adaptor handle
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+int contact_adaptor_start(contact_adaptor_h adaptor)
+{
+       contact_adaptor_warning("Start contact adaptor");
+
+       if (NULL == adaptor) {
+               contact_adaptor_error("Invalid argument");
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->contact_adaptor_mutex);
+       int result = CONTACT_ADAPTOR_ERROR_NONE;
+       if (adaptor->started) {
+               contact_adaptor_error("Contact adaptor is already started");
+               result = CONTACT_ADAPTOR_ERROR_START;
+       } else {
+               adaptor->started = 1;
+               result = contact_adaptor_load_plugins_from_directory(adaptor, adaptor->plugins_dir);
+               if (CONTACT_ADAPTOR_ERROR_NONE != result) {
+                       adaptor->started = 0;
+                       contact_adaptor_error("Could not load plugins from directory");
+               } else {
+                       contact_adaptor_debug("Contact adaptor started successfully");
+               }
+       }
+       g_mutex_unlock(&adaptor->contact_adaptor_mutex);
+
+       return result;
+}
+
+/**
+* @brief Stops contact adaptor.
+*
+* @param[in]    adaptor                specifies contact adaptor handle
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+int contact_adaptor_stop(contact_adaptor_h adaptor)
+{
+       contact_adaptor_warning("Stop contact adaptor");
+
+       if (NULL == adaptor) {
+               contact_adaptor_error("Invalid argument");
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->contact_adaptor_mutex);
+       int result = CONTACT_ADAPTOR_ERROR_NONE;
+       if (!adaptor->started) {
+               result = CONTACT_ADAPTOR_ERROR_START;
+       } else {
+               if (NULL != adaptor->plugins) {
+                       g_mutex_lock(&adaptor->plugins_mutex);
+                       g_list_free_full(adaptor->plugins, (GDestroyNotify) contact_adaptor_plugin_unref);
+                       adaptor->plugins = NULL;
+                       g_mutex_unlock(&adaptor->plugins_mutex);
+               }
+               adaptor->started = 0;
+               contact_adaptor_debug("Contact adaptor stopped");
+       }
+
+       g_mutex_unlock(&adaptor->contact_adaptor_mutex);
+       return result;
+}
+
+/**
+* @brief Registers plugin state listener
+*
+* @param[in]    adaptor                specifies contact adaptor handle
+* @param[in]    listener       specifies contact adaptor listener handle
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+int contact_adaptor_register_listener(contact_adaptor_h adaptor,
+                                               contact_adaptor_listener_h listener)
+{
+       contact_adaptor_warning("Register contact adaptor listener");
+
+       if ((NULL == adaptor) || (NULL == listener)) {
+               contact_adaptor_error("Invalid argument");
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+
+       adaptor->adaptor_listeners = g_list_append(adaptor->adaptor_listeners, listener);
+
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+
+       _service_adaptor_on_message_received =
+                       (contact_adaptor_service_on_message_received_cb) listener->_on_message_received;
+
+       return CONTACT_ADAPTOR_ERROR_NONE;
+}
+
+/**
+* @brief Unregisters plugin state listener
+*
+* @param[in]    adaptor                specifies contact adaptor handle
+* @param[in]    listener       specifies contact adaptor listener handle
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+int contact_adaptor_unregister_listener(contact_adaptor_h adaptor,
+                                               contact_adaptor_listener_h listener)
+{
+       contact_adaptor_warning("Deregister contact adaptor listener");
+
+       if ((NULL == adaptor) || (NULL == listener)) {
+               contact_adaptor_error("Invalid argument");
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+
+       if (NULL == g_list_find(adaptor->adaptor_listeners, listener)) {
+               g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+               contact_adaptor_error("Could not find listener");
+               return CONTACT_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       adaptor->adaptor_listeners = g_list_remove(adaptor->adaptor_listeners, listener);
+
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+
+       _service_adaptor_on_message_received    = NULL;
+
+       return CONTACT_ADAPTOR_ERROR_NONE;
+}
+
+/* //////////////////////////////////////////////////////
+   // Plugin context create / destroy
+   ////////////////////////////////////////////////////// */
+
+/**
+* @brief Creates plugin context
+*
+* @param[in]    plugin         specifies contact adaptor plugin handle
+* @param[in]    duid           specifies device unique ID
+* @param[in]    access_token   specifies access token issued by Auth Adaptor
+* @return       contact_adaptor_plugin_context_h on success, otherwise NULL value
+*/
+contact_adaptor_plugin_context_h contact_adaptor_create_plugin_context(contact_adaptor_plugin_h plugin,
+                                               const char *duid,
+                                               const char *access_token,
+                                               const char *service_name)
+{
+       contact_adaptor_warning("Create plugin context");
+
+       if ((NULL == plugin) || (NULL == duid) || (NULL == access_token) || (NULL == service_name)) {
+               contact_adaptor_error("Invalid argument: %s, %s", duid, access_token);
+               return NULL;
+       }
+
+       if (NULL != plugin->handle) {
+               contact_adaptor_plugin_context_h plugin_context = NULL;
+
+               plugin_req_enter();
+               plugin->handle->create_context(&plugin_context, duid, access_token);
+               plugin_req_exit_void();
+
+               plugin_context->plugin_uri = strdup(plugin->handle->plugin_uri);
+               plugin_context->service_name = strdup(service_name);
+               return plugin_context;
+       } else {
+               contact_adaptor_error("Plugin handle is null");
+       }
+
+       return NULL;
+}
+
+/**
+* @brief Destroys plugin context.
+*
+* @param[in]    plugin         specifies contact adaptor plugin handle
+* @param[in]    context                specifies contact adaptor plugin context handle
+* @return       void
+*/
+void contact_adaptor_destroy_plugin_context(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h plugin_context)
+{
+       contact_adaptor_warning("Destroy plugin context");
+
+       if ((NULL == plugin) || (NULL == plugin_context)) {
+               contact_adaptor_error("Invalid argument");
+               return;
+       }
+
+       if (NULL != plugin->handle) {
+               free(plugin_context->plugin_uri);
+               plugin_context->plugin_uri = NULL;
+               free(plugin_context->service_name);
+               plugin_context->service_name = NULL;
+
+               plugin_req_enter();
+               plugin->handle->destroy_context(plugin_context);
+               plugin_req_exit_void();
+       } else {
+               contact_adaptor_error("Plugin handle is null");
+       }
+}
+
+/* //////////////////////////////////////////////////////
+   // Get plugin by plugin name
+   ////////////////////////////////////////////////////// */
+
+/**
+* @brief Gets plugin with specified unique name
+*
+* @param[in]    adaptor                specifies contact adaptor handle
+* @param[in]    plugin_name     specifies plugin name to be searched for
+* @return       contact_adaptor_plugin_h on success, otherwise NULL value
+*/
+contact_adaptor_plugin_h contact_adaptor_get_plugin_by_name(contact_adaptor_h adaptor,
+                                               const char *plugin_name)
+{
+       contact_adaptor_warning("Get plugin by name: %s", plugin_name);
+
+       if ((NULL == adaptor) || (NULL == plugin_name)) {
+               contact_adaptor_error("Invalid argument");
+               return NULL;
+       }
+
+       contact_adaptor_plugin_h plugin = NULL;
+       g_mutex_lock(&adaptor->plugins_mutex);
+       int count = g_list_length(adaptor->plugins);
+       int i = 0;
+       for (i = 0; i < count; i++) {
+               contact_adaptor_plugin_h temp_plugin = g_list_nth_data(adaptor->plugins, i);
+               if (NULL != temp_plugin) {
+                       if (0 == strcmp(temp_plugin->handle->plugin_uri, plugin_name)) {
+                               contact_adaptor_plugin_ref(temp_plugin);
+                               plugin = temp_plugin;
+                               contact_adaptor_debug("Plugin is found by name");
+                               g_mutex_unlock(&adaptor->plugins_mutex);
+                               return plugin;
+                       }
+               }
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       if (NULL == plugin) {
+               contact_adaptor_debug("Plugin is not found by name");
+       }
+
+       return plugin;
+}
+
+/* //////////////////////////////////////////////////////
+   // Plugin load / unload / get plugin list
+   ////////////////////////////////////////////////////// */
+
+/**
+* @brief Loads plugin from selected path
+*
+* @param[in]    adaptor         specifies contact adaptor handle
+* @param[in]    plugin_path     specifies plugin's saved path
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+int contact_adaptor_load_plugin(contact_adaptor_h adaptor,
+                                               const char *plugin_path)
+{
+       contact_adaptor_warning("Load plugin by plugin path: %s", plugin_path);
+
+       if ((NULL == adaptor) || (NULL == plugin_path)) {
+               contact_adaptor_error("Invalid argument");
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (!adaptor->started) {
+               contact_adaptor_error("Contact adaptor is not started");
+               return CONTACT_ADAPTOR_ERROR_START;
+       }
+
+       contact_adaptor_plugin_h plugin = contact_adaptor_create_plugin(plugin_path);
+       if (NULL == plugin) {
+               contact_adaptor_error("Could not load plugin %s", plugin_path);
+               return CONTACT_ADAPTOR_ERROR_CREATE;
+       }
+
+       plugin->adaptor = adaptor;
+       contact_adaptor_plugin_ref(plugin);
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       adaptor->plugins = g_list_append(adaptor->plugins, plugin);
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return CONTACT_ADAPTOR_ERROR_NONE;
+}
+
+/**
+* @brief Unloads selected plugin
+*
+* @param[in]    adaptor         specifies contact adaptor handle
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+int contact_adaptor_unload_plugin(contact_adaptor_h adaptor,
+                                               contact_adaptor_plugin_h plugin)
+{
+       contact_adaptor_warning("Unload plugin");
+
+       if ((NULL == adaptor) || (NULL == plugin)) {
+               contact_adaptor_error("Invalid argument");
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (!adaptor->started) {
+               contact_adaptor_error("Contact adaptor is not started");
+               return CONTACT_ADAPTOR_ERROR_START;
+       }
+
+       if (!contact_adaptor_has_plugin(adaptor, plugin)) {
+               contact_adaptor_error("Contact adaptor has no plugin");
+               return CONTACT_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       plugin->adaptor = NULL;
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       adaptor->plugins = g_list_remove(adaptor->plugins, plugin);
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       contact_adaptor_plugin_unref(plugin);
+
+       return CONTACT_ADAPTOR_ERROR_NONE;
+}
+
+/**
+* @brief Get plugin list of contact adaptor handle has
+*
+* @param[in]    adaptor         specifies contact adaptor handle
+* @return       GList pointer on success, otherwise NULL value
+*/
+GList *contact_adaptor_get_plugins(contact_adaptor_h adaptor)
+{
+       contact_adaptor_warning("Get plugin list");
+
+       if (NULL == adaptor) {
+               contact_adaptor_error("Invalid argument");
+               return NULL;
+       }
+
+       GList *plugins = NULL;
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       int plugins_count = g_list_length(adaptor->plugins);
+       int i;
+       for (i = 0; i < plugins_count; i++) {
+               contact_adaptor_plugin_h plugin = g_list_nth_data(adaptor->plugins, i);
+               if (NULL != plugin) {
+                       contact_adaptor_plugin_ref(plugin);
+                       plugins = g_list_append(plugins, plugin);
+               }
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return plugins;
+}
+
+/**
+* @brief Refresh access token was issued from auth-adaptor
+*
+* @param[in]   context                 specifies Contact Adaptor Plugin Context handle
+* @param[in]   new_access_token        specifies New access token
+* @return      contact_adaptor_error_code_h on success, otherwise NULL value
+*/
+EXPORT_API
+contact_error_code_t contact_adaptor_refresh_access_token(contact_adaptor_plugin_context_h context,
+                                               const char *new_access_token)
+{
+       if ((NULL == context) || (NULL == new_access_token) || (0 >= strlen(new_access_token))) {
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+       contact_adaptor_debug("New access token : %s", new_access_token);
+
+       free(context->access_token);
+       context->access_token = NULL;
+       context->access_token = strdup(new_access_token);
+
+       return CONTACT_ADAPTOR_ERROR_NONE;
+}
+
+EXPORT_API
+contact_error_code_t contact_adaptor_refresh_uid(contact_adaptor_plugin_context_h context,
+                                               const char *new_uid)
+{
+       if ((NULL == context) || (NULL == new_uid) || (0 >= strlen(new_uid))) {
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+       contact_adaptor_debug("New uid : %s", new_uid);
+
+       free(context->duid);
+       context->duid = NULL;
+       context->duid = strdup(new_uid);
+
+       return CONTACT_ADAPTOR_ERROR_NONE;
+}
+
+
+/* //////////////////////////////////////////////////////
+   // Create / Destroy error code
+   ////////////////////////////////////////////////////// */
+
+/**
+* @brief Create error code
+*
+* @param[in]    code            specifies error code number
+* @param[in]    msg             specifies error message
+* @return       contact_adaptor_error_code_h on success, otherwise NULL value
+*/
+contact_adaptor_error_code_h contact_adaptor_create_error_code(const int64_t code,
+                                               const char *msg)
+{
+       if (NULL == msg) {
+               return NULL;
+       }
+
+       contact_adaptor_error_code_h error_code = (contact_adaptor_error_code_h) malloc(sizeof(contact_adaptor_error_code_t));
+       if (NULL == error_code) {
+               return NULL;
+       }
+
+       error_code->code = code;
+       error_code->msg = strdup(msg);
+
+       return error_code;
+}
+
+/**
+* @brief Destroy error code
+*
+* @param[in]    error_code      specifies error code handle
+* @return       void
+*/
+void contact_adaptor_destroy_error_code(contact_adaptor_error_code_h *error_code)
+{
+       if (NULL == *error_code) {
+               return;
+       }
+
+       if (NULL != (*error_code)->msg) {
+               free((*error_code)->msg);
+               (*error_code)->msg = NULL;
+       }
+
+       free(*error_code);
+       *error_code = NULL;
+}
+
+void __contact_adaptor_destroy_char_array(char **arr, unsigned int len)
+{
+       if ((NULL != arr) && (0U < len)) {
+               for (int i = 0; i < len; i++) {
+                       free(arr[i]);
+               }
+               free(arr);
+       }
+}
+
+EXPORT_API
+void contact_adaptor_destroy_contact_req_s(contact_adaptor_contact_req_h req)
+{
+       if (NULL != req) {
+               if ((req->cts != NULL) && (0U < req->cts_len)) {
+                       for (int i = 0; i < req->cts_len; i++) {
+                               if (NULL != req->cts[i]) {
+                                       free(req->cts[i]->tp);
+                                       free(req->cts[i]->id);
+                                       free(req->cts[i]->pn);
+                                       free(req->cts[i]->nm);
+                                       free(req->cts[i]->cc);
+                               }
+                               free(req->cts[i]);
+                       }
+                       free(req->cts);
+               }
+               free(req);
+       }
+}
+
+EXPORT_API
+void contact_adaptor_destroy_contact_res_s(contact_adaptor_contact_res_h res)
+{
+       if (NULL == res) {
+               return;
+       } else if ((res->cts == NULL) || (0U == res->cts_len)) {
+               free(res);
+               return;
+       }
+
+       for (int i = 0; i < res->cts_len; i++) {
+               if (NULL != res->cts[i]) {
+                       free(res->cts[i]->duid);
+                       free(res->cts[i]->id);
+                       free(res->cts[i]->msisdn);
+                       free(res->cts[i]->ty);
+                       free(res->cts[i]->cc);
+                       free(res->cts[i]->pn);
+                       free(res->cts[i]->nm);
+                       /*
+                          if ((NULL != res->cts[i]->evnt) && (0U > res->cts[i]->evnt_len)) {
+                          for (int j = 0; j < res->cts[i]->evnt_len; j++) {
+                          free(res->cts[i]->evnt[j]);
+                          }
+                          free(res->cts[i]->evnt);
+                          }
+                        */
+                       __contact_adaptor_destroy_char_array(res->cts[i]->evnt, res->cts[i]->evnt_len);
+                       /* free(res->cts[i]->img);*/
+
+                       __contact_adaptor_destroy_char_array(res->cts[i]->adrs, res->cts[i]->adrs_len);
+                       __contact_adaptor_destroy_char_array(res->cts[i]->mail, res->cts[i]->mail_len);
+                       /*
+                          if ((NULL != res->cts[i]->adrs) && (0U > res->cts[i]->adrs_len)) {
+                          for (int j = 0; j < res->cts[i]->adrs_len; j++) {
+                          free(res->cts[i]->adrs[j]);
+                          }
+                          free(res->cts[i]->adrs);
+                          }
+                          if ((NULL != res->cts[i]->mail) && (0U > res->cts[i]->mail_len)) {
+                          for (int j = 0; j < res->cts[i]->mail_len; j++) {
+                          free(res->cts[i]->mail[j]);
+                          }
+                          free(res->cts[i]->mail);
+                          }
+                        */
+                       free(res->cts[i]->org);
+                       free(res->cts[i]->prsc);
+                       free(res->cts[i]->status);
+               }
+               free(res->cts[i]);
+       }
+       free(res->cts);
+       free(res);
+}
+
+EXPORT_API
+void contact_adaptor_destroy_profile_req_s(contact_adaptor_profile_req_h req)
+{
+       if (NULL == req) {
+               return;
+       }
+
+       free(req->cc);
+       free(req->pn);
+       free(req->nm);
+       __contact_adaptor_destroy_char_array(req->evnt, req->evnt_len);
+       free(req->img);
+       __contact_adaptor_destroy_char_array(req->adrs, req->adrs_len);
+       __contact_adaptor_destroy_char_array(req->mail, req->mail_len);
+       free(req->org);
+       free(req->prsc);
+       free(req->status);
+
+       free(req);
+}
+
+EXPORT_API
+void contact_adaptor_destroy_profile_res_s(contact_adaptor_profile_res_h res)
+{
+       if (NULL == res) {
+               return;
+       }
+
+       free(res->nm);
+       free(res->img);
+       free(res->prsc);
+       free(res->status);
+
+       free(res);
+}
+
+EXPORT_API
+void contact_adaptor_destroy_file_path_s(contact_adaptor_file_path_h path)
+{
+       if (NULL == path) {
+               return;
+       }
+
+       __contact_adaptor_destroy_char_array(path->file_paths, path->file_paths_len);
+
+       free(path);
+}
+
+EXPORT_API
+void contact_adaptor_destroy_privacy_req_s(contact_adaptor_privacy_req_h req)
+{
+       if (NULL == req) {
+               return;
+       }
+
+       if ((NULL != req->cts) && (0U < req->cts_len)) {
+               for (int i = 0; i < req->cts_len; i++) {
+                       free(req->cts[i]->cc);
+                       free(req->cts[i]->pn);
+                       free(req->cts[i]);
+               }
+               free(req->cts);
+       }
+       free(req);
+}
+
+EXPORT_API
+void contact_adaptor_destroy_privacy_res_s(contact_adaptor_privacy_res_h res)
+{
+       free(res);
+}
+
+EXPORT_API
+void contact_adaptor_destroy_presence_info_s(contact_adaptor_presence_info_h info)
+{
+       if (NULL == info) {
+               return;
+       }
+
+       free(info->prsc);
+       free(info->status);
+       free(info);
+}
+
+/* //////////////////////////////////////////////////////
+   // Contact Adaptor External APIs
+   ////////////////////////////////////////////////////// */
+
+/**
+* @brief Set server information for Contact Plugin
+*
+* @param[in]    plugin         specifies Contact Adaptor Plugin handle
+* @param[in]    context        specifies Contact Adaptor Plugin Context handle
+* @param[in]    server_info    specifies server information for Contact Plugin
+* @param[in]    request        specifies optional parameter
+* @param[out]   error          specifies error code
+* @param[out]   response       specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in contact_error_code_t - CONTACT_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+contact_error_code_t contact_adaptor_set_server_info(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context,
+                                               GHashTable *server_info,
+                                               void *user_data,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               contact_adaptor_error("Invalid argument");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                               "Invalid argument (plugin or context)");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               contact_adaptor_error("Plugin handle is null");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                               "Plugin handle is null");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       contact_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->set_server_info(context, server_info, user_data, error, server_data);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+}
+
+/**
+* @brief Resets contact information in Contact server and upload native contact information of device to
+* the server
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor contact API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor contact API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+contact_error_code_t contact_adaptor_new_contact_list(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context,
+                                               contact_adaptor_contact_req_h request,
+                                               void *user_data,
+                                               contact_adaptor_contact_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data)
+{
+       contact_adaptor_warning("New contact list");
+
+       if ((NULL == plugin) || (NULL == context) || (NULL == request)) {
+               contact_adaptor_error("Invalid argument");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                       "Invalid argument (plugin or context or request)");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               contact_adaptor_error("Plugin handle is null");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                       "Plugin handle is null");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       contact_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->new_contact_list(context, request, user_data, response, error, server_data);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+}
+
+/**
+* @brief Synchronized native contact information of device with contact server according to type
+* "type" field of each contact
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor contact API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor contact API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+contact_error_code_t contact_adaptor_set_contact_list(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context,
+                                               contact_adaptor_contact_req_h request,
+                                               void *user_data,
+                                               contact_adaptor_contact_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data)
+{
+       contact_adaptor_warning("Set contact list");
+
+       if ((NULL == plugin) || (NULL == context) || (NULL == request)) {
+               contact_adaptor_error("Invalid argument");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                       "Invalid argument (plugin or context or request)");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               contact_adaptor_error("Plugin handle is null");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                       "Plugin handle is null");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       contact_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->set_contact_list(context, request, user_data,
+                                               response, error, server_data);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+}
+
+/**
+* @brief Gets profile and service registration information of each contact
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor contact API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor contact API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+contact_error_code_t contact_adaptor_get_contact_infos_latest(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context,
+                                               contact_adaptor_contact_req_h request,
+                                               void *user_data,
+                                               contact_adaptor_contact_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data)
+{
+       contact_adaptor_warning("Get contact infos latest");
+
+       if ((NULL == plugin) || (NULL == context)) {
+               contact_adaptor_error("Invalid argument");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                       "Invalid argument (plugin or context)");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               contact_adaptor_error("Plugin handle is null");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                       "Plugin handle is null");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       contact_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->get_contact_infos_latest(context, request, user_data,
+                                               response, error, server_data);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+}
+
+/**
+* @brief Gets profile and service registration information of contact that have been updated since
+* last update
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor contact API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor contact API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+contact_error_code_t contact_adaptor_get_contact_infos_polling(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context,
+                                               contact_adaptor_contact_req_h request,
+                                               void *user_data,
+                                               contact_adaptor_contact_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data)
+{
+       contact_adaptor_warning("Get contact infos polling");
+
+       if ((NULL == plugin) || (NULL == context) || (NULL == request)) {
+               contact_adaptor_error("Invalid argument");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                       "Invalid argument (plugin or context or request)");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               contact_adaptor_error("Plugin handle is null");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                       "Plugin handle is null");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       contact_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->get_contact_infos_polling(context, request, user_data,
+                                               response, error, server_data);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+}
+
+/**
+* @brief Sets or updates device's profile to server
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor profile API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor profile API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+contact_error_code_t contact_adaptor_set_me_profile_with_push(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context,
+                                               contact_adaptor_profile_req_h request,
+                                               void *user_data,
+                                               contact_adaptor_profile_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data)
+{
+       contact_adaptor_warning("Set me profile with push");
+
+       if ((NULL == plugin) || (NULL == context) || (NULL == request)) {
+               contact_adaptor_error("Invalid argument");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                       "Invalid argument (plugin or context or request)");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               contact_adaptor_error("Plugin handle is null");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                       "Plugin handle is null");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       contact_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->set_me_profile_with_push(context, request, user_data,
+                                               response, error, server_data);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+}
+
+/**
+* @brief Gets the profile information of a contact which is correspondent with country code and phone number
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor profile API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor profile API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+contact_error_code_t contact_adaptor_get_profile(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context,
+                                               contact_adaptor_profile_req_h request,
+                                               void *user_data,
+                                               contact_adaptor_profile_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data)
+{
+       contact_adaptor_warning("Get profile");
+
+       if ((NULL == plugin) || (NULL == context) || (NULL == request)) {
+               contact_adaptor_error("Invalid argument");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                       "Invalid argument (plugin or context or request)");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               contact_adaptor_error("Plugin handle is null");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                       "Plugin handle is null");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       contact_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->get_profile(context, request, user_data, response, error, server_data);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+}
+
+/**
+* @brief Uploads profile image meta to file server
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor profile API image file request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor profile API image file response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+contact_error_code_t contact_adaptor_set_me_profile_image_meta_with_push(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context,
+                                               contact_adaptor_contact_image_h *imgs,
+                                               unsigned int imgs_len,
+                                               void *user_data,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data)
+{
+       contact_adaptor_warning("Set me profile image meta with push");
+
+       if ((NULL == plugin) || (NULL == context) || (NULL == imgs) || (0U == imgs_len)) {
+               contact_adaptor_error("Invalid argument");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                       "Invalid argument (plugin or context or request)");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               contact_adaptor_error("Plugin handle is null");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                       "Plugin handle is null");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       contact_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->set_me_profile_image_meta_with_push(context, imgs, imgs_len, user_data,
+                                               error, server_data);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+}
+
+/**
+* @brief Deletes profile image meta from profile server
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor profile API image file request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor profile API image file response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+contact_error_code_t contact_adaptor_delete_me_profile_image_meta_with_push(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context,
+                                               void *user_data,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data)
+{
+       contact_adaptor_warning("Delete me profile image meta with push");
+
+       if ((NULL == plugin) || (NULL == context)) {
+               contact_adaptor_error("Invalid argument");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                       "Invalid argument (plugin or context or request)");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               contact_adaptor_error("Plugin handle is null");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                       "Plugin handle is null");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       contact_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->delete_me_profile_image_meta_with_push(context, user_data,
+                                               error, server_data);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+}
+
+/**
+* @brief Sets the level of privacy
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor privacy API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor privacy API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+contact_error_code_t contact_adaptor_set_me_profile_privacy(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context,
+                                               contact_adaptor_privacy_req_h request,
+                                               void *user_data,
+                                               contact_adaptor_privacy_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data)
+{
+       contact_adaptor_warning("Set me profile privacy");
+
+       if ((NULL == plugin) || (NULL == context) || (NULL == request)) {
+               contact_adaptor_error("Invalid argument");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                       "Invalid argument (plugin or context or request)");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               contact_adaptor_error("Plugin handle is null");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                       "Plugin handle is null");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       contact_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->set_me_profile_privacy(context, request, user_data,
+                                               response, error, server_data);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+}
+
+/**
+* @brief Gets my profile's privacy level
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor privacy API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor privacy API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+contact_error_code_t contact_adaptor_get_me_profile_privacy(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context,
+                                               contact_adaptor_privacy_req_h request,
+                                               void *user_data,
+                                               contact_adaptor_privacy_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data)
+{
+       contact_adaptor_warning("Get me profile privacy");
+
+       if ((NULL == plugin) || (NULL == context)) {
+               contact_adaptor_error("Invalid argument");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                       "Invalid argument (plugin or context or request)");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               contact_adaptor_error("Plugin handle is null");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                       "Plugin handle is null");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       contact_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->get_me_profile_privacy(context, request, user_data,
+                                               response, error, server_data);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+}
+
+/**
+* @brief Sets my presence information
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor presence API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor presence API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+contact_error_code_t contact_adaptor_set_me_presence_with_push(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context,
+                                               contact_adaptor_presence_info_h request,
+                                               void *user_data,
+                                               contact_adaptor_presence_info_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data)
+{
+       contact_adaptor_warning("Set me presence with push");
+
+       if ((NULL == plugin) || (NULL == context) || (NULL == request)) {
+               contact_adaptor_error("Invalid argument");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                       "Invalid argument (plugin or context or request)");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               contact_adaptor_error("Plugin handle is null");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                       "Plugin handle is null");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       contact_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->set_me_presence_with_push(context, request, user_data,
+                                               response, error, server_data);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+}
+
+/**
+* @brief Sets my presence on/off information
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor presence API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor presence API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+contact_error_code_t contact_adaptor_set_me_presence_on_off_with_push(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context,
+                                               contact_adaptor_presence_info_h request,
+                                               void *user_data,
+                                               contact_adaptor_presence_info_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data)
+{
+       contact_adaptor_warning("Set me presence on off with push");
+
+       if ((NULL == plugin) || (NULL == context) || (NULL == request)) {
+               contact_adaptor_error("Invalid argument");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                       "Invalid argument (plugin or context or request)");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               contact_adaptor_error("Plugin handle is null");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                       "Plugin handle is null");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       contact_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->set_me_presence_on_off_with_push(context, request, user_data,
+                                                               response, error, server_data);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+}
+
+EXPORT_API
+contact_error_code_t contact_adaptor_set_me_profile_type(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context,
+                                               int req_type,
+                                               void *user_data,
+                                               char **url,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data)
+{
+       contact_adaptor_info("%s", __FUNCTION__);
+
+       if ((NULL == plugin) || (NULL == context)) {
+               contact_adaptor_error("Invalid argument");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                       "Invalid argument (plugin or context or request)");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               contact_adaptor_error("Plugin handle is null");
+
+               *error = contact_adaptor_create_error_code((int64_t) CONTACT_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                       "Plugin handle is null");
+
+               return CONTACT_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       char *_url = NULL;
+       contact_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->set_me_profile_type(context, req_type, user_data,
+                                                               &_url, error, server_data);
+       plugin_req_exit(ret, plugin, error);
+
+       contact_adaptor_debug("url : %s", _url);
+       if (NULL != url) {
+               *url = _url;
+       } else {
+               free(_url);
+       }
+
+       return ret;
+}
+
+
diff --git a/adaptor/contact-adaptor/contact-adaptor.h b/adaptor/contact-adaptor/contact-adaptor.h
new file mode 100644 (file)
index 0000000..8d23f9b
--- /dev/null
@@ -0,0 +1,968 @@
+/*
+* Copyright (c) 2011 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 __CONTACT_ADAPTOR_H__
+#define __CONTACT_ADAPTOR_H__
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+#include <glib.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+/**
+* @brief Contact Adaptor error code
+*/
+typedef enum contact_error_code_e
+{
+       CONTACT_ADAPTOR_ERROR_NONE                     =  0,
+       CONTACT_ADAPTOR_ERROR_LAUNCH                    = 1,    /**< 1 ~ 99: internal error*/
+        CONTACT_ADAPTOR_ERROR_INIT                      = 2,
+        CONTACT_ADAPTOR_ERROR_DEINIT                    = 3,
+        CONTACT_ADAPTOR_ERROR_CREATE                    = 4,
+        CONTACT_ADAPTOR_ERROR_DESTROY                   = 5,
+        CONTACT_ADAPTOR_ERROR_START                     = 6,
+        CONTACT_ADAPTOR_ERROR_STOP                      = 7,
+        CONTACT_ADAPTOR_ERROR_CONNECT                   = 8,
+        CONTACT_ADAPTOR_ERROR_DISCONNECT                = 9,
+        CONTACT_ADAPTOR_ERROR_NOT_FOUND                 = 10,
+        CONTACT_ADAPTOR_ERROR_CORRUPTED                 = 11,
+        CONTACT_ADAPTOR_ERROR_UNSUPPORTED               = 12,
+        CONTACT_ADAPTOR_ERROR_INVALID_HANDLE            = 13,
+        CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT          = 14,
+        CONTACT_ADAPTOR_ERROR_INVALID_ARGUMENT_TYPE     = 15,
+        CONTACT_ADAPTOR_ERROR_NOT_AUTHORIZED            = 16,
+        CONTACT_ADAPTOR_ERROR_ADAPTOR_INTERNAL          = 17,
+        CONTACT_ADAPTOR_ERROR_PLUGIN_INTERNAL           = 18,
+        CONTACT_ADAPTOR_ERROR_SERVER_INTERNAL           = 19,
+        CONTACT_ADAPTOR_ERROR_DBUS                      = 20,
+        CONTACT_ADAPTOR_ERROR_CALLBACK_TIME_OUT         = 21,
+       CONTACT_ADAPTOR_ERROR_MAX
+} contact_error_code_t;
+
+
+typedef enum _contact_plugin_internal_error_code_e
+{
+       CONTACT_PLUGIN_ERROR_HTTP_BAD_REQUEST           = 400,
+       CONTACT_PLUGIN_ERROR_HTTP_UNAUTHORIZED          = 401,
+       CONTACT_PLUGIN_ERROR_HTTP_FORBIDDEN             = 403,
+       CONTACT_PLUGIN_ERROR_HTTP_NOT_FOUND             = 404,
+       CONTACT_PLUGIN_ERROR_HTTP_METHOD_NOT_ALLOWED    = 405,
+
+       CONTACT_PLUGIN_ERROR_CURL_COULDNT_CONNECT       = 601,
+       CONTACT_PLUGIN_ERROR_CURL_TIME_OUT              = 602,
+       CONTACT_PLUGIN_ERROR_CURL_ETC                   = 698,
+       CONTACT_PLUGIN_ERROR_CURL_UNKNOWN               = 699,
+
+       CONTACT_PLUGIN_ERROR_URL                        = 997,
+       CONTACT_PLUGIN_ERROR_ETC                        = 998,
+       CONTACT_PLUGIN_ERROR_UNKNOWN                    = 999,
+} contact_plugin_internal_error_code_e;
+
+
+
+
+/**
+* @brief Contact Adaptor plugin handle
+*/
+typedef struct contact_adaptor_plugin_s *contact_adaptor_plugin_h;
+
+/**
+* @brief Contact Adaptor handle
+*/
+typedef struct contact_adaptor_s *contact_adaptor_h;
+
+/**
+* @brief Contact Adaptor plugin context structure
+*/
+typedef struct contact_adaptor_plugin_context_s
+{
+       char    *duid;          /**< header: access control >*/
+       char    *access_token;  /**< header: access control >*/
+       void    *plugin_info;   /**< plugin's own context >*/
+
+       // Adaptor define
+       char    *plugin_uri;
+       char    *service_name;
+
+} contact_adaptor_plugin_context_t;
+typedef struct contact_adaptor_plugin_context_s *contact_adaptor_plugin_context_h;
+
+/**
+* @brief Contact Adaptor error code
+*/
+typedef struct contact_adaptor_error_code_s
+{
+       int64_t code;
+       char    *msg;
+
+} contact_adaptor_error_code_t;
+typedef struct contact_adaptor_error_code_s *contact_adaptor_error_code_h;
+
+/**
+* @brief Contact Adaptor contact API information request format
+*/
+typedef struct contact_adaptor_contact_info_req_s
+{
+       char    *tp;    /**< mandatory >*/
+       char    *id;    /**< mandatory >*/
+       char    *pn;    /**< mandatory >*/
+       char    *nm;    /**< mandatory >*/
+
+       char    *cc;    /**< optional >*/
+
+} contact_adaptor_contact_info_req_t;
+typedef struct contact_adaptor_contact_info_req_s *contact_adaptor_contact_info_req_h;
+
+/**
+* @brief Contact Adaptor contact API request format
+*/
+typedef struct contact_adaptor_contact_req_s
+{
+       long long int                           tt;
+       contact_adaptor_contact_info_req_h      *cts;
+       unsigned int                            cts_len;
+
+} contact_adaptor_contact_req_t;
+typedef struct contact_adaptor_contact_req_s *contact_adaptor_contact_req_h;
+
+typedef enum
+{
+       CONTACT_ADAPTOR_REQUEST_SET     = 1,
+       CONTACT_ADAPTOR_REQUEST_DEL     = 2,
+} contact_adaptor_request_type_e;
+
+typedef struct contact_adaptor_contact_image_s
+{
+       int     req_type;
+       int     no;     /**< mandatory >*/
+       char    *img;   /**< mandatory >*/
+} contact_adaptor_contact_image_t;
+typedef struct contact_adaptor_contact_image_s *contact_adaptor_contact_image_h;
+
+/**
+* @brief Contact Adaptor contact API information response format
+*/
+typedef struct contact_adaptor_contact_info_res_s
+{
+       char            *duid;          /**< mandatory >*/
+       char            *id;            /**< mandatory >*/
+       char            *msisdn;        /**< mandatory >*/
+
+       char            *ty;            /**< optional >*/
+       char            *cc;            /**< optional >*/
+       char            *pn;            /**< optional >*/
+       char            *nm;            /**< optional >*/
+       char            **evnt;         /**< optional >*/
+       unsigned int    evnt_len;       /**< optional >*/
+       contact_adaptor_contact_image_h *imgs;  /**< optional >*/
+       unsigned int    imgs_len;       /**< optional >*/
+       char            **adrs;         /**< optional >*/
+       unsigned int    adrs_len;       /**< optional >*/
+       char            **mail;         /**< optional >*/
+       unsigned int    mail_len;       /**< optional >*/
+       char            *org;           /**< optional >*/
+       char            *prsc;          /**< optional >*/
+       char            *status;        /**< optional >*/
+       unsigned int    sids;           /**< optional >*/
+       int             type;           /**< optional >*/
+       char            *url;           /**< optional >*/
+} contact_adaptor_contact_info_res_t;
+typedef struct contact_adaptor_contact_info_res_s *contact_adaptor_contact_info_res_h;
+
+/**
+* @brief Contact Adaptor contact API response format
+*/
+typedef struct contact_adaptor_contact_res_s
+{
+        long long int                          tt;
+        contact_adaptor_contact_info_res_h     *cts;
+        unsigned int                           cts_len;
+
+} contact_adaptor_contact_res_t;
+typedef struct contact_adaptor_contact_res_s *contact_adaptor_contact_res_h;
+
+/**
+* @brief Contact Adaptor profile API request format
+*/
+typedef struct contact_adaptor_profile_req_s
+{
+       char*   cc;
+       char*   pn;
+       char*   nm;
+       char**  evnt;
+       unsigned int    evnt_len;
+       char*   img;
+       char**  adrs;
+       unsigned int    adrs_len;
+       char**  mail;
+       unsigned int    mail_len;
+       char*   org;
+       char*   prsc;
+       char*   status;
+
+} contact_adaptor_profile_req_t;
+typedef struct contact_adaptor_profile_req_s *contact_adaptor_profile_req_h;
+
+/**
+* @brief Contact Adaptor profile API response format
+*/
+typedef struct contact_adaptor_profile_res_s
+{
+       char*   nm;
+       char*   img;
+       char*   prsc;
+       char*   status;
+
+} contact_adaptor_profile_res_t;
+typedef struct contact_adaptor_profile_res_s *contact_adaptor_profile_res_h;
+
+/**
+* @brief Contact Adaptor profile API image file path format
+*/
+typedef struct contact_adaptor_file_path_s
+{
+       char**  file_paths;
+       unsigned int file_paths_len;
+
+} contact_adaptor_file_path_t;
+typedef struct contact_adaptor_file_path_s *contact_adaptor_file_path_h;
+
+/**
+* @brief Contact Adaptor privacy API information request format
+*/
+typedef struct contact_adaptor_privacy_info_req_s
+{
+       char*   cc;
+       char*   pn;
+
+} contact_adaptor_privacy_info_req_t;
+typedef struct contact_adaptor_privacy_info_req_s *contact_adaptor_privacy_info_req_h;
+
+/**
+* @brief Contact Adaptor privacy API request format
+*/
+typedef struct contact_adaptor_privacy_req_s
+{
+       unsigned int    lvl;
+       contact_adaptor_privacy_info_req_h*     cts;
+       unsigned int    cts_len;
+
+} contact_adaptor_privacy_req_t;
+typedef struct contact_adaptor_privacy_req_s *contact_adaptor_privacy_req_h;
+
+/**
+* @brief Contact Adaptor privacy API response format
+*/
+typedef struct contact_adaptor_privacy_res_s
+{
+       unsigned int    lvl;
+       unsigned int    prscon;
+
+} contact_adaptor_privacy_res_t;
+typedef struct contact_adaptor_privacy_res_s *contact_adaptor_privacy_res_h;
+
+/**
+* @brief Contact Adaptor presence API information format
+*/
+typedef struct contact_adaptor_presence_info_s
+{
+       char            *prsc;
+       unsigned int    prscon;
+       char            *status;
+
+} contact_adaptor_presence_info_t;
+typedef struct contact_adaptor_presence_info_s *contact_adaptor_presence_info_h;
+
+/**
+* @brief Callback on pushed message received for Service Adaptor (not in use)
+*
+* @param[in]   user_data       specifies user_data passed to message received API
+* @return      void
+*/
+typedef void(*contact_adaptor_service_on_message_received_cb)(void *user_data);
+
+/**
+* @brief Callback on pushed message received for contact plugin (not in use)
+*
+* @param[in]   user_data       specifies user_data passed to message received API
+* @return      void
+*/
+typedef void(*contact_adaptor_plugin_on_message_received_cb)(void *user_data);
+
+/**
+* @brief Contact Adaptor listener for Service Adaptor
+*/
+typedef struct contact_adaptor_listener_s
+{
+        contact_adaptor_service_on_message_received_cb _on_message_received;
+
+} contact_adaptor_listener_t;
+typedef struct contact_adaptor_listener_s *contact_adaptor_listener_h;
+
+/**
+* @brief Contact Adaptor listener for plugins
+*/
+typedef struct contact_adaptor_plugin_listener_s
+{
+        contact_adaptor_plugin_on_message_received_cb _on_message_received;
+
+} contact_adaptor_plugin_listener_t;
+typedef struct contact_adaptor_plugin_listener_s *contact_adaptor_plugin_listener_h;
+
+/**
+* @brief Contact Adaptor plugin handle
+*/
+typedef struct contact_adaptor_plugin_handle_s
+{
+       /**< mandatory >*/
+       contact_error_code_t (*create_context)(contact_adaptor_plugin_context_h *context,
+                                               const char *duid,
+                                               const char *access_token);
+
+       /**< mandatory >*/
+       contact_error_code_t (*destroy_context)(contact_adaptor_plugin_context_h context);
+
+       /**< mandatory >*/
+       contact_error_code_t (*destroy_handle)(struct contact_adaptor_plugin_handle_s *handle);
+
+       /**< mandatory >*/
+       contact_error_code_t (*set_listener)(contact_adaptor_plugin_listener_h listener);
+
+       /**< mandatory >*/
+       contact_error_code_t (*unset_listener)(void);
+
+       /**< optional >*/
+       contact_error_code_t (*set_server_info)(contact_adaptor_plugin_context_h context,
+                                               GHashTable *server_info,
+                                               void *user_data,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+       /**< optional >*/
+       contact_error_code_t (*new_contact_list)(contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_contact_req_h request,
+                                               void *user_data,
+                                                contact_adaptor_contact_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+       /**< optional >*/
+       contact_error_code_t (*set_contact_list)(contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_contact_req_h request,
+                                               void *user_data,
+                                                contact_adaptor_contact_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+       /**< optional >*/
+       contact_error_code_t (*get_contact_infos_latest)(contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_contact_req_h request,
+                                               void *user_data,
+                                                contact_adaptor_contact_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+       /**< optional >*/
+        contact_error_code_t (*get_contact_infos_polling)(contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_contact_req_h request,
+                                               void *user_data,
+                                                contact_adaptor_contact_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+       /**< optional >*/
+        contact_error_code_t (*set_me_profile_with_push)(contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_profile_req_h request,
+                                               void *user_data,
+                                                contact_adaptor_profile_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+       /**< optional >*/
+        contact_error_code_t (*get_profile)(contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_profile_req_h request,
+                                               void *user_data,
+                                                contact_adaptor_profile_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+       /**< optional >*/
+        contact_error_code_t (*set_me_profile_image_meta_with_push)
+                                               (contact_adaptor_plugin_context_h context,
+                                               contact_adaptor_contact_image_h *imgs,
+                                               unsigned int imgs_len,
+                                               void *user_data,
+                                                contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+       /**< optional >*/
+        contact_error_code_t (*delete_me_profile_image_meta_with_push)
+                                               (contact_adaptor_plugin_context_h context,
+                                               void *user_data,
+                                                contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+       /**< optional >*/
+        contact_error_code_t (*set_me_profile_privacy)(contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_privacy_req_h request,
+                                               void *user_data,
+                                                contact_adaptor_privacy_res_h *response,
+                                                contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+       /**< optional >*/
+        contact_error_code_t (*get_me_profile_privacy)(contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_privacy_req_h request,
+                                               void *user_data,
+                                                contact_adaptor_privacy_res_h *response,
+                                                contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+       /**< optional >*/
+        contact_error_code_t (*set_me_presence_with_push)(contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_presence_info_h request,
+                                               void *user_data,
+                                                contact_adaptor_presence_info_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+       /**< optional >*/
+        contact_error_code_t (*set_me_presence_on_off_with_push)(contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_presence_info_h request,
+                                               void *user_data,
+                                                contact_adaptor_presence_info_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+       contact_error_code_t (*set_me_profile_type)(contact_adaptor_plugin_context_h context,
+                                               int req_type,
+                                               void *user_data,
+                                               char **url,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+       /**< mandatory >*/
+       char *plugin_uri;       // get from config file
+
+} contact_adaptor_plugin_handle_t;
+typedef struct contact_adaptor_plugin_handle_s *contact_adaptor_plugin_handle_h;
+
+/**
+* @brief Creates Contact Adaptor.
+*
+* @param[in]    plugin_dir      specifies directory path where plugins are stored
+* @return       contact_adaptor_h on success, otherwise NULL value
+*/
+EXPORT_API
+contact_adaptor_h contact_adaptor_create(const char *plugins_dir);
+
+/**
+* @brief Destroys contact adaptor. If contact adaptor was started it is stopped first.
+*
+* @param[in]   adaptor         specifies contact adaptor handle to be destroyed
+* @return      void
+*/
+EXPORT_API
+void contact_adaptor_destroy(contact_adaptor_h adaptor);
+
+/**
+* @brief Starts contact adaptor and loads plugins that are found in contact_adaptor_create().
+*
+* @param[in]   adaptor         specifies contact adaptor handle
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+int contact_adaptor_start(contact_adaptor_h adaptor);
+
+/**
+* @brief Stops contact adaptor.
+*
+* @param[in]    adaptor                specifies contact adaptor handle
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+int contact_adaptor_stop(contact_adaptor_h adaptor);
+
+/**
+* @brief Registers plugin state listener
+*
+* @param[in]    adaptor                specifies contact adaptor handle
+* @param[in]   listener        specifies contact adaptor listener handle
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+int contact_adaptor_register_listener(contact_adaptor_h adaptor,
+                                               contact_adaptor_listener_h listener);
+
+/**
+* @brief Unregisters plugin state listener
+*
+* @param[in]    adaptor                specifies contact adaptor handle
+* @param[in]    listener       specifies contact adaptor listener handle
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+int contact_adaptor_unregister_listener(contact_adaptor_h adaptor,
+                                               contact_adaptor_listener_h listener);
+
+/**
+* @brief Creates plugin context
+*
+* @param[in]   plugin          specifies contact adaptor plugin handle
+* @param[in]   duid            specifies device unique ID
+* @param[in]   access_token    specifies access token issued by Auth Adaptor
+* @return      contact_adaptor_plugin_context_h on success, otherwise NULL value
+*/
+EXPORT_API
+contact_adaptor_plugin_context_h contact_adaptor_create_plugin_context(contact_adaptor_plugin_h plugin,
+                                               const char *duid,
+                                               const char *access_token,
+                                               const char *service_name);
+
+/**
+* @brief Destroys plugin context.
+*
+* @param[in]   plugin          specifies contact adaptor plugin handle
+* @param[in]   context         specifies contact adaptor plugin context handle
+* @return      void
+*/
+EXPORT_API
+void contact_adaptor_destroy_plugin_context(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context);
+
+/**
+* @brief Gets plugin with specified unique name
+*
+* @param[in]    adaptor         specifies contact adaptor handle
+* @param[in]   plugin_name     specifies plugin name to be searched for
+* @return      contact_adaptor_plugin_h on success, otherwise NULL value
+*/
+EXPORT_API
+contact_adaptor_plugin_h contact_adaptor_get_plugin_by_name(contact_adaptor_h adaptor,
+                                               const char *plugin_uri);
+
+
+/**
+* @brief Loads plugin from selected path
+*
+* @param[in]   adaptor         specifies contact adaptor handle
+* @param[in]   plugin_path     specifies plugin's saved path
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+int contact_adaptor_load_plugin(contact_adaptor_h adaptor,
+                                               const char *plugin_path);
+
+/**
+* @brief Unloads selected plugin
+*
+* @param[in]   adaptor         specifies contact adaptor handle
+* @param[in]   plugin          specifies contact adaptor plugin handle
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+int contact_adaptor_unload_plugin(contact_adaptor_h adaptor,
+                                               contact_adaptor_plugin_h plugin);
+
+/**
+* @brief Get plugin list of contact adaptor handle has
+*
+* @param[in]   adaptor         specifies contact adaptor handle
+* @return      GList pointer on success, otherwise NULL value
+*/
+EXPORT_API
+GList *contact_adaptor_get_plugins(contact_adaptor_h adaptor);
+
+/**
+* @brief Gets plugin name
+*
+* @param[in]   plugin          specifies contact adaptor plugin handle
+* @return      const char pointer on success, otherwise NULL value
+*/
+EXPORT_API
+const char* contact_adaptor_get_plugin_name(contact_adaptor_plugin_h plugin);
+
+/**
+ * @brief Refresh access token was issued from auth-adaptor
+ *
+ * @param[in]  context                 specifies Contact Adaptor Plugin Context handle
+ * @param[in]  new_access_token        specifies New access token
+ * @return     contact_adaptor_error_code_h on success, otherwise NULL value
+*/
+EXPORT_API
+contact_error_code_t contact_adaptor_refresh_access_token(contact_adaptor_plugin_context_h context,
+                                               const char *new_access_token);
+
+/**
+ * @brief Refresh unique id was issued from auth-adaptor
+ *
+ * @param[in]  context                 specifies Contact Adaptor Plugin Context handle
+ * @param[in]  new_access_token        specifies New access token
+ * @return     contact_adaptor_error_code_h on success, otherwise NULL value
+*/
+EXPORT_API
+contact_error_code_t contact_adaptor_refresh_uid(contact_adaptor_plugin_context_h context,
+                                               const char *new_uid);
+
+/**
+* @brief Create error code
+*
+* @param[in]   code            specifies error code number
+* @param[in]   msg             specifies error message
+* @return      contact_adaptor_error_code_h on success, otherwise NULL value
+*/
+EXPORT_API
+contact_adaptor_error_code_h contact_adaptor_create_error_code(const int64_t code,
+                                               const char *msg);
+
+/**
+* @brief Destroy error code
+*
+* @param[in]   error_code      specifies error code handle
+* @return      void
+*/
+EXPORT_API
+void contact_adaptor_destroy_error_code(contact_adaptor_error_code_h *error_code);
+
+EXPORT_API
+void contact_adaptor_destroy_contact_req_s(contact_adaptor_contact_req_h req);
+
+EXPORT_API
+void contact_adaptor_destroy_contact_res_s(contact_adaptor_contact_res_h res);
+
+EXPORT_API
+void contact_adaptor_destroy_profile_req_s(contact_adaptor_profile_req_h req);
+
+EXPORT_API
+void contact_adaptor_destroy_profile_res_s(contact_adaptor_profile_res_h res);
+
+EXPORT_API
+void contact_adaptor_destroy_file_path_s(contact_adaptor_file_path_h path);
+
+EXPORT_API
+void contact_adaptor_destroy_privacy_req_s(contact_adaptor_privacy_req_h req);
+
+EXPORT_API
+void contact_adaptor_destroy_privacy_res_s(contact_adaptor_privacy_res_h res);
+
+EXPORT_API
+void contact_adaptor_destroy_presence_info_s(contact_adaptor_presence_info_h info);
+
+/**
+ * @brief Set server information for Contact Plugin
+ *
+ * @param[in]    plugin                specifies Contact Adaptor Plugin handle
+ * @param[in]    context       specifies Contact Adaptor Plugin Context handle
+ * @param[in]    server_info   specifies server information for Contact Plugin
+ * @param[in]    user_data     specifies optional parameter
+ * @param[out]   error         specifies error code
+ * @param[out]   server_data   specifies optional parameter
+ * @return 0 on success, otherwise a positive error value
+ * @retval error code defined in contact_error_code_t - CONTACT_ADAPTOR_ERROR_NONE if Successful
+ */
+EXPORT_API
+contact_error_code_t contact_adaptor_set_server_info(contact_adaptor_plugin_h plugin,
+                                       contact_adaptor_plugin_context_h context,
+                                       GHashTable *server_info,
+                                       void *user_data,
+                                       contact_adaptor_error_code_h *error,
+                                       void **server_data);
+
+/**
+* @brief Resets contact information in Contact server and upload native contact information of device to
+* the server
+*
+* @param[in]   plugin          specifies contact adaptor plugin handle
+* @param[in]   context         specifies contact adaptor plugin context handle
+* @param[in]   request         specifies contact adaptor contact API request handle
+* @param[in]   user_data       specifies user side arbitrary data
+* @param[out]  response        specifies contact adaptor contact API response handle
+* @param[out]  error           specifies returned error code handle
+* @param[out]  server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+contact_error_code_t contact_adaptor_new_contact_list(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_contact_req_h request,
+                                               void *user_data,
+                                                contact_adaptor_contact_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+/**
+* @brief Synchronized native contact information of device with contact server according to type
+* "type" field of each contact
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor contact API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor contact API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+contact_error_code_t contact_adaptor_set_contact_list(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_contact_req_h request,
+                                               void *user_data,
+                                                contact_adaptor_contact_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+/**
+* @brief Gets profile and service registration information of each contact
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor contact API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor contact API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+contact_error_code_t contact_adaptor_get_contact_infos_latest(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_contact_req_h request,
+                                               void *user_data,
+                                                contact_adaptor_contact_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+/**
+* @brief Gets profile and service registration information of contact that have been updated since
+* last update
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor contact API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor contact API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+contact_error_code_t contact_adaptor_get_contact_infos_polling(contact_adaptor_plugin_h plugin,
+                                               contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_contact_req_h request,
+                                               void *user_data,
+                                                contact_adaptor_contact_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+/**
+* @brief Sets or updates device's profile to server
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor profile API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor profile API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+contact_error_code_t contact_adaptor_set_me_profile_with_push(contact_adaptor_plugin_h plugin,
+                                                contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_profile_req_h request,
+                                               void *user_data,
+                                                contact_adaptor_profile_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+/**
+* @brief Gets the profile information of a contact which is correspondent with country code and phone number
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor profile API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor profile API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+contact_error_code_t contact_adaptor_get_profile(contact_adaptor_plugin_h plugin,
+                                                contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_profile_req_h request,
+                                               void *user_data,
+                                                contact_adaptor_profile_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+/**
+* @brief Uploads profile image meta to file server
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor profile API image file request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor profile API image file response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+contact_error_code_t contact_adaptor_set_me_profile_image_meta_with_push(contact_adaptor_plugin_h plugin,
+                                                contact_adaptor_plugin_context_h context,
+                                               contact_adaptor_contact_image_h *imgs,
+                                               unsigned int imgs_len,
+                                               void *user_data,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+/**
+* @brief Deletes profile image meta from profile server
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor profile API image file request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor profile API image file response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+contact_error_code_t contact_adaptor_delete_me_profile_image_meta_with_push(
+                                               contact_adaptor_plugin_h plugin,
+                                                contact_adaptor_plugin_context_h context,
+                                               void *user_data,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+/**
+* @brief Sets the level of privacy
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor privacy API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor privacy API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+contact_error_code_t contact_adaptor_set_me_profile_privacy(contact_adaptor_plugin_h plugin,
+                                                contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_privacy_req_h request,
+                                               void *user_data,
+                                                contact_adaptor_privacy_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+/**
+* @brief Gets my profile's privacy level
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor privacy API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor privacy API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+contact_error_code_t contact_adaptor_get_me_profile_privacy(contact_adaptor_plugin_h plugin,
+                                                contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_privacy_req_h request,
+                                               void *user_data,
+                                                contact_adaptor_privacy_res_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+/**
+* @brief Sets my presence information
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor presence API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor presence API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+contact_error_code_t contact_adaptor_set_me_presence_with_push(contact_adaptor_plugin_h plugin,
+                                                contact_adaptor_plugin_context_h context,
+                                               contact_adaptor_presence_info_h request,
+                                               void *user_data,
+                                               contact_adaptor_presence_info_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+/**
+* @brief Sets my presence on/off information
+*
+* @param[in]    plugin          specifies contact adaptor plugin handle
+* @param[in]    context         specifies contact adaptor plugin context handle
+* @param[in]    request         specifies contact adaptor presence API request handle
+* @param[in]    user_data       specifies user side arbitrary data
+* @param[out]   response        specifies contact adaptor presence API response handle
+* @param[out]   error           specifies returned error code handle
+* @param[out]   server_data     specifies server side arbitrary data
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in contact_error_code_e - CONTACT_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+contact_error_code_t contact_adaptor_set_me_presence_on_off_with_push(contact_adaptor_plugin_h plugin,
+                                                contact_adaptor_plugin_context_h context,
+                                                contact_adaptor_presence_info_h request,
+                                               void *user_data,
+                                                contact_adaptor_presence_info_h *response,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+EXPORT_API
+contact_error_code_t contact_adaptor_set_me_profile_type(contact_adaptor_plugin_h plugin,
+                                                contact_adaptor_plugin_context_h context,
+                                               int req_type,
+                                               void *user_data,
+                                               char **url,
+                                               contact_adaptor_error_code_h *error,
+                                               void **server_data);
+
+#endif /* __CONTACT_ADAPTOR_H__ */
diff --git a/adaptor/message-adaptor/message-adaptor-log.h b/adaptor/message-adaptor/message-adaptor-log.h
new file mode 100644 (file)
index 0000000..69f9e69
--- /dev/null
@@ -0,0 +1,192 @@
+/*\r
+* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved\r
+*\r
+* Licensed under the Apache License, Version 2.0 (the License);\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+* http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an AS IS BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+*/\r
+\r
+#ifndef __MESSAGE_ADAPTOR_LOG_H__\r
+#define __MESSAGE_ADAPTOR_LOG_H__\r
+\r
+\r
+/* #define WORK_IN_LOCAL */\r
+\r
+/**\r
+ *  HOW TO USE IT:\r
+ *  First you need to set platform logging on the device:\r
+ *\r
+ *    # dlogctrl set platformlog 1\r
+ *\r
+ *  After reboot you are able to see logs from this application, when you launch dlogutil with a proper filter e.g.:\r
+ *\r
+ *    # dlogutil MESSAGE_ADAPTOR:D\r
+ *\r
+ *  You may use different logging levels as: D (debug), I (info), W (warning), E (error) or F (fatal).\r
+ *  Higher level messages are included by default e.g. dlogutil CLOUDBOX:W prints warnings but also errors and fatal messages.\r
+ */\r
+\r
+#include <unistd.h>\r
+#include <linux/unistd.h>\r
+\r
+/* These defines must be located before #include <dlog.h> */\r
+#define TIZEN_ENGINEER_MODE\r
+// TODO: Investigate why this macro is defined somewhere else\r
+#ifndef TIZEN_DEBUG_ENABLE\r
+#define TIZEN_DEBUG_ENABLE\r
+#endif\r
+\r
+#ifdef LOG_TAG\r
+#undef LOG_TAG\r
+#endif\r
+/* Literal to filter logs from dlogutil */\r
+#define LOG_TAG "MESSAGE_ADAPTOR"\r
+\r
+\r
+#ifndef WORK_IN_LOCAL\r
+#include <dlog.h>\r
+#else\r
+#define LOGE(fmt, arg...)\r
+#define LOGD(fmt, arg...)\r
+#define LOGI(fmt, arg...)\r
+#define LOGF(fmt, arg...)\r
+#define LOGW(fmt, arg...)\r
+#endif\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif /* __cplusplus */\r
+\r
+       /**\r
+        *  Colors of font\r
+        */\r
+#define FONT_COLOR_RESET      "\033[0m"\r
+#define FONT_COLOR_BLACK      "\033[30m"             /* Black */\r
+#define FONT_COLOR_RED        "\033[31m"             /* Red */\r
+#define FONT_COLOR_GREEN      "\033[32m"             /* Green */\r
+#define FONT_COLOR_YELLOW     "\033[33m"             /* Yellow */\r
+#define FONT_COLOR_BLUE       "\033[34m"             /* Blue */\r
+#define FONT_COLOR_PURPLE     "\033[35m"             /* Purple */\r
+#define FONT_COLOR_CYAN       "\033[36m"             /* Cyan */\r
+#define FONT_COLOR_WHITE      "\033[37m"             /* White */\r
+#define FONT_COLOR_BOLDBLACK  "\033[1m\033[30m"      /* Bold Black */\r
+#define FONT_COLOR_BOLDRED    "\033[1m\033[31m"      /* Bold Red */\r
+#define FONT_COLOR_BOLDGREEN  "\033[1m\033[32m"      /* Bold Green */\r
+#define FONT_COLOR_BOLDYELLOW "\033[1m\033[33m"      /* Bold Yellow */\r
+#define FONT_COLOR_BOLDBLUE   "\033[1m\033[34m"      /* Bold Blue */\r
+#define FONT_COLOR_BOLDPURPLE "\033[1m\033[35m"      /* Bold Purple */\r
+#define FONT_COLOR_BOLDCYAN   "\033[1m\033[36m"      /* Bold Cyan */\r
+#define FONT_COLOR_BOLDWHITE  "\033[1m\033[37m"      /* Bold White */\r
+\r
+       /**\r
+        *  Gets thread ID\r
+        */\r
+#define message_adaptor_gettid() syscall(__NR_gettid)\r
+\r
+/**\r
+ *  @brief Macro for returning value if expression is satisfied\r
+ *  @param[in]  expr Expression to be checked\r
+ *  @param[out] val  Value to be returned when expression is true\r
+ */\r
+#define message_adaptor_retv_if(expr, val) do { \\r
+            if(expr) { \\r
+                LOGE(FONT_COLOR_PURPLE"[%d]"FONT_COLOR_RESET, message_adaptor_gettid());    \\r
+                return (val); \\r
+            } \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints debug messages\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define message_adaptor_debug(fmt, arg...) do { \\r
+            LOGD(FONT_COLOR_GREEN"[%d]"fmt""FONT_COLOR_RESET, message_adaptor_gettid(), ##arg);     \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints info messages\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define message_adaptor_info(fmt, arg...) do { \\r
+            LOGI(FONT_COLOR_BLUE"[%d]"fmt""FONT_COLOR_RESET, message_adaptor_gettid() ,##arg);     \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints warning messages\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define message_adaptor_warning(fmt, arg...) do { \\r
+            LOGW(FONT_COLOR_YELLOW"[%d]"fmt""FONT_COLOR_RESET,message_adaptor_gettid(), ##arg);     \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints error messages\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define message_adaptor_error(fmt, arg...) do { \\r
+            LOGE(FONT_COLOR_RED"[%d]"fmt""FONT_COLOR_RESET,message_adaptor_gettid(), ##arg);     \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints fatal messages\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define message_adaptor_fatal(fmt, arg...) do { \\r
+            LOGF(FONT_COLOR_BOLDRED"[%d]"fmt""FONT_COLOR_RESET,message_adaptor_gettid(), ##arg);     \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints debug message on entry to particular function\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define message_adaptor_debug_func(fmt, arg...) do { \\r
+            LOGD(FONT_COLOR_CYAN"[%d]"fmt""FONT_COLOR_RESET, message_adaptor_gettid(), ##arg);     \\r
+        } while (0)\r
+\r
+#define plugin_req_enter()                     do { \\r
+               message_adaptor_info("[ENTER] plugin API call -)) -)) -)) -)) -)) -)) -)) -)) -)) -))"); \\r
+       } while (0)\r
+\r
+#define plugin_req_exit(ret, plugin, error)    do { \\r
+               message_adaptor_info("[EXIT] plugin API called (%d) ((- ((- ((- ((- ((- ((- ((- ((- ((- ((-", (int)(ret)); \\r
+               if ((error)) { \\r
+                       if ((*error)) { \\r
+                               message_adaptor_error("plugin issued error (%s) (%s)", (char *)((*error)->code), (char *)((*error)->msg)); \\r
+                               char *tem = g_strdup_printf("[PLUGIN_ERROR] URI(%s), MSG(%s)", (char *)((plugin)->handle->plugin_uri), (char *)((*error)->msg)); \\r
+                               if (tem) { \\r
+                                       free((*error)->msg); \\r
+                                       (*error)->msg = tem; \\r
+                               } \\r
+                       } \\r
+               } \\r
+       } while (0)\r
+\r
+#define plugin_req_exit_void()                 do { \\r
+               message_adaptor_info("[EXIT] plugin API called ((- ((- ((- ((- ((- ((- ((- ((- ((- ((-"); \\r
+       } while (0)\r
+\r
+#define plugin_req_id_print()                  do { \\r
+               message_adaptor_info("[REQUEST_ID] Important Request ID <%lld>", (long long int)request_id); \\r
+       } while (0)\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+\r
+#endif /* __MESSAGE_ADAPTOR_LOG_H__ */\r
diff --git a/adaptor/message-adaptor/message-adaptor.c b/adaptor/message-adaptor/message-adaptor.c
new file mode 100644 (file)
index 0000000..acf7738
--- /dev/null
@@ -0,0 +1,2095 @@
+/*
+* Copyright (c) 2011 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.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <glib.h>
+
+
+#include "message-adaptor.h"
+#include "message-adaptor-log.h"
+
+
+/**
+ * Message adaptor plugin
+ */
+typedef struct message_adaptor_plugin_s {
+       message_adaptor_h                       adaptor;                /* Adaptor */
+       char                                    *path;                  /* Plugin library path */
+       message_adaptor_plugin_handle_h         handle;                 /* Plugin handle */
+       void                                    *dl_handle;             /* Plugin library handle */
+       int                                     ref_counter;            /* Plugin reference counter */
+       GMutex                                  ref_counter_mutex;      /* Plugin reference counter mutex */
+       message_adaptor_plugin_listener_h       plugin_listener;        /* Plugin callback listener */
+       GMutex                                  plugin_listener_mutex;  /* Plugin callback listener mutex */
+       int                                     connected;              /* connected flag */
+       GMutex                                  plugin_connect_mutex;
+       GCond                                   plugin_connect_cond;
+} message_adaptor_plugin_t;
+
+/**
+ * Message adaptor
+ */
+typedef struct message_adaptor_s {
+       GMutex  message_adaptor_mutex;          /* Adaptor mutex */
+       int     started;                        /* Started flag */
+       char    *plugins_dir;                   /* Plugins directory path */
+       GList   *plugins;                       /* List of loaded plugins */
+       GMutex  plugins_mutex;                  /* Plugin list mutex */
+       GList   *adaptor_listeners;             /* List of vservice channel listener (for now not effective) */
+       GMutex  adaptor_listeners_mutex;        /* Listener list mutex */
+} message_adaptor_t;
+
+/**
+ * Creates plugin
+ */
+static message_adaptor_plugin_h message_adaptor_create_plugin(const char *plugin_path);
+
+/**
+ * Destroys plugin and deletes all resources associated with it
+ */
+static void message_adaptor_destroy_plugin(message_adaptor_plugin_h plugin);
+
+/**
+ * Loads plugins from selected directory
+ */
+static int message_adaptor_load_plugins_from_directory(message_adaptor_h adaptor, const char *dir_path);
+
+/**
+ * Checks if plugin is loaded by selected plugin adaptor
+ */
+static int message_adaptor_has_plugin(message_adaptor_h adaptor, message_adaptor_plugin_h plugin);
+
+/**
+ * Increases adaptor's plugin references counter
+ */
+static void message_adaptor_plugin_ref(message_adaptor_plugin_h);
+
+/**
+ * Decreases adaptor's plugin references counter
+ */
+static void message_adaptor_plugin_unref(message_adaptor_plugin_h);
+
+
+/**
+ * Definition of callback function variables for service adaptor
+ */
+
+message_adaptor_service_client_echo_cb _service_adaptor_service_client_echo_cb = NULL;
+message_adaptor_service_create_chatroom_reply_cb _service_adaptor_service_create_chatroom_reply_cb = NULL;
+message_adaptor_service_change_chatroom_meta_reply_cb _service_adaptor_service_change_chatroom_meta_reply_cb = NULL;
+message_adaptor_service_chat_reply_cb _service_adaptor_service_chat_reply_cb = NULL;
+message_adaptor_service_allow_chat_reply_cb _service_adaptor_service_allow_chat_reply_cb = NULL;
+message_adaptor_service_get_all_unread_message_reply_cb _service_adaptor_service_get_all_unread_message_reply_cb = NULL;
+message_adaptor_service_forward_online_message_request_cb _service_adaptor_service_forward_online_message_request_cb = NULL;
+message_adaptor_service_forward_unread_message_request_cb _service_adaptor_service_forward_unread_message_request_cb = NULL;
+message_adaptor_service_read_message_reply_cb _service_adaptor_service_read_message_reply_cb = NULL;
+message_adaptor_service_invite_chat_reply_cb _service_adaptor_service_invite_chat_reply_cb = NULL;
+message_adaptor_service_end_chat_reply_cb _service_adaptor_service_end_chat_reply_cb = NULL;
+message_adaptor_service_unseal_message_reply_cb _service_adaptor_service_unseal_message_reply_cb = NULL;
+message_adaptor_service_save_call_log_reply_cb _service_adaptor_service_save_call_log_reply_cb = NULL;
+message_adaptor_service_current_time_reply_cb _service_adaptor_service_current_time_reply_cb = NULL;
+message_adaptor_service_typing_updated_cb _service_adaptor_service_typing_updated_cb = NULL;
+message_adaptor_service_completion_cb _service_adaptor_service_completion_cb = NULL;
+/*
+ * Required function for sample callback functions
+ */
+
+void
+message_adaptor_client_echo_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_client_echo_cb) {
+               _service_adaptor_service_client_echo_cb(context, request_id, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_create_chatroom_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               int default_message_ttl,
+                                               message_adaptor_wrong_receiver_s *wrong_receiver,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_create_chatroom_reply_cb) {
+               _service_adaptor_service_create_chatroom_reply_cb(context, request_id,
+                               chatroom_id, default_message_ttl, wrong_receiver, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_change_chatroom_meta_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_change_chatroom_meta_reply_cb) {
+               _service_adaptor_service_change_chatroom_meta_reply_cb(context, request_id,
+                               chatroom_id, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_chat_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_processed_msg_s **processed_msgs,
+                                               unsigned int processed_msgs_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_chat_reply_cb) {
+               _service_adaptor_service_chat_reply_cb(context,
+                               request_id, chatroom_id, processed_msgs,
+                               processed_msgs_len, error_code, server_data);
+       }
+}
+
+
+void
+message_adaptor_allow_chat_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_delivery_ack_s **deliveryacks,
+                                               unsigned int deliveryacks_len,
+                                               unsigned long long last_delivery_ack_timestamp,
+                                               message_adaptor_read_ack_s **read_acks,
+                                               unsigned int read_acks_len,
+                                               unsigned long long last_read_ack_timestamp,
+                                               message_adaptor_ordered_chat_member_s **ordered_chat_members,
+                                               unsigned int ordered_chat_members_len,
+                                               const char *chatroom_title,
+                                               int default_message_ttl,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_allow_chat_reply_cb) {
+               _service_adaptor_service_allow_chat_reply_cb(context,
+                               request_id, chatroom_id,
+                               deliveryacks, deliveryacks_len, last_delivery_ack_timestamp,
+                               read_acks, read_acks_len, last_read_ack_timestamp,
+                               ordered_chat_members, ordered_chat_members_len,
+                               chatroom_title, default_message_ttl,
+                               error_code, server_data);
+       }
+}
+
+void
+message_adaptor_get_all_unread_message_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_get_all_unread_message_reply_cb) {
+               _service_adaptor_service_get_all_unread_message_reply_cb(context,
+                               request_id, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_forward_online_message_request_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id, int chat_type,
+                                               message_inboxentry_t *inbox_msg,
+                                               bool skip_reply,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_forward_online_message_request_cb) {
+               _service_adaptor_service_forward_online_message_request_cb(context,
+                               request_id, chatroom_id, chat_type,
+                               inbox_msg, skip_reply, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_forward_unread_message_request_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_inboxentry_t ***inbox_msgs,
+                                               unsigned int inbox_msgs_len,
+                                               char **next_pagination_key,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_forward_unread_message_request_cb) {
+               _service_adaptor_service_forward_unread_message_request_cb(context,
+                               request_id, inbox_msgs, inbox_msgs_len,
+                               next_pagination_key, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_read_message_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_read_message_reply_cb) {
+               _service_adaptor_service_read_message_reply_cb(context,
+                               request_id, chatroom_id, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_invite_chat_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               long long int sent_time,
+                                               message_adaptor_wrong_receiver_s *wrong_receiver,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_invite_chat_reply_cb) {
+               _service_adaptor_service_invite_chat_reply_cb(context,
+                               request_id, chatroom_id, sent_time,
+                               wrong_receiver, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_end_chat_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_end_chat_reply_cb) {
+               _service_adaptor_service_end_chat_reply_cb(context,
+                               request_id, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_unseal_message_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_unseal_message_reply_cb) {
+               _service_adaptor_service_unseal_message_reply_cb(context,
+                               request_id, chatroom_id, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_save_call_log_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_save_call_log_reply_cb) {
+               _service_adaptor_service_save_call_log_reply_cb(context,
+                               request_id, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_current_time_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int current_time_millis,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_current_time_reply_cb) {
+               _service_adaptor_service_current_time_reply_cb(context,
+                               request_id, current_time_millis, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_typing_updated_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               long long int *sender,
+                                               char **state,
+                                               int *contentType,
+                                               int *refreshTime,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_typing_updated_cb) {
+               _service_adaptor_service_typing_updated_cb(context,
+                               request_id, chatroom_id, sender,
+                               state, contentType, refreshTime,
+                               error_code, server_data);
+       }
+}
+
+void
+message_adaptor_completion_cb(message_adaptor_plugin_context_h context,
+                                               message_connection_state_t state,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       if (_service_adaptor_service_completion_cb) {
+               _service_adaptor_service_completion_cb(context,
+                               state, error_code, server_data);
+       }
+}
+
+
+/* //------------------------------------------------------------------------
+   // Functions implementations
+   //------------------------------------------------------------------------ */
+
+/* //////////////////////////////////////////////////////
+   // Mandatory: External adaptor management function
+   ////////////////////////////////////////////////////// */
+
+EXPORT_API
+message_adaptor_h message_adaptor_create(const char *plugins_dir)
+{
+       message_adaptor_h message_adaptor = (message_adaptor_h) malloc(sizeof(message_adaptor_t));
+       if (NULL == message_adaptor) {
+               return NULL;
+       }
+
+       message_adaptor->started = 0;
+       message_adaptor->plugins_dir = strdup(plugins_dir);
+
+       g_mutex_init(&message_adaptor->message_adaptor_mutex);
+       g_mutex_init(&message_adaptor->plugins_mutex);
+       g_mutex_init(&message_adaptor->adaptor_listeners_mutex);
+
+       g_mutex_lock(&message_adaptor->adaptor_listeners_mutex);
+       message_adaptor->adaptor_listeners = NULL;
+       g_mutex_unlock(&message_adaptor->adaptor_listeners_mutex);
+
+       g_mutex_lock(&message_adaptor->plugins_mutex);
+       message_adaptor->plugins = NULL;
+       g_mutex_unlock(&message_adaptor->plugins_mutex);
+
+       return message_adaptor;
+
+}
+
+EXPORT_API
+void message_adaptor_destroy(message_adaptor_h adaptor)
+{
+       if (NULL == adaptor) {
+               message_adaptor_error("Invalid argument");
+               return ;
+       }
+
+       g_mutex_lock(&adaptor->message_adaptor_mutex);
+       if (adaptor->started) {
+               message_adaptor_error("Message adaptor is running. Forcing stop before destroy");
+               message_adaptor_stop(adaptor);
+       }
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       if (NULL != adaptor->plugins) {
+               g_list_free_full(adaptor->plugins, (GDestroyNotify) message_adaptor_plugin_unref);
+               adaptor->plugins = NULL;
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+       if (NULL != adaptor->adaptor_listeners) {
+               g_list_free(adaptor->adaptor_listeners);
+               adaptor->adaptor_listeners = NULL;
+       }
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+
+       free(adaptor->plugins_dir);
+       adaptor->plugins_dir = NULL;
+
+       g_mutex_unlock(&adaptor->message_adaptor_mutex);
+
+       free(adaptor);
+}
+
+EXPORT_API
+int message_adaptor_start(message_adaptor_h adaptor)
+{
+       message_adaptor_debug("Starting message adaptor");
+       if (NULL == adaptor) {
+               message_adaptor_error("Invalid argument");
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->message_adaptor_mutex);
+       int result = MESSAGE_ADAPTOR_ERROR_NONE;
+       if (adaptor->started) {
+               message_adaptor_error("Message adaptor is already started");
+               result = MESSAGE_ADAPTOR_ERROR_START;
+       } else {
+               adaptor->started = 1;
+               result = message_adaptor_load_plugins_from_directory(adaptor, adaptor->plugins_dir);
+               if (MESSAGE_ADAPTOR_ERROR_NONE != result) {
+                       adaptor->started = 0;
+                       message_adaptor_error("Could not load plugins from directory");
+               } else {
+                       message_adaptor_debug("Message adaptor started successfully");
+               }
+       }
+       g_mutex_unlock(&adaptor->message_adaptor_mutex);
+
+       return result;
+}
+
+/**
+ * Stops message adaptor.
+ */
+EXPORT_API
+int message_adaptor_stop(message_adaptor_h adaptor)
+{
+       if (NULL == adaptor) {
+               message_adaptor_error("Invalid argument");
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->message_adaptor_mutex);
+       int result = MESSAGE_ADAPTOR_ERROR_NONE;
+       if (!adaptor->started) {
+               result = MESSAGE_ADAPTOR_ERROR_START;
+       } else {
+               if (NULL != adaptor->plugins) {
+                       g_mutex_lock(&adaptor->plugins_mutex);
+                       g_list_free_full(adaptor->plugins, (GDestroyNotify) message_adaptor_plugin_unref);
+                       adaptor->plugins = NULL;
+                       g_mutex_unlock(&adaptor->plugins_mutex);
+               }
+               adaptor->started = 0;
+               message_adaptor_debug("Message adaptor stopped");
+       }
+
+       g_mutex_unlock(&adaptor->message_adaptor_mutex);
+       return result;
+}
+
+/**
+ * Registers plugin state listener
+ */
+       EXPORT_API
+int message_adaptor_register_listener(message_adaptor_h adaptor, message_adaptor_listener_h listener)
+{
+       if ((NULL == adaptor) || (NULL == listener)) {
+               message_adaptor_error("Invalid argument");
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+
+       adaptor->adaptor_listeners = g_list_append(adaptor->adaptor_listeners, listener);
+
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+
+       _service_adaptor_service_client_echo_cb =
+               (message_adaptor_service_client_echo_cb)listener->client_echo_cb;
+       _service_adaptor_service_create_chatroom_reply_cb =
+               (message_adaptor_service_create_chatroom_reply_cb)listener->create_chatroom_reply_cb;
+       _service_adaptor_service_change_chatroom_meta_reply_cb =
+               (message_adaptor_service_change_chatroom_meta_reply_cb)listener->change_chatroom_meta_reply_cb;
+       _service_adaptor_service_chat_reply_cb =
+               (message_adaptor_service_chat_reply_cb)listener->chat_reply_cb;
+       _service_adaptor_service_allow_chat_reply_cb =
+               (message_adaptor_service_allow_chat_reply_cb)listener->allow_chat_reply_cb;
+       _service_adaptor_service_get_all_unread_message_reply_cb =
+               (message_adaptor_service_get_all_unread_message_reply_cb)listener->get_all_unread_message_reply_cb;
+       _service_adaptor_service_forward_online_message_request_cb =
+               (message_adaptor_service_forward_online_message_request_cb)listener->forward_online_message_request_cb;
+       _service_adaptor_service_forward_unread_message_request_cb =
+               (message_adaptor_service_forward_unread_message_request_cb)listener->forward_unread_message_request_cb;
+       _service_adaptor_service_read_message_reply_cb =
+               (message_adaptor_service_read_message_reply_cb)listener->read_message_reply_cb;
+       _service_adaptor_service_invite_chat_reply_cb =
+               (message_adaptor_service_invite_chat_reply_cb)listener->invite_chat_reply_cb;
+       _service_adaptor_service_end_chat_reply_cb =
+               (message_adaptor_service_end_chat_reply_cb)listener->end_chat_reply_cb;
+       _service_adaptor_service_unseal_message_reply_cb =
+               (message_adaptor_service_unseal_message_reply_cb)listener->unseal_message_reply_cb;
+       _service_adaptor_service_save_call_log_reply_cb =
+               (message_adaptor_service_save_call_log_reply_cb)listener->save_call_log_reply_cb;
+       _service_adaptor_service_current_time_reply_cb =
+               (message_adaptor_service_current_time_reply_cb)listener->current_time_reply_cb;
+       _service_adaptor_service_typing_updated_cb =
+               (message_adaptor_service_typing_updated_cb)listener->typing_updated_cb;
+       _service_adaptor_service_completion_cb =
+               (message_adaptor_service_completion_cb)listener->completion_cb;
+
+       return MESSAGE_ADAPTOR_ERROR_NONE;
+}
+
+/**
+ * Unregisters plugin state listener
+ */
+EXPORT_API
+int message_adaptor_unregister_listener(message_adaptor_h adaptor, message_adaptor_listener_h listener)
+{
+       if ((NULL == adaptor) || (NULL == listener)) {
+               message_adaptor_error("Invalid argument");
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+
+       if (NULL == g_list_find(adaptor->adaptor_listeners, listener)) {
+               g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+               message_adaptor_error("Could not find listener");
+               return MESSAGE_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       adaptor->adaptor_listeners = g_list_remove(adaptor->adaptor_listeners, listener);
+
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+
+       _service_adaptor_service_client_echo_cb = NULL;
+       _service_adaptor_service_create_chatroom_reply_cb = NULL;
+       _service_adaptor_service_change_chatroom_meta_reply_cb = NULL;
+       _service_adaptor_service_chat_reply_cb = NULL;
+       _service_adaptor_service_allow_chat_reply_cb = NULL;
+       _service_adaptor_service_get_all_unread_message_reply_cb = NULL;
+       _service_adaptor_service_forward_online_message_request_cb = NULL;
+       _service_adaptor_service_forward_unread_message_request_cb = NULL;
+       _service_adaptor_service_read_message_reply_cb = NULL;
+       _service_adaptor_service_invite_chat_reply_cb = NULL;
+       _service_adaptor_service_end_chat_reply_cb = NULL;
+       _service_adaptor_service_unseal_message_reply_cb = NULL;
+       _service_adaptor_service_save_call_log_reply_cb = NULL;
+       _service_adaptor_service_current_time_reply_cb = NULL;
+       _service_adaptor_service_typing_updated_cb = NULL;
+       _service_adaptor_service_completion_cb = NULL;
+
+       return MESSAGE_ADAPTOR_ERROR_NONE;
+}
+
+/* /////////////////////////////////////////////////////////////
+   // Plugin create / destroy / ref. count / get plugin name
+   ///////////////////////////////////////////////////////////// */
+static message_adaptor_plugin_h message_adaptor_create_plugin(const char *plugin_path)
+{
+       if (NULL == plugin_path) {
+               message_adaptor_error("Invalid argument");
+               return NULL;
+       }
+
+       void *dl_handle = dlopen(plugin_path, RTLD_LAZY);
+       if (NULL == dl_handle) {
+               message_adaptor_error("Could not load plugin %s: %s", plugin_path, dlerror());
+               return NULL;
+       }
+
+       message_adaptor_plugin_handle_h (*get_adaptee_handle)(void) = NULL;
+
+       get_adaptee_handle = (message_adaptor_plugin_handle_h (*)(void))(dlsym(dl_handle, "create_plugin_handle"));
+       if (NULL == get_adaptee_handle) {
+               dlclose(dl_handle);
+               message_adaptor_error("Could not get function pointer to create_plugin_handle");
+               return NULL;
+       }
+
+       plugin_req_enter();
+       message_adaptor_plugin_handle_h handle = get_adaptee_handle();
+       plugin_req_exit_void();
+       if (NULL == handle) {
+               dlclose(dl_handle);
+               message_adaptor_error("Could not get adaptee handle");
+               return NULL;
+       }
+
+       message_adaptor_plugin_h plugin = (message_adaptor_plugin_h) calloc(1, sizeof(message_adaptor_plugin_t));
+       if (NULL == plugin) {
+               dlclose(dl_handle);
+               message_adaptor_error("Could not create plugin object");
+               return NULL;
+       }
+
+       message_adaptor_plugin_listener_h listener =
+               (message_adaptor_plugin_listener_h) calloc(1, sizeof(message_adaptor_plugin_listener_t));
+       if (NULL == listener) {
+               free(plugin);
+               dlclose(dl_handle);
+               message_adaptor_error("Could not create listener object");
+               return NULL;
+       }
+
+       plugin->path = g_strdup(plugin_path);
+       plugin->handle = handle;
+       plugin->dl_handle = dl_handle;
+       plugin->ref_counter = 0;
+
+       g_mutex_init(&plugin->ref_counter_mutex);
+       g_mutex_init(&plugin->plugin_listener_mutex);
+
+       plugin->connected = 0;
+
+       g_mutex_init(&plugin->plugin_connect_mutex);
+       g_cond_init(&plugin->plugin_connect_cond);
+
+       listener->message_adaptor_client_echo = message_adaptor_client_echo_cb;
+       listener->message_adaptor_create_chatroom_reply = message_adaptor_create_chatroom_reply_cb;
+       listener->message_adaptor_change_chatroom_meta_reply = message_adaptor_change_chatroom_meta_reply_cb;
+       listener->message_adaptor_chat_reply = message_adaptor_chat_reply_cb;
+       listener->message_adaptor_allow_chat_reply = message_adaptor_allow_chat_reply_cb;
+       listener->message_adaptor_get_all_unread_message_reply = message_adaptor_get_all_unread_message_reply_cb;
+       listener->message_adaptor_forward_online_message_request = message_adaptor_forward_online_message_request_cb;
+       listener->message_adaptor_forward_unread_message_request = message_adaptor_forward_unread_message_request_cb;
+       listener->message_adaptor_read_message_reply = message_adaptor_read_message_reply_cb;
+       listener->message_adaptor_invite_chat_reply = message_adaptor_invite_chat_reply_cb;
+       listener->message_adaptor_end_chat_reply = message_adaptor_end_chat_reply_cb;
+       listener->message_adaptor_unseal_message_reply = message_adaptor_unseal_message_reply_cb;
+       listener->message_adaptor_save_call_log_reply = message_adaptor_save_call_log_reply_cb;
+       listener->message_adaptor_current_time_reply = message_adaptor_current_time_reply_cb;
+       listener->message_adaptor_typing_updated = message_adaptor_typing_updated_cb;
+       listener->message_adaptor_completion = message_adaptor_completion_cb;
+
+       plugin_req_enter();
+       plugin->handle->set_listener(listener);
+       plugin_req_exit_void();
+
+       g_mutex_lock(&plugin->plugin_listener_mutex);
+       plugin->plugin_listener = listener;
+       g_mutex_unlock(&plugin->plugin_listener_mutex);
+
+       return plugin;
+}
+
+static void message_adaptor_destroy_plugin(message_adaptor_plugin_h plugin)
+{
+       if (NULL == plugin) {
+               message_adaptor_error("Invalid argument");
+               return;
+       }
+
+       if (NULL != plugin->handle) {
+               plugin->handle->destroy_handle(plugin->handle);
+
+               g_mutex_lock(&plugin->plugin_listener_mutex);
+               plugin_req_enter();
+               plugin->handle->unset_listener();
+               plugin_req_exit_void();
+               g_mutex_unlock(&plugin->plugin_listener_mutex);
+
+               plugin->handle = NULL;
+       }
+
+       if (NULL != plugin->dl_handle) {
+               dlclose(plugin->dl_handle);
+               plugin->dl_handle = NULL;
+       }
+
+       free(plugin->path);
+       plugin->path = NULL;
+
+       free(plugin);
+}
+
+static int message_adaptor_load_plugins_from_directory(message_adaptor_h adaptor, const char *dir_path)
+{
+       char *plugin_path = NULL;
+       DIR *dir = NULL;
+       struct dirent dir_entry, *result = NULL;
+
+       message_adaptor_debug("Starting load plugins from directory");
+
+       if ((NULL == adaptor) || (NULL == dir_path)) {
+               message_adaptor_error("Invalid argument");
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       dir = opendir(dir_path);
+       if (NULL == dir) {
+               message_adaptor_error("Could not open dir path (%s)", dir_path);
+               return MESSAGE_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       int ret = MESSAGE_ADAPTOR_ERROR_NONE;
+       while (0 == (readdir_r(dir, &dir_entry, &result))) {
+
+               if (NULL == result) {
+                       message_adaptor_error("Could not open directory %s", plugin_path);
+                       break;
+               }
+
+               if (dir_entry.d_type & DT_DIR) {
+                       continue;
+               }
+
+               plugin_path = g_strconcat(dir_path, "/", dir_entry.d_name, NULL);
+               message_adaptor_plugin_h plugin = message_adaptor_create_plugin(plugin_path);
+
+               if (NULL != plugin) {
+                       message_adaptor_debug("Loaded plugin: %s", plugin_path);
+                       plugin->adaptor = adaptor;
+                       message_adaptor_plugin_ref(plugin);
+                       g_mutex_lock(&adaptor->plugins_mutex);
+                       adaptor->plugins = g_list_append(adaptor->plugins, plugin);
+                       g_mutex_unlock(&adaptor->plugins_mutex);
+               } else {
+                       message_adaptor_error("Could not load plugin %s", plugin_path);
+               }
+
+               free(plugin_path);
+               plugin_path = NULL;
+       }
+
+       message_adaptor_debug("End load plugins from directory");
+       closedir(dir);
+       return ret;
+}
+
+
+static int message_adaptor_has_plugin(message_adaptor_h adaptor, message_adaptor_plugin_h plugin)
+{
+       if ((NULL == adaptor) || (NULL == plugin)) {
+               message_adaptor_error("Invalid argument");
+               return 0;
+       }
+
+       int result = 0;
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       if (NULL != g_list_find(adaptor->plugins, plugin)) {
+               result = 1;
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return result;
+}
+
+static void message_adaptor_plugin_ref(message_adaptor_plugin_h plugin)
+{
+       if (NULL == plugin) {
+               message_adaptor_error("Invalid argument");
+               return;
+       }
+
+       g_mutex_lock(&plugin->ref_counter_mutex);
+       plugin->ref_counter = plugin->ref_counter + 1;
+       if (NULL != plugin->handle) {
+               message_adaptor_info("plugin name : %s, ref_counter: %d", plugin->handle->plugin_uri, plugin->ref_counter);
+       } else {
+               message_adaptor_info("ref_counter : %d", plugin->ref_counter);
+       }
+       g_mutex_unlock(&plugin->ref_counter_mutex);
+}
+
+static void message_adaptor_plugin_unref(message_adaptor_plugin_h plugin)
+{
+       if (NULL == plugin) {
+               message_adaptor_error("Invalid argument");
+               return ;
+       }
+
+       int should_destroy = 0;
+
+       g_mutex_lock(&plugin->ref_counter_mutex);
+       plugin->ref_counter = plugin->ref_counter - 1;
+
+       if (NULL != plugin->handle) {
+               message_adaptor_info("plugin name : %s, ref_counter: %d", plugin->handle->plugin_uri, plugin->ref_counter);
+       } else {
+               message_adaptor_info("ref_counter : %d", plugin->ref_counter);
+       }
+
+       if (0 >= plugin->ref_counter) {
+               should_destroy = 1;
+       }
+       g_mutex_unlock(&plugin->ref_counter_mutex);
+
+       if (should_destroy) {
+               message_adaptor_debug("Plugin is being destroyed");
+               message_adaptor_destroy_plugin(plugin);
+       }
+}
+
+
+/**
+ * Refresh access token
+ */
+EXPORT_API
+message_error_code_t message_adaptor_refresh_access_token(message_adaptor_plugin_context_h context,
+                                               const char *new_access_token)
+{
+       if ((NULL == context) || (NULL == new_access_token) || (0 >= strlen(new_access_token))) {
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+       if ((NULL == context->access_token) || (0 >= strlen(context->access_token))) {
+               return MESSAGE_ADAPTOR_ERROR_NOT_AUTHORIZED;
+       }
+
+       free(context->access_token);
+       context->access_token = NULL;
+       context->access_token = strdup(new_access_token);
+
+       return MESSAGE_ADAPTOR_ERROR_NONE;
+}
+
+EXPORT_API
+message_error_code_t message_adaptor_refresh_uid(message_adaptor_plugin_context_h context,
+                                               const char *new_uid)
+{
+       if ((NULL == context) || (NULL == new_uid) || (0 >= strlen(new_uid))) {
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+       message_adaptor_debug("New uid : %s", new_uid);
+
+       free(context->uid);
+       context->uid = NULL;
+       context->uid = strdup(new_uid);
+
+       char *pend = NULL;
+       context->duid = (long long int) strtoll(new_uid, &pend, 10);
+
+       return MESSAGE_ADAPTOR_ERROR_NONE;
+}
+
+/* //////////////////////////////////////////////////////
+   // Create / Destroy error code
+   ////////////////////////////////////////////////////// */
+message_adaptor_error_code_h message_adaptor_create_error_code(const char *code, const char *msg)
+{
+       if (NULL == code || NULL == msg) {
+               return NULL;
+       }
+
+       message_adaptor_error_code_h error_code = (message_adaptor_error_code_h) malloc(sizeof(message_adaptor_error_code_t));
+
+       if (NULL != error_code) {
+               error_code->code = strdup(code);
+               error_code->msg = strdup(msg);
+       }
+
+       return error_code;
+}
+
+void message_adaptor_destroy_error_code(message_adaptor_error_code_h *error_code)
+{
+       if ((NULL != error_code) && (NULL != (*error_code))) {
+               free((*error_code)->msg);
+               (*error_code)->msg = NULL;
+               free(*error_code);
+               *error_code = NULL;
+       }
+}
+
+void _set_error_code(message_adaptor_error_code_h *error, const char *code, const char *msg)
+{
+       if (NULL == error) {
+               return;
+       }
+
+       message_adaptor_error_code_h error_code = (message_adaptor_error_code_h) calloc(1, sizeof(message_adaptor_error_code_t));
+
+       if (NULL != error_code) {
+               error_code->code = strdup(code);
+               error_code->msg = strdup(msg);
+       }
+
+       *error = error_code;
+}
+
+void message_adaptor_destroy_chat_msg_s(message_adaptor_chat_msg_s *msg)
+{
+       if (NULL == msg) {
+               return;
+       }
+       free(msg->chatmsg);
+       free(msg);
+}
+void message_adaptor_destroy_processed_msg_s(message_adaptor_processed_msg_s *msg)
+{
+       if (NULL == msg) {
+               return;
+       }
+       free(msg);
+}
+void message_adaptor_destroy_delivery_ack_s(message_adaptor_delivery_ack_s *ack)
+{
+       if (NULL == ack) {
+               return;
+       }
+       free(ack);
+}
+void message_adaptor_destroy_read_ack_s(message_adaptor_read_ack_s *ack)
+{
+       if (NULL == ack) {
+               return;
+       }
+       free(ack);
+}
+void message_adaptor_destroy_ordered_chat_member_s(message_adaptor_ordered_chat_member_s *member)
+{
+       if (NULL == member) {
+               return;
+       }
+       free(member->name);
+       free(member);
+}
+void message_adaptor_destroy_inbox_message_s(message_adaptor_inbox_message_s *msg)
+{
+       if (NULL == msg) {
+               return;
+       }
+       free(msg->chatMsg);
+       free(msg);
+}
+void message_adaptor_destroy_phone_number_s(message_adaptor_phone_number_s *num)
+{
+       if (NULL == num) {
+               return;
+       }
+       free(num->phonenumber);
+       free(num->ccc);
+       free(num);
+}
+void message_adaptor_destroy_chat_id_s(message_adaptor_chat_id_s *id)
+{
+       if (NULL == id) {
+               return;
+       }
+       free(id->msisdn);
+       free(id);
+}
+void message_adaptor_destroy_end_chat_s(message_adaptor_end_chat_s *msg)
+{
+       if (NULL == msg) {
+               return;
+       }
+       free(msg);
+}
+
+
+/* //////////////////////////////////////////////////////
+   // Plugin context create / destroy
+   ////////////////////////////////////////////////////// */
+
+message_adaptor_plugin_context_h message_adaptor_create_plugin_context(message_adaptor_plugin_h plugin,
+                                               char *plugin_uri,
+                                               char *duid,
+                                               char *access_token,
+                                               char *app_id,
+                                               int service_id)
+{
+       message_adaptor_debug("Starting message_adaptor_create_plugin_context");
+
+       if (NULL == plugin) {
+               message_adaptor_error("Invalid argument");
+               return NULL;
+       }
+
+       if (NULL != plugin->handle) {
+               message_adaptor_plugin_context_h plugin_context = NULL;
+
+               plugin_req_enter();
+               plugin->handle->create_context(&plugin_context, duid, access_token, app_id, service_id);
+               plugin_req_exit_void();
+
+               if (NULL != plugin_context) {
+                       plugin_context->plugin_uri = strdup(plugin->handle->plugin_uri);
+                       plugin_context->connection_policy = MESSAGE_CONNECTION_POLICY_AUTO;
+               } else {
+                       message_adaptor_error("plugin context info message_context set error");
+                       message_adaptor_error("plugin context info message_plugin set error");
+               }
+               return plugin_context;
+       } else {
+               message_adaptor_error("Plugin handle is null");
+       }
+
+       message_adaptor_debug("End message_adaptor_create_plugin_context");
+       return NULL;
+}
+
+void message_adaptor_destroy_plugin_context(message_adaptor_plugin_h plugin, message_adaptor_plugin_context_h plugin_context)
+{
+       message_adaptor_warning("Destroy plugin context");
+
+       if ((NULL == plugin) || (NULL == plugin_context)) {
+               message_adaptor_error("Invalid argument");
+               return;
+       }
+
+       if (NULL != plugin->handle) {
+               plugin_req_enter();
+               plugin->handle->destroy_context(plugin_context);
+               plugin_req_exit_void();
+       } else {
+               message_adaptor_error("Plugin handle is null");
+       }
+}
+
+message_error_code_t message_adaptor_set_connected(message_adaptor_plugin_h plugin, int connected)
+{
+       if (NULL == plugin) {
+               message_adaptor_error("plugin is NULL");
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&plugin->plugin_connect_mutex);
+       plugin->connected = connected;
+       g_cond_signal(&plugin->plugin_connect_cond);
+       g_mutex_unlock(&plugin->plugin_connect_mutex);
+
+       return MESSAGE_ADAPTOR_ERROR_NONE;
+}
+
+message_error_code_t message_adaptor_wait_connected(message_adaptor_plugin_h plugin)
+{
+       if (NULL == plugin) {
+               message_adaptor_error("plugin is NULL");
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       gint64 timeout = g_get_monotonic_time() + 10 * G_TIME_SPAN_SECOND;
+       g_mutex_lock(&plugin->plugin_connect_mutex);
+
+       while (0 == plugin->connected) {
+               if (!g_cond_wait_until(&plugin->plugin_connect_cond, &plugin->plugin_connect_mutex, timeout)) {
+                       g_mutex_unlock(&plugin->plugin_connect_mutex);
+                       return MESSAGE_ADAPTOR_ERROR_CONNECT;
+               }
+       }
+
+       g_mutex_unlock(&plugin->plugin_connect_mutex);
+
+       return MESSAGE_ADAPTOR_ERROR_NONE;
+}
+
+/* //////////////////////////////////////////////////////
+   // Get plugin by plugin name
+   ////////////////////////////////////////////////////// */
+message_adaptor_plugin_h message_adaptor_get_plugin_by_name(message_adaptor_h adaptor, const char *plugin_uri)
+{
+       message_adaptor_warning("Starting message_adaptor_get_plugin_by_name");
+
+       if ((NULL == adaptor)) {
+               message_adaptor_error("adaptor is NULL");
+       }
+
+       if ((NULL == plugin_uri)) {
+               message_adaptor_error("adaptor is NULL");
+       } else {
+               message_adaptor_error("plugin name : %s", plugin_uri);
+       }
+
+       if ((NULL == adaptor) || (NULL == plugin_uri)) {
+               message_adaptor_error("Invalid argument");
+               return NULL;
+       }
+
+       message_adaptor_plugin_h plugin = NULL;
+       g_mutex_lock(&adaptor->plugins_mutex);
+       int count = g_list_length(adaptor->plugins);
+       int i = 0;
+       message_adaptor_error("count : %d", count);
+       for (i = 0; i < count; i++) {
+               message_adaptor_plugin_h temp_plugin = (message_adaptor_plugin_h)g_list_nth_data(adaptor->plugins, i);
+               if (NULL != temp_plugin) {
+                       message_adaptor_error("temp_plugin name : %s", temp_plugin->handle->plugin_uri);
+                       if (0 == strcmp(temp_plugin->handle->plugin_uri, plugin_uri)) {
+                               message_adaptor_plugin_ref(temp_plugin);
+                               plugin = temp_plugin;
+                               g_mutex_unlock(&adaptor->plugins_mutex);
+                               return plugin;
+                       }
+               } else {
+                       message_adaptor_error("NULL != temp_plugin");
+               }
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       if (NULL == plugin) {
+               message_adaptor_debug("Plugin is not found by name");
+       }
+
+       return plugin;
+}
+
+/* //////////////////////////////////////////////////////
+   // Plugin load / unload / get plugin list
+   ////////////////////////////////////////////////////// */
+int message_adaptor_load_plugin(message_adaptor_h adaptor, const char *plugin_path)
+{
+       if ((NULL == adaptor) || (NULL == plugin_path)) {
+               message_adaptor_error("Invalid argument");
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (!adaptor->started) {
+               message_adaptor_error("Storage adaptor is not started");
+               return MESSAGE_ADAPTOR_ERROR_START;
+       }
+
+       message_adaptor_plugin_h plugin = message_adaptor_create_plugin(plugin_path);
+       if (NULL == plugin) {
+               message_adaptor_error("Could not load plugin %s", plugin_path);
+               return MESSAGE_ADAPTOR_ERROR_CREATE;
+       }
+
+       plugin->adaptor = adaptor;
+       message_adaptor_plugin_ref(plugin);
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       adaptor->plugins = g_list_append(adaptor->plugins, plugin);
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return MESSAGE_ADAPTOR_ERROR_NONE;
+}
+
+int message_adaptor_unload_plugin(message_adaptor_h adaptor, message_adaptor_plugin_h plugin)
+{
+       if ((NULL == adaptor) || (NULL == plugin)) {
+               message_adaptor_error("Invalid argument");
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (!adaptor->started) {
+               message_adaptor_error("Storage adaptor is not started");
+               return MESSAGE_ADAPTOR_ERROR_START;
+       }
+
+       if (!message_adaptor_has_plugin(adaptor, plugin)) {
+               message_adaptor_error("Storage adaptor has no plugin");
+               return MESSAGE_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       plugin->adaptor = NULL;
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       adaptor->plugins = g_list_remove(adaptor->plugins, plugin);
+       g_mutex_unlock(&adaptor->plugins_mutex);
+       message_adaptor_plugin_unref(plugin);
+
+       return MESSAGE_ADAPTOR_ERROR_NONE;
+}
+
+GList *message_adaptor_get_plugins(message_adaptor_h adaptor)
+{
+       if (NULL == adaptor) {
+               message_adaptor_error("Invalid argument");
+               return NULL;
+       }
+
+       GList *plugins = NULL;
+       g_mutex_lock(&adaptor->plugins_mutex);
+       int plugins_count = g_list_length(adaptor->plugins);
+       int i;
+       for (i = 0; i < plugins_count; i++) {
+               message_adaptor_plugin_h plugin = (message_adaptor_plugin_h) g_list_nth_data(adaptor->plugins, i);
+               if (NULL != plugin) {
+                       message_adaptor_plugin_ref(plugin);
+                       plugins = g_list_append(plugins, plugin);
+               }
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return plugins;
+
+}
+
+/* ////////////////////////////////////////////////////////////
+   // Adaptor Plugin call Functions
+   //////////////////////////////////////////////////////////// */
+
+/**
+* @brief Set server information for Message Plugin
+*
+* @param[in]   plugin                          specifies Message Adaptor Plugin handle
+* @param[in]   context                         specifies Message Adaptor Plugin Context handle
+* @param[in]   server_info                     specifies server information for Message Plugin
+* @param[in]   request                         specifies optional parameter
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t - MESSAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+message_error_code_t message_adaptor_set_server_info(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               GHashTable *server_info,
+                                               void *request,
+                                               message_adaptor_error_code_h *error_code,
+                                               void *response)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument""(plugin: %p, context: %p)", plugin, context);
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->set_server_info(context, server_info, request, error_code, response);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+
+/*TODO fill this area */
+EXPORT_API
+message_error_code_t message_adaptor_get_key(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               char **in_gcmid,
+                                               char **in_del_gcm_id,
+                                               char **key,
+                                               char **expiredkey,
+                                               char **gpbauthkey,
+                                               message_adaptor_error_code_t **error_code,
+                                               void **server_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       if (NULL == context->uid) {
+               message_adaptor_error("UID is null");
+
+               _set_error_code(error_code, "14", "Invalid argument (uid)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->get_key(context, &(context->uid), in_gcmid, in_del_gcm_id, key, expiredkey, gpbauthkey, error_code, server_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+message_error_code_t message_adaptor_request_chat_id(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               message_adaptor_phone_number_s **phone_numbers,
+                                               unsigned int phone_numbers_len,
+                                               void *user_data,
+                                               message_adaptor_chat_id_s ***chat_ids,
+                                               unsigned int *chat_ids_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void **server_data)
+{
+       message_adaptor_info("%s() Start!!!", __FUNCTION__);
+
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       if (NULL == context->uid) {
+               message_adaptor_error("UID is null");
+
+               _set_error_code(error_code, "14", "Invalid argument (uid)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->request_chat_id(context, context->uid, phone_numbers, phone_numbers_len, user_data, chat_ids, chat_ids_len, error_code, server_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+message_error_code_t message_adaptor_request_msisdn(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int *chat_ids,
+                                               unsigned int chat_ids_len,
+                                               void *user_data,
+                                               message_adaptor_chat_id_s ***msisdns,
+                                               unsigned int *msisdns_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void **server_data)
+{
+       message_adaptor_info("%s() Start!!!", __FUNCTION__);
+
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       if (NULL == context->uid) {
+               message_adaptor_error("UID is null");
+
+               _set_error_code(error_code, "14", "Invalid argument (uid)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->request_msisdn(context, context->uid, chat_ids, chat_ids_len, user_data, msisdns, msisdns_len, error_code, server_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+/*TODO fill this area */
+EXPORT_API
+message_error_code_t message_adaptor_channel_auth_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               const int timeout_second,
+                                               void *user_data,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+       plugin_req_id_print();
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->channel_auth_request(context, request_id, context->uid,
+                       context->duid, context->app_id, context->access_token,
+                       timeout_second, user_data, error_code, server_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+message_error_code_t message_adaptor_client_echo_reply(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+       plugin_req_id_print();
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->client_echo_reply(context, &request_id, error_code, server_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+message_error_code_t message_adaptor_create_chatroom_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               int chat_type,
+                                               long long int **receivers,
+                                               unsigned int receivers_len,
+                                               const char *chatroom_title,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+       plugin_req_id_print();
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->create_chatroom_request(context, &request_id, &chat_type, receivers,
+                       (int *)&receivers_len, chatroom_title, error_code, user_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+message_error_code_t message_adaptor_change_chatroom_meta_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               const char *chatroom_title,
+                                               int default_message_ttl,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+       plugin_req_id_print();
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->change_chatroom_meta_request(context, request_id, chatroom_id, chatroom_title,
+                       default_message_ttl, error_code, user_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+
+EXPORT_API
+message_error_code_t message_adaptor_chat_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_chat_msg_s **chat_msgs,
+                                               unsigned int chat_msgs_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+       plugin_req_id_print();
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->chat_request(context, &request_id, &chatroom_id, chat_msgs[0], error_code, user_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+message_error_code_t message_adaptor_allow_chat_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               bool is_auto_allow,
+                                               int max_count,
+                                               bool need_delivery_ack,
+                                               long long int delivery_ack_timestamp,
+                                               bool need_read_ack,
+                                               long long int last_read_ack_timestamp,
+                                               bool need_ordered_chat_member_list,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+       plugin_req_id_print();
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->allow_chat_request(context,
+                       &request_id, &chatroom_id, is_auto_allow, max_count,
+                       need_delivery_ack, delivery_ack_timestamp,
+                       need_read_ack, last_read_ack_timestamp,
+                       need_ordered_chat_member_list,
+                       error_code, user_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+
+EXPORT_API
+message_error_code_t message_adaptor_get_all_unread_message_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               int max_count,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+       plugin_req_id_print();
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->get_all_unread_message_request(context, &request_id, &max_count, error_code, user_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+
+EXPORT_API
+message_error_code_t message_adaptor_forward_online_message_reply(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               bool mark_as_read,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+       plugin_req_id_print();
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->forward_online_message_reply(context, &request_id, &chatroom_id, &mark_as_read, error_code, user_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+message_error_code_t message_adaptor_forward_unread_message_reply(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               const char *next_pagination_key,
+                                               int max_count,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+       plugin_req_id_print();
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->forward_unread_message_reply(context, &request_id, &next_pagination_key, &max_count, error_code, user_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+message_error_code_t message_adaptor_read_message_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_inboxentry_t *inbox_msg,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+       plugin_req_id_print();
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->read_message_request(context, &request_id, &chatroom_id,
+                       inbox_msg, error_code, user_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+message_error_code_t message_adaptor_invite_chat_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               long long int *inviting_members,
+                                               unsigned int inviting_members_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+       plugin_req_id_print();
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->invite_request(context, &request_id, &chatroom_id,
+                       inviting_members, (int *)&inviting_members_len, error_code, user_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+message_error_code_t message_adaptor_end_chat_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_end_chat_s **end_chats,
+                                               unsigned int end_chats_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+       plugin_req_id_print();
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->end_chat_request(context, &request_id, end_chats, (int *)&end_chats_len, error_code, user_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+message_error_code_t message_adaptor_unseal_message_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               long long int sender_id,
+                                               long long int message_id,
+                                               const char *message_detail,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+       plugin_req_id_print();
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->unseal_message_request(context, &request_id,
+                       &chatroom_id, &sender_id, &message_id, message_detail, error_code, user_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+message_error_code_t message_adaptor_save_call_log_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               const char *call_id,
+                                               const char *call_log_type,
+                                               long long int call_sender_id,
+                                               long long int call_receiver_id,
+                                               int conversaction_second,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+       plugin_req_id_print();
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->save_call_log_request(context, &request_id, &chatroom_id, &call_id, &call_log_type, &call_sender_id, &call_receiver_id, &conversaction_second, error_code, user_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+message_error_code_t message_adaptor_current_time_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+       plugin_req_id_print();
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->current_time_request(context, &request_id, error_code, user_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+message_error_code_t message_adaptor_is_typing(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int *request_id,
+                                               long long int *chatroom_id,
+                                               char **state,
+                                               int *chat_type,
+                                               int *refreshtime,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->is_typing(context, request_id, chatroom_id,
+                       state, chat_type, refreshtime, error_code, user_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+message_error_code_t message_adaptor_connect(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               message_adaptor_error_code_h *error_code)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->connect_to_server(context);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+message_error_code_t message_adaptor_disconnect(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               message_adaptor_error_code_h *error_code)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->disconnect_to_server(context);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+
+message_error_code_t message_adaptor_get_connection_state(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               message_connection_state_t *state,
+                                               message_adaptor_error_code_h *error_code)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->get_connection_state(context, state);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+message_error_code_t message_adaptor_decode_push_message(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               char *in_msg,
+                                               char **out_msg,
+                                               message_adaptor_error_code_h *error_code)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               message_adaptor_error("Invalid argument");
+
+               _set_error_code(error_code, "14", "Invalid argument (plugin or context)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               message_adaptor_error("Plugin handle is null");
+
+               _set_error_code(error_code, "13", "Plugin handle is null");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       if (NULL == in_msg || NULL == out_msg) {
+               message_adaptor_error("invalid argument : input/output message");
+
+               _set_error_code(error_code, "14", "Invalid argument (in_msg or out_msg)");
+
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       message_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->decode_push_message(context, in_msg, out_msg);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
diff --git a/adaptor/message-adaptor/message-adaptor.h b/adaptor/message-adaptor/message-adaptor.h
new file mode 100644 (file)
index 0000000..a5d64b7
--- /dev/null
@@ -0,0 +1,1842 @@
+/*
+* Copyright (c) 2011 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 __MESSAGE_ADAPTOR_H__
+#define __MESSAGE_ADAPTOR_H__
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <arpa/inet.h>
+#include <stdbool.h>
+#include <pthread.h>
+
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+#include <glib.h>
+
+/**
+ * Message adaptor error code
+ */
+typedef enum message_error_code_e
+{
+       MESSAGE_ADAPTOR_ERROR_NONE                     =  0,
+       MESSAGE_ADAPTOR_ERROR_LAUNCH                    = 1,    /**< 1 ~ 99: internal error*/
+       MESSAGE_ADAPTOR_ERROR_INIT                      = 2,
+       MESSAGE_ADAPTOR_ERROR_DEINIT                    = 3,
+       MESSAGE_ADAPTOR_ERROR_CREATE                    = 4,
+       MESSAGE_ADAPTOR_ERROR_DESTROY                   = 5,
+       MESSAGE_ADAPTOR_ERROR_START                     = 6,
+       MESSAGE_ADAPTOR_ERROR_STOP                      = 7,
+       MESSAGE_ADAPTOR_ERROR_CONNECT                   = 8,
+       MESSAGE_ADAPTOR_ERROR_DISCONNECT                = 9,
+       MESSAGE_ADAPTOR_ERROR_NOT_FOUND                 = 10,
+       MESSAGE_ADAPTOR_ERROR_CORRUPTED                 = 11,
+       MESSAGE_ADAPTOR_ERROR_UNSUPPORTED               = 12,
+       MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE            = 13,
+       MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT          = 14,
+       MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT_TYPE     = 15,
+       MESSAGE_ADAPTOR_ERROR_NOT_AUTHORIZED            = 16,
+       MESSAGE_ADAPTOR_ERROR_ADAPTOR_INTERNAL          = 17,
+       MESSAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL           = 18,   // input error code and message issued from curl or http or message_plugin_internal_error_code_e(defined by developer manually)
+       MESSAGE_ADAPTOR_ERROR_SERVER_INTERNAL           = 19,   // input error code and message issued from server.
+       MESSAGE_ADAPTOR_ERROR_DBUS                      = 20,
+       MESSAGE_ADAPTOR_ERROR_TIME_OUT                  = 21,
+       MESSAGE_ADAPTOR_ERROR_MAX
+} message_error_code_t;
+
+/**
+ * @ brief Message plugin internal error code
+ * @ details When a plugin returns MESSAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL, input this number to message_adaptor_error_code_s.code
+ */
+typedef enum _message_plugin_internal_error_code_e
+{
+       MESSAGE_PLUGIN_ERROR_HTTP_BAD_REQUEST           = 400,
+       MESSAGE_PLUGIN_ERROR_HTTP_UNAUTHORIZED          = 401,
+       MESSAGE_PLUGIN_ERROR_HTTP_FORBIDDEN             = 403,
+       MESSAGE_PLUGIN_ERROR_HTTP_NOT_FOUND             = 404,
+       MESSAGE_PLUGIN_ERROR_HTTP_METHOD_NOT_ALLOWED    = 405,
+       MESSAGE_PLUGIN_ERROR_HTTP_BAD_GATEWAY           = 502,
+       MESSAGE_PLUGIN_ERROR_HTTP_SERVICE_UNAVAILBLE    = 503,
+       MESSAGE_PLUGIN_ERROR_HTTP_INSUFFICIENT_STORAGE  = 507,
+       MESSAGE_PLUGIN_ERROR_HTTP_ETC                   = 598,
+       MESSAGE_PLUGIN_ERROR_HTTP_UNKNOWN               = 599,
+
+       MESSAGE_PLUGIN_ERROR_NETWORK_DEVICE_OFFLINE     = 601,
+       MESSAGE_PLUGIN_ERROR_NETWORK_DEVICE_CONFUSED    = 602,
+       MESSAGE_PLUGIN_ERROR_NETWORK_SOCKET_ISSUE       = 603,
+       MESSAGE_PLUGIN_ERROR_NETWORK_SERVER_NOT_RESPONSE= 604,
+       MESSAGE_PLUGIN_ERROR_NEWTORK_ETC                = 648,
+       MESSAGE_PLUGIN_ERROR_NEWTORK_UNKNOWN            = 649,
+
+       MESSAGE_PLUGIN_ERROR_AUTH_FAILED                = 701,
+       MESSAGE_PLUGIN_ERROR_AUTH_ETC                   = 718,
+       MESSAGE_PLUGIN_ERROR_AUTH_UNKNOWN               = 719,
+
+       MESSAGE_PLUGIN_ERROR_MEMORY_ALLOCATION_FAILED   = 801,
+       MESSAGE_PLUGIN_ERROR_MEMORY_ETC                 = 808,
+       MESSAGE_PLUGIN_ERROR_MEMORY_UNKNOWN             = 809,
+
+       MESSAGE_PLUGIN_ERROR_THREAD_CREATE_FAILED       = 821,
+       MESSAGE_PLUGIN_ERROR_THREAD_STOPPED             = 822,
+       MESSAGE_PLUGIN_ERROR_THREAD_ETC                 = 828,
+       MESSAGE_PLUGIN_ERROR_THREAD_UNNOWN              = 829,
+
+       MESSAGE_PLUGIN_ERROR_ETC                        = 998,
+       MESSAGE_PLUGIN_ERROR_UNKNOWN                    = 999,
+} message_plugin_internal_error_code_e;
+
+typedef enum _message_connection_policy_e
+{
+       MESSAGE_CONNECTION_POLICY_AUTO          = 0,
+       MESSAGE_CONNECTION_POLICY_CONNECT       = 1,
+       MESSAGE_CONNECTION_POLICY_DISCONNECT    = 2,
+} message_connection_policy_e;
+
+/**
+ * @ brief Message plugin's TCP connection state flag
+ */
+typedef enum message_connection_state_e
+{
+       MESSAGE_CONNECTION_STATE_INIT           = 0,    // init value (after create_context)
+       MESSAGE_CONNECTION_STATE_READY          = 1,    // thread running (after connect) before channel_auth
+       MESSAGE_CONNECTION_STATE_CONNECT        = 2,    // connection authenticated (after channel_auth_reply)
+       MESSAGE_CONNECTION_STATE_DISCONNECTED   = 3,    // connection was stopped explicitly (after disconnect)
+       MESSAGE_CONNECTION_STATE_INTERRUPTED    = 4,    // connection was stopped inadventently (by network/server/etc issue)
+       MESSAGE_CONNECTION_STATE_MAX            = 5,
+} message_connection_state_t;
+
+/**
+ * @ brief Message adaptor plugin handle
+ */
+typedef struct message_adaptor_plugin_s *message_adaptor_plugin_h;
+
+/**
+ * @ brief Message adaptor
+ */
+typedef struct message_adaptor_s *message_adaptor_h;
+
+/**
+ * @ brief Message adaptor error code
+ */
+typedef struct message_adaptor_error_code_s
+{
+       char *code;
+       char *msg;
+} message_adaptor_error_code_t;
+typedef struct message_adaptor_error_code_s *message_adaptor_error_code_h;
+
+/**
+ * @ brief Message adaptor violated user structure
+ */
+typedef struct message_adaptor_did_violation_users_s
+{
+       long long int usera;
+       long long int userb;
+} message_adaptor_did_violation_users_t;
+typedef struct message_adaptor_did_violation_users_s *message_adaptor_did_violation_users_h;
+
+/**
+ * @ brief Message adaptor wrong receiver structure
+ */
+typedef struct
+{
+       long long int *invalid_receivers;
+       unsigned int invalid_receivers_len;
+       long long int *interrupted_receivers;
+       unsigned int interrupted_receivers_len;
+       long long int *disabled_receivers;
+       unsigned int disabled_receivers_len;
+       long long int *existing_chatmember;
+       unsigned int existing_chatmembers_len;
+       struct message_adaptor_did_violation_users_s * did_violation_users;
+       unsigned int did_violation_users_len;
+       long long int *invitation_denieds;
+       unsigned int invitation_denieds_len;
+} message_adaptor_wrong_receiver_s;
+
+/**
+ * @ brief Message adaptor chat message structure
+ */
+typedef struct
+{
+       long long int msg_id;
+       int msg_type;
+       char *chatmsg;
+       int message_ttl;
+} message_adaptor_chat_msg_s;
+
+/**
+ * @ brief Message adaptor processed message structure
+ */
+typedef struct
+{
+       long long int msg_id;
+       long long int sent_time;
+} message_adaptor_processed_msg_s;
+
+/**
+ * @ brief Message adaptor deliveryAck structure
+ */
+typedef struct
+{
+       long long int userId;
+       long long int msgId;
+       long long int timestamp;
+} message_adaptor_delivery_ack_s;
+
+/**
+ * @ brief Message adaptor read_ack structure
+ */
+typedef struct
+{
+       long long int userId;
+       long long int msgId;
+       long long int timestamp;
+} message_adaptor_read_ack_s;
+
+/**
+ * @ brief Message adaptor ordered chat member structure
+ */
+typedef struct
+{
+       long long int userId;
+       long long int available;
+       char *name;
+} message_adaptor_ordered_chat_member_s;
+
+/**
+ * @ brief Message adaptor inbox entry structure
+ */
+typedef struct _message_inboxentry
+{
+       long long int msgId;
+       int msgType;
+       long long int sender;
+       long long int receiver;
+       long long int sentTime;
+       char *chatMsg;
+       long long int chatroomId;
+       int chatType;
+       int message_ttl;
+} message_inboxentry_t;
+
+typedef message_inboxentry_t message_adaptor_inbox_message_s;
+
+/**
+ * @ brief Message adaptor plugin context structure
+ */
+typedef struct message_adaptor_plugin_context_s
+{
+       long long int duid;
+       char *access_token;
+       char *app_id;
+       int service_id;
+       char *app_key;
+       char *uid;
+       char *imei;
+       char *imsi;
+
+       GMutex connection_state_mutex;
+       message_connection_state_t connection_state;
+       message_connection_policy_e connection_policy;
+
+       // Encryption
+       unsigned char enc_key[32];
+       unsigned char enc_vec[16];
+       //bool enc_key_updated;
+       unsigned char gpb_key[32];
+       unsigned char gpb_vec[16];
+       //bool gpb_key_updated;
+       unsigned char exp_key[32];
+       unsigned char exp_vec[16];
+       //bool exp_key_updated;
+
+       char *plugin_uri;
+
+       GMutex plugin_data_mutex;
+       void *plugin_data;
+} message_adaptor_plugin_context_t;
+
+typedef struct message_adaptor_plugin_context_s *message_adaptor_plugin_context_h;
+
+/**
+ * @ brief Message adaptor result code for internal use
+ */
+typedef enum message_plugin_result_code_e
+{
+       MESSAGE_PLUGIN_RESULT_SUCCEDED = 0,
+       MESSAGE_PLUGIN_RESULT_FAILED = -1,
+       MESSAGE_PLUGIN_RESULT_CANCELED = -2
+} message_plugin_result_code_t;
+
+typedef struct curl_cb_data_s
+{
+       char *data;
+       int size;
+} curl_cb_data_t;
+
+/**
+ * @ brief Message adaptor phone number structure
+ */
+typedef struct
+{
+       char *phonenumber;
+       char *ccc;
+} message_adaptor_phone_number_s;
+
+/**
+ * @ brief Message adaptor chat id structure
+ */
+typedef struct
+{
+       long long int chatid;
+       char *msisdn;
+} message_adaptor_chat_id_s;
+
+/**
+ * @ brief Message adaptor end chat structure
+ */
+typedef struct {
+       long long int chatroom_id;
+       bool deny_invitation;
+} message_adaptor_end_chat_s;
+
+void message_adaptor_destroy_chat_msg_s(message_adaptor_chat_msg_s *msg);
+void message_adaptor_destroy_processed_msg_s(message_adaptor_processed_msg_s *msg);
+void message_adaptor_destroy_delivery_ack_s(message_adaptor_delivery_ack_s *ack);
+void message_adaptor_destroy_read_ack_s(message_adaptor_read_ack_s *ack);
+void message_adaptor_destroy_ordered_chat_member_s(message_adaptor_ordered_chat_member_s *member);
+void message_adaptor_destroy_inbox_message_s(message_adaptor_inbox_message_s *msg);
+void message_adaptor_destroy_phone_number_s(message_adaptor_phone_number_s *num);
+void message_adaptor_destroy_chat_id_s(message_adaptor_chat_id_s *id);
+void message_adaptor_destroy_end_chat_s(message_adaptor_end_chat_s *msg);
+
+/**
+* @brief The handle for Message Plugin Listener
+*/
+typedef struct message_adaptor_plugin_listener_s *message_adaptor_plugin_listener_h;
+
+/**
+ * @ brief Message adaptor plugin handle
+ */
+typedef struct message_adaptor_plugin_handle_s
+{
+       // Mandatory functions to handle plugin in adaptor
+       //struct message_adaptor_plugin_handle_s * (*create_plugin_handle)(void);
+       message_error_code_t (*create_context)(message_adaptor_plugin_context_h *context,
+                                                       char *duid,
+                                                       char *access_token,
+                                                       char *app_id,
+                                                       int service_id);
+
+       message_error_code_t (*destroy_context)(message_adaptor_plugin_context_h context);
+
+       message_error_code_t (*destroy_handle)(struct message_adaptor_plugin_handle_s *handle);
+       message_error_code_t (*set_listener)(message_adaptor_plugin_listener_h listener);
+       message_error_code_t (*unset_listener)(void);
+
+       message_error_code_t (*set_server_info)(message_adaptor_plugin_context_h context,
+                                                       GHashTable *server_info,
+                                                       void *request,
+                                                       message_adaptor_error_code_h *error,
+                                                       void *response);
+
+       message_error_code_t (*get_key)(message_adaptor_plugin_context_h handle,
+                                                       char **in_uid,
+                                                       char **in_gcmid,
+                                                       char **in_del_gcm_id,
+                                                       char **key,
+                                                       char **expiredkey,
+                                                       char **gpbauthkey,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void **server_data);
+
+       message_error_code_t (*request_chat_id) (message_adaptor_plugin_context_h handle,
+                                                       char *uid,
+                                                       message_adaptor_phone_number_s **phone_numbers,
+                                                       unsigned int phone_numbers_len,
+                                                       void *user_data,
+                                                       message_adaptor_chat_id_s ***chat_ids,
+                                                       unsigned int *chat_ids_len,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void **server_data);
+
+       message_error_code_t (*request_msisdn) (message_adaptor_plugin_context_h handle,
+                                                       char *uid,
+                                                       long long int *chat_ids,
+                                                       unsigned int chat_ids_len,
+                                                       void *user_data,
+                                                       message_adaptor_chat_id_s ***msisdns,
+                                                       unsigned int *msisdns_len,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void **server_data);
+
+       message_error_code_t (*channel_auth_request)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       const char *uid,
+                                                       long long int duid,
+                                                       const char *appid,
+                                                       const char *access_token,
+                                                       int timeout_second,
+                                                       void *user_data,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       message_error_code_t (*client_echo_reply) (message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*create_chatroom_request)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       int *chat_type,
+                                                       long long int **receivers,
+                                                       int *receivers_len,
+                                                       const char *chatroom_title,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*change_chatroom_meta_request)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       const char *chatroom_title,
+                                                       int default_message_ttl,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*chat_request)(message_adaptor_plugin_context_h context,\
+                                                       long long int *request_id,
+                                                       long long int *chatroom_id,
+                                                       message_adaptor_chat_msg_s *msgs,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*allow_chat_request)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       long long int *chatroom_id,
+                                                       bool is_auto_allow,
+                                                       int max_count,
+                                                       bool need_delivery_ack,
+                                                       long long int delivery_ack_timestamp,
+                                                       bool need_read_ack,
+                                                       long long int last_read_ack_timestamp,
+                                                       bool need_ordered_chat_member_list,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*get_all_unread_message_request)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       int *max_count,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+
+       message_error_code_t (*forward_online_message_reply)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       long long int *chatroom_id,
+                                                       bool *mark_as_read,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*forward_unread_message_reply)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       const char **next_pagination_key,
+                                                       int *max_count,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*read_message_request)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       long long int *chatroom_id,
+                                                       message_inboxentry_t *inbox_msg,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*invite_request)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       long long int *chatroom_id,
+                                                       long long int *inviting_members,
+                                                       int *inviting_members_len,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*end_chat_request)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       message_adaptor_end_chat_s **end_chats,
+                                                       int *end_chats_len,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*unseal_message_request)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       long long int *chatroom_id,
+                                                       long long int *sender_id,
+                                                       long long int *message_id,
+                                                       const char *message_detail,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*save_call_log_request)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       long long int *chatroom_id,
+                                                       const char **call_id,
+                                                       const char **call_log_type,
+                                                       long long int *call_sender_id,
+                                                       long long int *call_receiver_id,
+                                                       int *conversaction_second,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*current_time_request)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*is_typing)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       long long int *chatroom_id,
+                                                       char **state,
+                                                       int *chat_type,
+                                                       int *refreshtime,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       //message_error_code_t (*message_set_key)(message_adaptor_plugin_context_h context, char *key, bool is_gpb);
+       message_error_code_t (*connect_to_server)(message_adaptor_plugin_context_h context);
+       message_error_code_t (*decode_push_message)(message_adaptor_plugin_context_h context, char *in_msg, char **out_msg);
+       message_error_code_t (*disconnect_to_server)(message_adaptor_plugin_context_h context);
+       message_error_code_t (*get_connection_state)(message_adaptor_plugin_context_h context,
+                                                       message_connection_state_t *state);
+       char *plugin_uri;               // get from config file
+
+} message_adaptor_plugin_handle_t;
+typedef struct message_adaptor_plugin_handle_s *message_adaptor_plugin_handle_h;
+
+
+/**
+ * Callback function variable for service channel (= service adaptor)
+ */
+
+/**
+* @brief Callback for ClientEcho API(sent from remote server, referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data     specifies additional reply data from server(unused)
+* @pre  ClientEcho()(requested by remote server) will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_client_echo_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_create_chatroom_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   chatroom_id             specifies chatroom id
+* @param[in]   wrong_receiver  specifies wrong receivers information
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_create_chatroom_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_create_chatroom_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               int default_message_ttl,
+                                               message_adaptor_wrong_receiver_s *wrong_receiver,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+typedef void (*message_adaptor_service_change_chatroom_meta_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_chat_request API (referenced by Service Adaptor)
+* @param[in]   request_id                      specifies request id for received data
+* @param[in]   chatroom_id                     specifies chatroom id
+* @param[in]   processed_msgs          specifies processed message information
+* @param[in]   processed_msgs_len      specifies the number of processed message
+* @param[in]   error_code                      specifies error code
+* @param[in]   server_data                     specifies additional reply data from server(unused)
+* @pre  message_adaptor_chat_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_chat_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_processed_msg_s **processed_msgs,
+                                               unsigned int processed_msgs_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_allow_chat_request API (referenced by Service Adaptor)
+* @param[in]   request_id                                      specifies request id for received data
+* @param[in]   chatroom_id                                     specifies chatroom id
+* @param[in]   deliveryacks                                    specifies last receipt messages information for each user
+* @param[in]   deliveryacks_len                                specifies the number of deliveryacks
+* @param[in]   read_acks                                       specifies last read message information for each user
+* @param[in]   read_acks_len                           specifies the number of wartermarks
+* @param[in]   ordered_chat_members                    specifies chat member list aligned to participation order
+* @param[in]   ordered_chat_members_len                specifies the number of ordered_chat_members
+* @param[in]   error_code                                      specifies error code
+* @param[in]   server_data                                     specifies additional reply data from server(unused)
+* @pre  message_adaptor_allow_chat_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_allow_chat_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_delivery_ack_s **deliveryacks,
+                                               unsigned int deliveryacks_len,
+                                               unsigned long long last_delivery_ack_timestamp,
+                                               message_adaptor_read_ack_s **read_acks,
+                                               unsigned int read_acks_len,
+                                               unsigned long long last_read_ack_timestamp,
+                                               message_adaptor_ordered_chat_member_s **ordered_chat_members,
+                                               unsigned int ordered_chat_members_len,
+                                               const char *chatroom_title,
+                                               int default_message_ttl,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_get_all_unread_message_request API (referenced by Service Adaptor)
+* @param[in]   request_id      specifies request id for received data
+* @param[in]   error_code      specifies error code
+* @param[in]   server_data     specifies additional reply data from server(unused)
+* @pre  message_adaptor_get_all_unread_message_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_get_all_unread_message_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for ForwardOnlineMessage API (sent from remote server, referenced by Service Adaptor)
+* @details This function is used for transferring a message from server to client requested by user
+*                who sent request messages via message_adaptor_chat_request()
+* @param[in]   request_id      specifies request id for received data
+* @param[in]   chatroom_id     specifies chatroom id
+* @param[in]   chat_type               specifies chat room type(0: SINGLE, 1: GROUP)
+* @param[in]   inbox_msg       specifies one message transferred from sender to receiver
+* @param[in]   error_code      specifies error code
+* @param[in]   server_data     specifies additional reply data from server(unused)
+* @pre  ForwardOnlineMessage()(requested by remote server) will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_forward_online_message_request_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               int chat_type,
+                                               message_inboxentry_t *inbox_msg,
+                                               bool skip_reply,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for ForwardUnreadMessage API (sent from remote server, referenced by Service Adaptor)
+* @details This function is used for transferring unread messages from server to client requested by user
+*                who sent request messages via message_adaptor_get_all_unread_message_request() or
+*                message_adaptor_allow_chat_request()
+* @param[in]   request_id                      specifies request id for received data
+* @param[in]   inbox_msgs                      specifies messages transferred from sender to receiver
+* @param[in]   inbox_msg_len           specifies the number of inbox message
+* @param[in]   next_pagination_key     specifies value for using pagination(NULL for unused case)
+* @param[in]   error_code                      specifies error code
+* @param[in]   server_data                     specifies additional reply data from server(unused)
+* @pre  ForwardUnreadMessage()(requested by remote server) will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_forward_unread_message_request_cb) (message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_inboxentry_t ***inbox_msgs,
+                                               unsigned int inbox_msgs_len,
+                                               char **next_pagination_key,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_read_message_request API (referenced by Service Adaptor)
+* @param[in]   request_id      specifies request id for received data
+* @param[in]   chatroom_id     specifies chatroom id
+* @param[in]   error_code      specifies error code
+* @param[in]   server_data     specifies additional reply data from server(unused)
+* @pre  message_adaptor_read_message_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_read_message_reply_cb) (message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_invite_chat_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   chatroom_id             specifies chatroom id
+* @param[in]   sent_time               specifies time when server received request message by client
+* @param[in]   wrong_receiver  specifies wrong receivers information
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_invite_chat_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_invite_chat_reply_cb) (message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               long long int sent_time,
+                                               message_adaptor_wrong_receiver_s *wrong_receiver,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_end_chat_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_end_chat_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_end_chat_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_unseal_message_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_unseal_message_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_unseal_message_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_save_call_log_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_save_call_log_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_save_call_log_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+
+/**
+* @brief Callback for message_adaptor_current_time_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   current_time_millis     specifies current UTC time in milliseconds
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_current_time_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_current_time_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int current_time_millis,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+typedef void (*message_adaptor_service_typing_updated_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               long long int *sender,
+                                               char ** state,
+                                               int *contentType,
+                                               int *refershTime,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for notification of termination of Listener(referenced by Service Adaptor)
+* @details This function called when channel is disconnected by server
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @return      void.
+*/
+typedef void (*message_adaptor_service_completion_cb)(message_adaptor_plugin_context_h context,
+                                               message_connection_state_t state,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+
+
+typedef struct message_adaptor_listener_s
+{
+       void (*client_echo_cb)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*create_chatroom_reply_cb)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       int default_message_ttl,
+                                                       message_adaptor_wrong_receiver_s *wrong_receiver,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*change_chatroom_meta_reply_cb)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*chat_reply_cb)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       message_adaptor_processed_msg_s **processed_msgs,
+                                                       unsigned int processed_msgs_len,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*allow_chat_reply_cb) (message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       message_adaptor_delivery_ack_s **deliveryacks,
+                                                       unsigned int deliveryacks_len,
+                                                       unsigned long long last_delivery_ack_timestamp,
+                                                       message_adaptor_read_ack_s **read_acks,
+                                                       unsigned int read_acks_len,
+                                                       unsigned long long last_read_ack_timestamp,
+                                                       message_adaptor_ordered_chat_member_s **ordered_chat_members,
+                                                       unsigned int ordered_chat_members_len,
+                                                       const char *chatroom_title,
+                                                       int default_message_ttl,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+
+       void (*get_all_unread_message_reply_cb) (message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*forward_online_message_request_cb)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       int chat_type,
+                                                       message_inboxentry_t *inbox_msg,
+                                                       bool skip_reply,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+
+       void (*forward_unread_message_request_cb)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       message_inboxentry_t ***inbox_msgs,
+                                                       unsigned int inbox_msgs_len,
+                                                       char **next_pagination_key,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*read_message_reply_cb) (message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*invite_chat_reply_cb) (message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       long long int sent_time,
+                                                       message_adaptor_wrong_receiver_s *wrong_receiver,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*end_chat_reply_cb) (message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*unseal_message_reply_cb) (message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*save_call_log_reply_cb) (message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*current_time_reply_cb)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int current_time_millis,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*typing_updated_cb)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       long long int *sender,
+                                                       char ** state,
+                                                       int *contentType,
+                                                       int *refershTime,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*completion_cb)(message_adaptor_plugin_context_h context,
+                                                       message_connection_state_t state,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data );
+
+
+} message_adaptor_listener_t;
+typedef struct message_adaptor_listener_s *message_adaptor_listener_h;
+
+
+/**
+ * Message adaptor listener for plugins
+ * Listener is used by plugins
+ */
+
+
+/**
+* @brief Callback for ClientEcho API(sent from remote server)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data     specifies additional reply data from server(unused)
+* @pre  ClientEcho()(requested by remote server) will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_client_echo_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_plugin_handle->create_chatroom_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   chatroom_id             specifies chatroom id
+* @param[in]   wrong_receiver  specifies wrong receivers information
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_plugin_handle->create_chatroom_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_create_chatroom_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               int default_message_ttl,
+                                               message_adaptor_wrong_receiver_s *wrong_receiver,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+typedef void (*message_adaptor_plugin_change_chatroom_meta_reply_cb)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+/**
+* @brief Callback for message_adaptor_plugin_handle->chat_request API (referenced by Service Adaptor)
+* @param[in]   request_id                      specifies request id for received data
+* @param[in]   chatroom_id                     specifies chatroom id
+* @param[in]   processed_msgs          specifies processed message information
+* @param[in]   processed_msgs_len      specifies the number of processed message
+* @param[in]   error_code                      specifies error code
+* @param[in]   server_data                     specifies additional reply data from server(unused)
+* @pre  message_adaptor_plugin_handle->chat_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_chat_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_processed_msg_s **processed_msgs,
+                                               unsigned int processed_msgs_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_plugin_handle->allow_chat_request API (referenced by Service Adaptor)
+* @param[in]   request_id                                      specifies request id for received data
+* @param[in]   chatroom_id                                     specifies chatroom id
+* @param[in]   deliveryacks                                    specifies last receipt messages information for each user
+* @param[in]   deliveryacks_len                                specifies the number of deliveryacks
+* @param[in]   read_acks                                       specifies last read message information for each user
+* @param[in]   read_acks_len                           specifies the number of wartermarks
+* @param[in]   ordered_chat_members                    specifies chat member list aligned to participation order
+* @param[in]   ordered_chat_members_len                specifies the number of ordered_chat_members
+* @param[in]   error_code                                      specifies error code
+* @param[in]   server_data                                     specifies additional reply data from server(unused)
+* @pre  message_adaptor_plugin_handle->allow_chat_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_allow_chat_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_delivery_ack_s **deliveryacks,
+                                               unsigned int deliveryacks_len,
+                                               unsigned long long last_delivery_ack_timestamp,
+                                               message_adaptor_read_ack_s **read_acks,
+                                               unsigned int read_acks_len,
+                                               unsigned long long last_read_ack_timestamp,
+                                               message_adaptor_ordered_chat_member_s **ordered_chat_members,
+                                               unsigned int ordered_chat_members_len,
+                                               const char *chatroom_title,
+                                               int default_message_ttl,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_plugin_handle->get_all_unread_message_request API (referenced by Service Adaptor)
+* @param[in]   request_id      specifies request id for received data
+* @param[in]   error_code      specifies error code
+* @param[in]   server_data     specifies additional reply data from server(unused)
+* @pre  message_adaptor_plugin_handle->get_all_unread_message_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_get_all_unread_message_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for ForwardOnlineMessage API (sent from remote server, referenced by Service Adaptor)
+* @details This function is used for transferring a message from server to client requested by user
+*                who sent request messages via message_adaptor_chat_request()
+* @param[in]   request_id      specifies request id for received data
+* @param[in]   chatroom_id     specifies chatroom id
+* @param[in]   chat_type               specifies chat room type(0: SINGLE, 1: GROUP)
+* @param[in]   inbox_msg       specifies one message transferred from sender to receiver
+* @param[in]   error_code      specifies error code
+* @param[in]   server_data     specifies additional reply data from server(unused)
+* @pre  ForwardOnlineMessage()(requested by remote server) will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_forward_online_message_request_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               int chat_type,
+                                               message_inboxentry_t *inbox_msg,
+                                               bool skip_reply,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for ForwardUnreadMessage API (sent from remote server, referenced by Service Adaptor)
+* @details This function is used for transferring unread messages from server to client requested by user
+*                who sent request messages via message_adaptor_get_all_unread_message_request() or
+*                message_adaptor_allow_chat_request()
+* @param[in]   request_id                      specifies request id for received data
+* @param[in]   inbox_msgs                      specifies messages transferred from sender to receiver
+* @param[in]   inbox_msg_len           specifies the number of inbox message
+* @param[in]   next_pagination_key     specifies value for using pagination(NULL for unused case)
+* @param[in]   error_code                      specifies error code
+* @param[in]   server_data                     specifies additional reply data from server(unused)
+* @pre  ForwardUnreadMessage()(requested by remote server) will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_forward_unread_message_request_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_inboxentry_t ***inbox_msgs,
+                                               unsigned int inbox_msgs_len,
+                                               char **next_pagination_key,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_plugin_handle->read_message_request API (referenced by Service Adaptor)
+* @param[in]   request_id      specifies request id for received data
+* @param[in]   chatroom_id     specifies chatroom id
+* @param[in]   error_code      specifies error code
+* @param[in]   server_data     specifies additional reply data from server(unused)
+* @pre  message_adaptor_plugin_handle->read_message_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_read_message_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_plugin_handle->invite_chat_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   chatroom_id             specifies chatroom id
+* @param[in]   sent_time               specifies time when server received request message by client
+* @param[in]   wrong_receiver  specifies wrong receivers information
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_plugin_handle->invite_chat_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_invite_chat_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               long long int sent_time,
+                                               message_adaptor_wrong_receiver_s *wrong_receiver,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_plugin_handle->end_chat_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_plugin_handle->end_chat_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_end_chat_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_plugin_handle->unseal_message_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   chatroom_id             specifies chatroom id
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_plugin_handle->end_chat_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_unseal_message_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_plugin_handle->save_call_log_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_plugin_handle->save_call_log_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_save_call_log_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+
+/**
+* @brief Callback for  message_adaptor_plugin_handle->current_time_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   current_time_millis     specifies current UTC time in milliseconds
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre   message_adaptor_plugin_handle->current_time_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_current_time_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int current_time_millis,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+typedef void (*message_adaptor_plugin_typing_updated_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               long long int *sender,
+                                               char ** state,
+                                               int *contentType,
+                                               int *refershTime,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for notification of termination of Listener(referenced by Service Adaptor)
+* @details This function called when channel is disconnected by server
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_completion_cb)(message_adaptor_plugin_context_h context,
+                                               message_connection_state_t state,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+ * Message adaptor listener for plugins
+ * Listener is used by plugins
+ */
+typedef struct message_adaptor_plugin_listener_s
+{
+       message_adaptor_plugin_client_echo_cb message_adaptor_client_echo;
+       message_adaptor_plugin_create_chatroom_reply_cb message_adaptor_create_chatroom_reply;
+       message_adaptor_plugin_change_chatroom_meta_reply_cb message_adaptor_change_chatroom_meta_reply;
+       message_adaptor_plugin_chat_reply_cb message_adaptor_chat_reply;
+       message_adaptor_plugin_allow_chat_reply_cb message_adaptor_allow_chat_reply;
+       message_adaptor_plugin_get_all_unread_message_reply_cb message_adaptor_get_all_unread_message_reply;
+       message_adaptor_plugin_forward_online_message_request_cb message_adaptor_forward_online_message_request;
+       message_adaptor_plugin_forward_unread_message_request_cb message_adaptor_forward_unread_message_request;
+       message_adaptor_plugin_read_message_reply_cb message_adaptor_read_message_reply;
+       message_adaptor_plugin_invite_chat_reply_cb message_adaptor_invite_chat_reply;
+       message_adaptor_plugin_end_chat_reply_cb message_adaptor_end_chat_reply;
+       message_adaptor_plugin_unseal_message_reply_cb message_adaptor_unseal_message_reply;
+       message_adaptor_plugin_save_call_log_reply_cb message_adaptor_save_call_log_reply;
+       message_adaptor_plugin_current_time_reply_cb message_adaptor_current_time_reply;
+       message_adaptor_plugin_typing_updated_cb message_adaptor_typing_updated;
+       message_adaptor_plugin_completion_cb message_adaptor_completion;
+
+} message_adaptor_plugin_listener_t;
+
+/**
+ * Loads plugin from selected path
+ */
+ EXPORT_API
+int message_adaptor_load_plugin(message_adaptor_h adaptor, const char *plugin_path);
+
+/**
+ * Unloads selected plugin
+ */
+ EXPORT_API
+int message_adaptor_unload_plugin(message_adaptor_h adaptor, message_adaptor_plugin_h plugin);
+
+ EXPORT_API
+message_error_code_t message_adaptor_set_connected(message_adaptor_plugin_h plugin, int connected);
+
+ EXPORT_API
+message_error_code_t message_adaptor_wait_connected(message_adaptor_plugin_h plugin);
+
+/**
+ * Gets plugin name
+ */
+ EXPORT_API
+const char *message_adaptor_get_plugin_uri(message_adaptor_plugin_h plugin);
+
+/**
+ * Refresh access token
+ */
+EXPORT_API
+message_error_code_t message_adaptor_refresh_access_token(message_adaptor_plugin_context_h context,
+                                               const char *new_access_token);
+
+/**
+ * Refresh uid
+ */
+EXPORT_API
+message_error_code_t message_adaptor_refresh_uid(message_adaptor_plugin_context_h context,
+                                               const char *new_uid);
+
+/**
+ * Create error code
+ */
+EXPORT_API
+message_adaptor_error_code_h message_adaptor_create_error_code(const char *code, const char *msg);
+
+/**
+ * Destroy error code
+ */
+EXPORT_API
+void message_adaptor_destroy_error_code(message_adaptor_error_code_h *error_code);
+
+/**
+ * Creates message adaptor
+ */
+EXPORT_API
+message_adaptor_h message_adaptor_create(const char *plugins_dir);
+
+/**
+ * Destroys message adaptor
+ * Destroys message adaptor. If message adaptor was started it is stopped first.
+ */
+EXPORT_API
+void message_adaptor_destroy(message_adaptor_h adaptor);
+
+/**
+ * Starts message adaptor
+ * Starts message adaptor and loads plugins that were found in plugins search dir
+ * specified in message_adaptor_create
+ */
+EXPORT_API
+int message_adaptor_start(message_adaptor_h adaptor);
+
+/**
+ * Stops message adaptor.
+ */
+EXPORT_API
+int message_adaptor_stop(message_adaptor_h adaptor);
+
+/**
+ * Registers plugin state listener
+ */
+EXPORT_API
+int message_adaptor_register_listener(message_adaptor_h adaptor, message_adaptor_listener_h listener);
+
+/**
+ * Unregisters plugin state listener
+ */
+EXPORT_API
+int message_adaptor_unregister_listener(message_adaptor_h adaptor, message_adaptor_listener_h listener);
+
+/**
+ * Creates plugin context.
+ */
+EXPORT_API
+message_adaptor_plugin_context_h message_adaptor_create_plugin_context(message_adaptor_plugin_h plugin,
+                                               char *plugin_uri,
+                                               char *duid,
+                                               char *access_token,
+                                               char *app_id,
+                                               int service_id);
+
+/**
+ * Destroys plugin context.
+ */
+EXPORT_API
+void message_adaptor_destroy_plugin_context(message_adaptor_plugin_h plugin, message_adaptor_plugin_context_h plugin_context);
+
+/**
+ * Gets plugin with specified unique name
+ */
+EXPORT_API
+message_adaptor_plugin_h message_adaptor_get_plugin_by_name(message_adaptor_h adaptor, const char *plugin_uri);
+
+////////////////////////////////////////////////////////////
+// Adaptor Plugin call Functions
+////////////////////////////////////////////////////////////
+
+/**
+* @brief Set server information for Message Plugin
+*
+* @param[in]   plugin                          specifies Message Adaptor Plugin handle
+* @param[in]   context                         specifies Message Adaptor Plugin Context handle
+* @param[in]   server_info                     specifies server information for Message Plugin
+* @param[in]   request                         specifies optional parameter
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t - MESSAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+message_error_code_t message_adaptor_set_server_info(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               GHashTable *server_info,
+                                               void *request,
+                                               message_adaptor_error_code_h *error,
+                                               void *response);
+/**
+* @brief Request encryption/decryption key from remote server
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   in_gcmid                specifies GCM Registration ID for use of Google Cloud Messaging
+* @param[in]   in_del_gcm_id   specifies Paramter for deletion of gcmid in db
+* @param[out]  key                     specifies user key for en/decryption of messages
+* @param[out]  expiredkey      specifies expired key
+* @param[out]  gpbauthkey      specifies system key for en/decryption of ChannelAuth Request/Reply messages
+* @param[out]  error_code      specifies error code
+* @param[out]  server_data     specifies additional reply data from server(JSON format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in message_error_code_e - MESSAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+message_error_code_t message_adaptor_get_key(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               char **in_gcmid,
+                                               char **in_del_gcm_id,
+                                               char **key,
+                                               char **expiredkey,
+                                               char **gpbauthkey,
+                                               message_adaptor_error_code_t **error_code,
+                                               void **server_data);
+
+/**
+* @brief Request Chat ID corresponds to MSISDN to remote server
+* @param[in]   plugin                          specifies Message-adaptor Plugin handle
+* @param[in]   context                         specifies Message-adaptor Plugin context
+* @param[in]   phone_numbers           specifies List of phone numbers to request chat id
+* @param[in]   phone_numbers_len       specifies the number of phone numbers
+* @param[in]   user_data                       specifies additional input data(JSON format, unused)
+* @param[out]  chat_ids                                specifies chat ids correspond to requested phone numbers
+* @param[out]  chat_ids_len                    specifies the number of chat ids
+* @param[out]  error_code                      specifies error code
+* @param[out]  server_data                     specifies additional reply data from server(JSON format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in message_error_code_e - MESSAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+message_error_code_t message_adaptor_request_chat_id(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h handle,
+                                               message_adaptor_phone_number_s **phone_numbers,
+                                               unsigned int phone_numbers_len,
+                                               void *user_data,
+                                               message_adaptor_chat_id_s ***chat_ids,
+                                               unsigned int *chat_ids_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void **server_data);
+
+/**
+* @brief Request MSISDN corresponds to CHAT ID to remote server
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   chat_ids                specifies chat ids correspond to requested phone numbers
+* @param[in]   chat_ids_len    specifies the number of chat ids
+* @param[in]   user_data       specifies additional input data(JSON format, unused)
+* @param[out]  msisdn          specifies List of phone numbers to request chat id
+* @param[out]  msisdn_len      specifies the number of phone numbers
+* @param[out]  error_code      specifies error code
+* @param[out]  server_data     specifies additional reply data from server(JSON format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in message_error_code_e - MESSAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+message_error_code_t message_adaptor_request_msisdn (message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h handle,
+                                               long long int *chat_ids,
+                                               unsigned int chat_ids_len,
+                                               void *user_data,
+                                               message_adaptor_chat_id_s ***msisdns,
+                                               unsigned int *msisdns_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void **server_data);
+
+
+/**
+* @brief Channel Authorization Request.
+*
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   request_id      specifies unique request ID
+* @param[in]   timeout_second  specifies timeout second for wating this function (default = 0 : as long as possible be allowed by plugin)
+* @param[in]   user_data       specifies additional user input data (unused)
+* @param[out]  error_code      specifies error code
+* @param[out]  server_data     specifies additional server output data (unused)
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_channel_auth_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               const int timeout_second,
+                                               void *user_data,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Client Echo Reply.(Client -> Server)
+*
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   request_id      specifies unique request ID
+* @param[in]   error_code      specifies error code
+* @param[in]   server_data     specifies server data to be sent(not used)
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_client_echo_reply (message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Create Chatroom Request.
+*
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   request_id      specifies unique request ID
+* @param[in]   chattype                specifies chat type (0 - SINGLE, 1 - GROUP)
+* @param[in]   receivers               specifies the receivers devices ID
+* @param[in]   receivers_len   specifies the number of receivers
+* @param[in]   user_data       specifies additional user input data (unused)
+* @param[out]  error_code      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_create_chatroom_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               int chat_type,
+                                               long long int **receivers,
+                                               unsigned int receivers_len,
+                                               const char *chatroom_title,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief Change Chatroom meta Request.
+*
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   request_id      specifies unique request ID
+* @param[in]   chattype                specifies chat type (0 - SINGLE, 1 - GROUP)
+* @param[in]   receivers               specifies the receivers devices ID
+* @param[in]   receivers_len   specifies the number of receivers
+* @param[in]   user_data       specifies additional user input data (unused)
+* @param[out]  error_code      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_change_chatroom_meta_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               const char *chatroom_title,
+                                               int default_message_ttl,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+/**
+* @brief Chat Request.
+*
+* @param[in]   plugin                  specifies Message-adaptor Plugin handle
+* @param[in]   context                 specifies Message-adaptor Plugin context
+* @param[in]   request_id              specifies unique request ID
+* @param[in]   chatroom_id             specifies chatroom ID
+* @param[in]   chat_msgs               specifies message data
+* @param[in]   chat_msgs_len   specifies the number of message data
+* @param[in]   user_data               specifies additional user input data (unused)
+* @param[out]  error_code              specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_chat_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_chat_msg_s **chat_msgs,
+                                               unsigned int chat_msgs_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief Allow Chat Request.
+*
+* @param[in]   plugin                                          specifies Message-adaptor Plugin handle
+* @param[in]   context                                         specifies Message-adaptor Plugin context
+* @param[in]   request_id                                      specifies unique request ID
+* @param[in]   chatroom_id                                     specifies chatroom ID
+* @param[in]   max_count                                       specifies the max number of ForwardUnreadMessage (default : 500)
+* @param[in]   need_delivery_ack                               specifies whether receive delivery ack data or not (0 - do not receive delivery ack data, 1 - receive delivery ack data)
+* @param[in]   need_delivery_ack_timestamp     specifies       latest receipt time of delivery ack data
+* @param[in]   need_read_ack                           specifies whether receive water mark data or not (0 - do not receive water mark data, 1 - receive read_ack data)
+* @param[in]   last_read_ack_timestamp         specifies time of last read_ack
+* @param[in]   need_ordered_chat_member_list   specifies whether need odered chat memebr list or not
+* @param[in]   user_data                                       specifies additional user input data (unused)
+* @param[out]  error_code                                      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_allow_chat_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               bool is_auto_allow,
+                                               int max_count,
+                                               bool need_delivery_ack,
+                                               long long int delivery_ack_timestamp,
+                                               bool need_read_ack,
+                                               long long int last_read_ack_timestamp,
+                                               bool need_ordered_chat_member_list,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief Get All Unread Message Request.
+*
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   request_id      specifies unique request ID
+* @param[in]   max_count       specifies the max number of ForwardUnreadMessage (default : 500)
+* @param[in]   user_data       specifies additional user input data (unused)
+* @param[out]  error_code      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_get_all_unread_message_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               int max_count,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief Forward Online Message Reply.
+*
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   request_id      specifies unique request ID
+* @param[in]   chatroom_id     specifies chatroom ID
+* @param[in]   mark_as_read    marks the received message as read
+* @param[in]   user_data       specifies additional user input data (unused)
+* @param[out]  error_code      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_forward_online_message_reply(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               bool mark_as_read,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief Forward Unread Message Reply.
+*
+* @param[in]   plugin                          specifies Message-adaptor Plugin handle
+* @param[in]   context                         specifies Message-adaptor Plugin context
+* @param[in]   request_id                      specifies unique request ID
+* @param[in]   next_pagination_key     specifies the next pagination key
+* @param[in]   max_count                       specifies the max number of unread messages to be shown in one page(default : 500)
+* @param[in]   user_data                       specifies additional user input data (unused)
+* @param[out]  error_code                      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_forward_unread_message_reply(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               const char *next_pagination_key,
+                                               int max_count,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief Read Message Request.
+*
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   request_id      specifies unique request ID
+* @param[in]   chatroom_id     specifies chatroom ID
+* @param[in]   inbox_msg       specifies the message to be read
+* @param[in]   user_data       specifies additional user input data (unused)
+* @param[out]  error_code      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_read_message_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_inboxentry_t *inbox_msg,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief Invite Request.
+*
+* @param[in]   plugin                          specifies Message-adaptor Plugin handle
+* @param[in]   context                         specifies Message-adaptor Plugin context
+* @param[in]   request_id                      specifies unique request ID
+* @param[in]   chatroom_id                     specifies chatroom ID
+* @param[in]   inviting_members                specifies members IDs to be invited to chatroom
+* @param[in]   inviting_members_len    specifies the number of members IDs
+* @param[in]   user_data                       specifies additional user input data (unused)
+* @param[out]  error_code                      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_invite_chat_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               long long int *inviting_members,
+                                               unsigned int inviting_members_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief End Chat Request.
+*
+* @param[in]   plugin                  specifies Message-adaptor Plugin handle
+* @param[in]   context                 specifies Message-adaptor Plugin context
+* @param[in]   request_id              specifies unique request ID
+* @param[in]   end_chats               specifies chatrooms IDs
+* @param[in]   end_chats_len           specifies the number of chatrooms
+* @param[in]   user_data                       specifies additional user input data (unused)
+* @param[out]  error_code                      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_end_chat_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_end_chat_s **end_chats,
+                                               unsigned int end_chats_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief Unseal Message Request.
+*
+* @param[in]   plugin                          specifies Message-adaptor Plugin handle
+* @param[in]   context                         specifies Message-adaptor Plugin context
+* @param[in]   request_id                      specifies unique request ID
+* @param[in]   chatroom_id                     specifies chatroom ID
+* @param[in]   sender_id                       specifies message sender ID for 'Unseal Message'
+* @param[in]   message_id                      specifies message ID for 'Unseal Message'
+* @param[in]   user_data                       specifies additional user input data (unused)
+* @param[out]  error_code                      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_unseal_message_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               long long int sender_id,
+                                               long long int message_id,
+                                               const char *message_detail,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief Save Call Log Request.
+*
+* @param[in]   plugin                          specifies Message-adaptor Plugin handle
+* @param[in]   context                         specifies Message-adaptor Plugin context
+* @param[in]   request_id                      specifies unique request ID
+* @param[in]   chatroom_id                     specifies chatroom ID
+* @param[in]   call_id                         specifies unique call ID
+* @param[in]   call_log_type                   specifies call log type string
+* @param[in]   call_sender_id                  specifies caller's unique ID
+* @param[in]   call_receiver_id                specifies callee's unique ID
+* @param[in]   conversaction_second            specifies calling time
+* @param[in]   user_data                       specifies additional user input data (unused)
+* @param[out]  error_code                      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_save_call_log_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               const char *call_id,
+                                               const char *call_log_type,
+                                               long long int call_sender_id,
+                                               long long int call_receiver_id,
+                                               int conversaction_second,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+
+/**
+* @brief Current Time Request.
+*
+* @param[in]   plugin                  specifies Message-adaptor Plugin handle
+* @param[in]   context                 specifies Message-adaptor Plugin context
+* @param[in]   request_id              specifies unique request ID
+* @param[in]   user_data               specifies additional user input data (unused)
+* @param[out]  error_code              specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_current_time_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+EXPORT_API
+message_error_code_t message_adaptor_is_typing(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int *request_id,
+                                               long long int *chatroom_id,
+                                               char **state,
+                                               int *chat_type,
+                                               int *refreshtime,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+/*
+EXPORT_API
+message_error_code_t message_adaptor_plugin_set_key(message_adaptor_plugin_h plugin,
+                                                                                               message_adaptor_plugin_context_h context,
+                                                                                               char *key_str,
+                                                                                               bool is_gpb);
+*/
+
+/**
+* @brief Establish a TCP server connection
+* @details create socket and establish connection, then start recv listener
+* @param[in]   plugin                  specifies Message-adaptor Plugin handle
+* @param[in]   context                 specifies Message-adaptor Plugin context
+* @param[out]  error_code              specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_connect(message_adaptor_plugin_h plugin, message_adaptor_plugin_context_h context, message_adaptor_error_code_h *error_code);
+
+
+
+/**
+* @brief Disestablish a TCP server connection
+* @details destroy socket and disestablish connection, then stop recv listener
+* @param[in]   plugin                  specifies Message-adaptor Plugin handle
+* @param[in]   context                 specifies Message-adaptor Plugin context
+* @param[out]  error_code              specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_disconnect(message_adaptor_plugin_h plugin, message_adaptor_plugin_context_h context, message_adaptor_error_code_h *error_code);
+
+/**
+* @brief get TCP server connection state
+* @details get connection state flag
+* @param[in]   plugin                  specifies Message-adaptor Plugin handle
+* @param[in]   context                 specifies Message-adaptor Plugin context
+* @param[out]  state                   specifies TCP connection state
+* @param[out]  error_code              specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_get_connection_state(message_adaptor_plugin_h plugin, message_adaptor_plugin_context_h context, message_connection_state_t *state, message_adaptor_error_code_h *error_code);
+
+/**
+* @brief Decode Push Messages received from SPP Push server
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   in_msg          specifies Input Messages(json format, include encrypted fields)
+* @param[out]  out_msg         specifies Output Messages(decrypted)
+* @param[out]  error_code      specifies error to be sent to server
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+
+EXPORT_API
+message_error_code_t message_adaptor_decode_push_message(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               char *in_msg,
+                                               char **out_msg,
+                                               message_adaptor_error_code_h *error_code);
+
+#endif
diff --git a/adaptor/push-adaptor/push-adaptor-log.h b/adaptor/push-adaptor/push-adaptor-log.h
new file mode 100644 (file)
index 0000000..2bd7148
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+* Copyright (c) 2011 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 __PUSH_ADAPTOR_LOG_H__
+#define __PUSH_ADAPTOR_LOG_H__
+
+/**
+ *  HOW TO USE IT:
+ *  First you need to set platform logging on the device:
+ *
+ *    # dlogctrl set platformlog 1
+ *
+ *  After reboot you are able to see logs from this application, when you launch dlogutil with a proper filter e.g.:
+ *
+ *    # dlogutil PUSH_ADAPTOR:D
+ *
+ *  You may use different logging levels as: D (debug), I (info), W (warning), E (error) or F (fatal).
+ *  Higher level messages are included by default e.g. dlogutil CLOUDBOX:W prints warnings but also errors and fatal messages.
+ */
+
+#include <unistd.h>
+#include <linux/unistd.h>
+
+/* These defines must be located before #include <dlog.h> */
+#define TIZEN_ENGINEER_MODE
+// TODO: Investigate why this macro is defined somewhere else
+#ifndef TIZEN_DEBUG_ENABLE
+#define TIZEN_DEBUG_ENABLE
+#endif
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+/* Literal to filter logs from dlogutil */
+#define LOG_TAG "PUSH_ADAPTOR"
+
+#include <dlog.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+       /**
+        *  Colors of font
+        */
+#define FONT_COLOR_RESET      "\033[0m"
+#define FONT_COLOR_BLACK      "\033[30m"             /* Black */
+#define FONT_COLOR_RED        "\033[31m"             /* Red */
+#define FONT_COLOR_GREEN      "\033[32m"             /* Green */
+#define FONT_COLOR_YELLOW     "\033[33m"             /* Yellow */
+#define FONT_COLOR_BLUE       "\033[34m"             /* Blue */
+#define FONT_COLOR_PURPLE     "\033[35m"             /* Purple */
+#define FONT_COLOR_CYAN       "\033[36m"             /* Cyan */
+#define FONT_COLOR_WHITE      "\033[37m"             /* White */
+#define FONT_COLOR_BOLDBLACK  "\033[1m\033[30m"      /* Bold Black */
+#define FONT_COLOR_BOLDRED    "\033[1m\033[31m"      /* Bold Red */
+#define FONT_COLOR_BOLDGREEN  "\033[1m\033[32m"      /* Bold Green */
+#define FONT_COLOR_BOLDYELLOW "\033[1m\033[33m"      /* Bold Yellow */
+#define FONT_COLOR_BOLDBLUE   "\033[1m\033[34m"      /* Bold Blue */
+#define FONT_COLOR_BOLDPURPLE "\033[1m\033[35m"      /* Bold Purple */
+#define FONT_COLOR_BOLDCYAN   "\033[1m\033[36m"      /* Bold Cyan */
+#define FONT_COLOR_BOLDWHITE  "\033[1m\033[37m"      /* Bold White */
+
+       /**
+        *  Gets thread ID
+        */
+#define push_adaptor_gettid() syscall(__NR_gettid)
+
+/**
+ *  @brief Macro for returning value if expression is satisfied
+ *  @param[in]  expr Expression to be checked
+ *  @param[out] val  Value to be returned when expression is true
+ */
+#define push_adaptor_retv_if(expr, val) do { \
+            if(expr) { \
+                LOGE(FONT_COLOR_PURPLE"[%d]"FONT_COLOR_RESET, push_adaptor_gettid());    \
+                return (val); \
+            } \
+        } while (0)
+
+/**
+ * @brief Prints debug messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define push_adaptor_debug(fmt, arg...) do { \
+            LOGD(FONT_COLOR_GREEN"[%d]"fmt""FONT_COLOR_RESET, push_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints info messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define push_adaptor_info(fmt, arg...) do { \
+            LOGI(FONT_COLOR_BLUE"[%d]"fmt""FONT_COLOR_RESET, push_adaptor_gettid() ,##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints warning messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define push_adaptor_warning(fmt, arg...) do { \
+            LOGW(FONT_COLOR_YELLOW"[%d]"fmt""FONT_COLOR_RESET,push_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints error messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define push_adaptor_error(fmt, arg...) do { \
+            LOGE(FONT_COLOR_RED"[%d]"fmt""FONT_COLOR_RESET,push_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints fatal messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define push_adaptor_fatal(fmt, arg...) do { \
+            LOGF(FONT_COLOR_BOLDRED"[%d]"fmt""FONT_COLOR_RESET,push_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints debug message on entry to particular function
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define push_adaptor_debug_func(fmt, arg...) do { \
+            LOGD(FONT_COLOR_CYAN"[%d]"fmt""FONT_COLOR_RESET, push_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+#define plugin_req_enter()                     do { \
+               push_adaptor_info("[ENTER] plugin API call -)) -)) -)) -)) -)) -)) -)) -)) -)) -))"); \
+       } while (0)
+
+#define plugin_req_exit(ret, plugin, error)    do { \
+               push_adaptor_info("[EXIT] plugin API called (%d) ((- ((- ((- ((- ((- ((- ((- ((- ((- ((-", (int)(ret)); \
+               if ((error)) { \
+                       if ((*error)) {\
+                               push_adaptor_error("plugin issued error (%lld) (%s)", (long long int)((*error)->code), (char *)((*error)->msg)); \
+                               char *tem = g_strdup_printf("[PLUGIN_ERROR] URI(%s), MSG(%s)", (char *)((plugin)->handle->plugin_uri), (char *)((*error)->msg)); \
+                               if (tem) { \
+                                       free((*error)->msg); \
+                                       (*error)->msg = tem; \
+                               } \
+                       } \
+               } \
+       } while (0)
+
+#define plugin_req_exit_void()                 do { \
+               push_adaptor_info("[EXIT] plugin API called ((- ((- ((- ((- ((- ((- ((- ((- ((- ((-"); \
+       } while (0)
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __PUSH_ADAPTOR_LOG_H__ */
diff --git a/adaptor/push-adaptor/push-adaptor.c b/adaptor/push-adaptor/push-adaptor.c
new file mode 100644 (file)
index 0000000..af58ea8
--- /dev/null
@@ -0,0 +1,1022 @@
+/*
+* Copyright (c) 2011 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.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <dlfcn.h>
+
+#include "push-adaptor.h"
+#include "push-adaptor-log.h"
+
+/**
+ * Push adaptor plugin
+ */
+typedef struct push_adaptor_plugin_s {
+       push_adaptor_h                  adaptor;                /* Adaptor */
+       char                            *path;                  /* Plugin library path */
+       push_adaptor_plugin_handle_h    handle;                 /* Plugin handle */
+       void                            *dl_handle;             /* Plugin library handle */
+       int                             ref_counter;            /* Plugin reference counter */
+       GMutex                          ref_counter_mutex;      /* Plugin reference counter mutex */
+       push_adaptor_plugin_listener_h  plugin_listener;        /* Plugin callback listener */
+       GMutex                          plugin_listener_mutex;  /* Plugin callback listener mutex */
+} push_adaptor_plugin_t;
+
+/**
+ * Push adaptor
+ */
+typedef struct push_adaptor_s {
+       GMutex  push_adaptor_mutex;             /* Adaptor mutex */
+       int     started;                        /* Started flag */
+       char    *plugins_dir;                   /* Plugins directory path */
+       GList   *plugins;                       /* List of loaded plugins */
+       GMutex  plugins_mutex;                  /* Plugin list mutex */
+       GList   *adaptor_listeners;             /* List of vservice channel listener (for now not effective) */
+       GMutex  adaptor_listeners_mutex;        /* Listener list mutex */
+} push_adaptor_t;
+
+/**
+ * Creates plugin
+ */
+static push_adaptor_plugin_h push_adaptor_create_plugin(const char *plugin_path);
+
+/**
+ * Destroys plugin and deletes all resources associated with it
+ */
+static void push_adaptor_destroy_plugin(push_adaptor_plugin_h plugin);
+
+/**
+ * Loads plugins from selected directory
+ */
+static int push_adaptor_load_plugins_from_directory(push_adaptor_h adaptor, const char *dir_path);
+
+/**
+ * Checks if plugin is loaded by selected plugin adaptor
+ */
+static int push_adaptor_has_plugin(push_adaptor_h adaptor, push_adaptor_plugin_h plugin);
+
+/**
+ * Increases adaptor's plugin references counter
+ */
+static void push_adaptor_plugin_ref(push_adaptor_plugin_h);
+
+/**
+ * Decreases adaptor's plugin references counter
+ */
+static void push_adaptor_plugin_unref(push_adaptor_plugin_h);
+
+/**
+ * On notification received callback for service adaptor
+ */
+push_adaptor_service_on_notification_received_cb _service_adaptor_on_notification_received = NULL;
+
+/**
+ * Called on push notification received from plugin
+ */
+void
+push_adaptor_on_notification_received(push_adaptor_notification_data_h notification, void *user_data)
+{
+       push_adaptor_info("[Push MSG]: %s", notification->msg);
+
+       if (NULL != _service_adaptor_on_notification_received) {
+               _service_adaptor_on_notification_received(notification, user_data);
+       }
+}
+
+/* //////////////////////////////////////////////////////
+   // Mandatory: Internal adaptor management function
+   ////////////////////////////////////////////////////// */
+
+/**
+ * Creates plugin
+ */
+static push_adaptor_plugin_h push_adaptor_create_plugin(const char *plugin_path)
+{
+       push_adaptor_debug("Create plugin");
+
+       if (NULL == plugin_path) {
+               push_adaptor_error("Invalid argument");
+               return NULL;
+       }
+
+       void *dl_handle = dlopen(plugin_path, RTLD_LAZY);
+       if (NULL == dl_handle) {
+               push_adaptor_error("Could not load plugin %s: %s", plugin_path, dlerror());
+               return NULL;
+       }
+
+       push_adaptor_plugin_handle_h (*get_adaptee_handle)(void) = NULL;
+
+       get_adaptee_handle = (push_adaptor_plugin_handle_h (*)(void))(dlsym(dl_handle, "create_plugin_handle"));
+       if (NULL == get_adaptee_handle) {
+               dlclose(dl_handle);
+               push_adaptor_error("Could not get function pointer to create_plugin_handle");
+               return NULL;
+       }
+
+       plugin_req_enter();
+       push_adaptor_plugin_handle_h handle = get_adaptee_handle();
+       plugin_req_exit_void();
+
+       if (NULL == handle) {
+               dlclose(dl_handle);
+               push_adaptor_error("Could not get adaptee handle");
+               return NULL;
+       }
+
+       push_adaptor_plugin_h plugin = (push_adaptor_plugin_h) calloc(1, sizeof(push_adaptor_plugin_t));
+       if (NULL == plugin) {
+               dlclose(dl_handle);
+               push_adaptor_error("Could not create plugin object");
+               return NULL;
+       }
+
+       push_adaptor_plugin_listener_h listener =
+               (push_adaptor_plugin_listener_h) calloc(1, sizeof(push_adaptor_plugin_listener_t));
+       if (NULL == listener) {
+               free(plugin);
+               dlclose(dl_handle);
+               push_adaptor_error("Could not create listener object");
+               return NULL;
+       }
+
+       plugin->path = g_strdup(plugin_path);
+       plugin->handle = handle;
+       plugin->dl_handle = dl_handle;
+       plugin->ref_counter = 0;
+
+       g_mutex_init(&plugin->ref_counter_mutex);
+       g_mutex_init(&plugin->plugin_listener_mutex);
+
+       listener->_on_notification_received = push_adaptor_on_notification_received;
+
+       plugin_req_enter();
+       plugin->handle->set_listener(listener);
+       plugin_req_exit_void();
+
+       g_mutex_lock(&plugin->plugin_listener_mutex);
+       plugin->plugin_listener = listener;
+       g_mutex_unlock(&plugin->plugin_listener_mutex);
+
+       return plugin;
+}
+
+/**
+ * Destroys plugin and deletes all resources associated with it
+ */
+static void push_adaptor_destroy_plugin(push_adaptor_plugin_h plugin)
+{
+       push_adaptor_debug("Destroy plugin");
+
+       if (NULL == plugin) {
+               push_adaptor_error("Invalid argument");
+               return;
+       }
+
+       if (NULL != plugin->handle) {
+               plugin->handle->destroy_handle(plugin->handle);
+
+               g_mutex_lock(&plugin->plugin_listener_mutex);
+               plugin_req_enter();
+               plugin->handle->unset_listener();
+               plugin_req_exit_void();
+               g_mutex_unlock(&plugin->plugin_listener_mutex);
+
+               plugin->handle = NULL;
+       }
+
+       if (NULL != plugin->dl_handle) {
+               dlclose(plugin->dl_handle);
+               plugin->dl_handle = NULL;
+       }
+
+       free(plugin->path);
+       plugin->path = NULL;
+
+       free(plugin);
+}
+
+/**
+ * Loads plugins from selected directory
+ */
+static int push_adaptor_load_plugins_from_directory(push_adaptor_h adaptor, const char *dir_path)
+{
+       push_adaptor_debug("Load plugins from directory");
+
+       char *plugin_path = NULL;
+       DIR *dir = NULL;
+       struct dirent dir_entry, *result = NULL;
+
+       if ((NULL == adaptor) || (NULL == dir_path)) {
+               push_adaptor_error("Invalid argument");
+               return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       dir = opendir(dir_path);
+       if (NULL == dir) {
+               push_adaptor_error("Could not open dir path (%s)", dir_path);
+               return PUSH_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       int ret = PUSH_ADAPTOR_ERROR_NONE;
+       while (0 == (readdir_r(dir, &dir_entry, &result))) {
+
+               if (NULL == result) {
+                       push_adaptor_error("Could not open directory %s", plugin_path);
+                       break;
+               }
+
+               if (dir_entry.d_type & DT_DIR) {
+                       continue;
+               }
+
+               plugin_path = g_strconcat(dir_path, "/", dir_entry.d_name, NULL);
+               push_adaptor_plugin_h plugin = push_adaptor_create_plugin(plugin_path);
+
+               if (NULL != plugin) {
+                       push_adaptor_debug("Loaded plugin: %s", plugin_path);
+                       plugin->adaptor = adaptor;
+                       push_adaptor_plugin_ref(plugin);
+                       g_mutex_lock(&adaptor->plugins_mutex);
+                       adaptor->plugins = g_list_append(adaptor->plugins, plugin);
+                       g_mutex_unlock(&adaptor->plugins_mutex);
+               } else {
+                       push_adaptor_error("Could not load plugin %s", plugin_path);
+               }
+
+               free(plugin_path);
+               plugin_path = NULL;
+       }
+
+       push_adaptor_debug("End load plugins from directory");
+       closedir(dir);
+       return ret;
+}
+
+/**
+ * Checks if plugin is loaded by selected plugin adaptor
+ */
+static int push_adaptor_has_plugin(push_adaptor_h adaptor, push_adaptor_plugin_h plugin)
+{
+       push_adaptor_debug("Find plugin in plugin list");
+
+       if ((NULL == adaptor) || (NULL == plugin)) {
+               push_adaptor_error("Invalid argument");
+               return 0;
+       }
+
+       int result = 0;
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       if (NULL != g_list_find(adaptor->plugins, plugin)) {
+               result = 1;
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return result;
+}
+
+/**
+ * Increases adaptor's plugin references counter
+ */
+static void push_adaptor_plugin_ref(push_adaptor_plugin_h plugin)
+{
+       push_adaptor_debug("Increase plugin reference count");
+
+       if (NULL == plugin) {
+               push_adaptor_error("Invalid argument");
+               return;
+       }
+
+       g_mutex_lock(&plugin->ref_counter_mutex);
+       plugin->ref_counter = plugin->ref_counter + 1;
+       push_adaptor_info("ref_counter: %d", plugin->ref_counter);
+       g_mutex_unlock(&plugin->ref_counter_mutex);
+}
+
+/**
+ * Decreases adaptor's plugin references counter
+ */
+static void push_adaptor_plugin_unref(push_adaptor_plugin_h plugin)
+{
+       push_adaptor_debug("Decrease plugin reference count");
+
+       if (NULL == plugin) {
+               push_adaptor_error("Invalid argument");
+               return ;
+       }
+
+       int should_destroy = 0;
+
+       g_mutex_lock(&plugin->ref_counter_mutex);
+       plugin->ref_counter = plugin->ref_counter - 1;
+       push_adaptor_info("ref_counter: %d", plugin->ref_counter);
+       if (0 >= plugin->ref_counter) {
+               should_destroy = 1;
+       }
+       g_mutex_unlock(&plugin->ref_counter_mutex);
+
+       if (should_destroy) {
+               push_adaptor_debug("Plugin is being destroyed");
+               push_adaptor_destroy_plugin(plugin);
+       }
+}
+
+/* //////////////////////////////////////////////////////
+   // Mandatory: External adaptor management function
+   ////////////////////////////////////////////////////// */
+
+/**
+* @brief Creates Push Adaptor
+*
+* @param[in]    plugin_dir      specifies directory path where plugins are stored
+* @return       push_adaptor_h on success, otherwise NULL value
+*/
+push_adaptor_h push_adaptor_create(const char *plugins_dir)
+{
+       push_adaptor_warning("Create push adaptor");
+
+       push_adaptor_h push_adaptor = (push_adaptor_h) malloc(sizeof(push_adaptor_t));
+       if (NULL == push_adaptor) {
+               return NULL;
+       }
+
+       push_adaptor->started = 0;
+       push_adaptor->plugins_dir = strdup(plugins_dir);
+
+       g_mutex_init(&push_adaptor->push_adaptor_mutex);
+       g_mutex_init(&push_adaptor->plugins_mutex);
+       g_mutex_init(&push_adaptor->adaptor_listeners_mutex);
+
+       g_mutex_lock(&push_adaptor->adaptor_listeners_mutex);
+       push_adaptor->adaptor_listeners = NULL;
+       g_mutex_unlock(&push_adaptor->adaptor_listeners_mutex);
+
+       g_mutex_lock(&push_adaptor->plugins_mutex);
+       push_adaptor->plugins = NULL;
+       g_mutex_unlock(&push_adaptor->plugins_mutex);
+
+       return push_adaptor;
+}
+
+/**
+* @brief Destroys push adaptor. If push adaptor was started it is stopped first.
+*
+* @param[in]    adaptor         specifies push adaptor handle to be destroyed
+* @return       void
+*/
+void push_adaptor_destroy(push_adaptor_h adaptor)
+{
+       push_adaptor_warning("Destroy push adaptor");
+       if (NULL == adaptor) {
+               push_adaptor_error("Invalid argument");
+               return ;
+       }
+
+       g_mutex_lock(&adaptor->push_adaptor_mutex);
+       if (adaptor->started) {
+               push_adaptor_error("Push adaptor is running. Forcing stop before destroy");
+               push_adaptor_stop(adaptor);
+       }
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       if (NULL != adaptor->plugins) {
+               g_list_free_full(adaptor->plugins, (GDestroyNotify) push_adaptor_plugin_unref);
+               adaptor->plugins = NULL;
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+       if (NULL != adaptor->adaptor_listeners) {
+               g_list_free(adaptor->adaptor_listeners);
+               adaptor->adaptor_listeners = NULL;
+       }
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+
+       _service_adaptor_on_notification_received = NULL;
+
+       free(adaptor->plugins_dir);
+       adaptor->plugins_dir = NULL;
+
+       g_mutex_unlock(&adaptor->push_adaptor_mutex);
+
+       free(adaptor);
+}
+
+/**
+* @brief Starts push adaptor and loads plugins that were found in plugins search dir
+* specified in push_adaptor_create
+*
+* @param[in]    adaptor         specifies push adaptor handle
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
+*/
+int push_adaptor_start(push_adaptor_h adaptor)
+{
+       push_adaptor_warning("Start push adaptor");
+       if (NULL == adaptor) {
+               push_adaptor_error("Invalid argument");
+               return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->push_adaptor_mutex);
+       int result = PUSH_ADAPTOR_ERROR_NONE;
+       if (adaptor->started) {
+               push_adaptor_error("Push adaptor is already started");
+               result = PUSH_ADAPTOR_ERROR_START;
+       } else {
+               adaptor->started = 1;
+               result = push_adaptor_load_plugins_from_directory(adaptor, adaptor->plugins_dir);
+               if (PUSH_ADAPTOR_ERROR_NONE != result) {
+                       adaptor->started = 0;
+                       push_adaptor_error("Could not load plugins from directory");
+               } else {
+                       push_adaptor_debug("Push adaptor started successfully");
+               }
+       }
+       g_mutex_unlock(&adaptor->push_adaptor_mutex);
+
+       return result;
+}
+
+/**
+* @brief Stops push adaptor
+*
+* @param[in]    adaptor         specifies push adaptor handle
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
+*/
+int push_adaptor_stop(push_adaptor_h adaptor)
+{
+       push_adaptor_warning("Stop contact adaptor");
+
+       if (NULL == adaptor) {
+               push_adaptor_error("Invalid argument");
+               return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->push_adaptor_mutex);
+       int result = PUSH_ADAPTOR_ERROR_NONE;
+       if (!adaptor->started) {
+               result = PUSH_ADAPTOR_ERROR_START;
+       } else {
+               if (NULL != adaptor->plugins) {
+                       g_mutex_lock(&adaptor->plugins_mutex);
+                       g_list_free_full(adaptor->plugins, (GDestroyNotify) push_adaptor_plugin_unref);
+                       adaptor->plugins = NULL;
+                       g_mutex_unlock(&adaptor->plugins_mutex);
+               }
+               adaptor->started = 0;
+               push_adaptor_debug("Push adaptor stopped");
+       }
+
+       g_mutex_unlock(&adaptor->push_adaptor_mutex);
+       return result;
+}
+
+/**
+* @brief Registers plugin state listener
+*
+* @param[in]    adaptor                specifies push adaptor handle
+* @param[in]    listener        specifies push adaptor listener handle
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
+*/
+int push_adaptor_register_listener(push_adaptor_h adaptor, push_adaptor_listener_h listener)
+{
+       push_adaptor_warning("Register push adaptor listener");
+
+       if ((NULL == adaptor) || (NULL == listener)) {
+               push_adaptor_error("Invalid argument");
+               return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+       adaptor->adaptor_listeners = g_list_append(adaptor->adaptor_listeners, listener);
+
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+
+       _service_adaptor_on_notification_received =
+                       (push_adaptor_service_on_notification_received_cb) listener->_on_notification_received;
+
+       return PUSH_ADAPTOR_ERROR_NONE;
+}
+
+/**
+* @brief Unregisters plugin state listener
+*
+* @param[in]    adaptor                specifies push adaptor handle
+* @param[in]    listener        specifies push adaptor listener handle
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
+*/
+int push_adaptor_unregister_listener(push_adaptor_h adaptor, push_adaptor_listener_h listener)
+{
+       push_adaptor_warning("Unregister push adaptor listener");
+
+       if ((NULL == adaptor) || (NULL == listener)) {
+               push_adaptor_error("Invalid argument");
+               return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+
+       if (NULL == g_list_find(adaptor->adaptor_listeners, listener)) {
+               g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+               push_adaptor_error("Could not find listener");
+               return PUSH_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       adaptor->adaptor_listeners = g_list_remove(adaptor->adaptor_listeners, listener);
+
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+
+       _service_adaptor_on_notification_received = NULL;
+
+       return PUSH_ADAPTOR_ERROR_NONE;
+}
+
+/* //////////////////////////////////////////////////////
+   // Create / Destroy error code
+   ////////////////////////////////////////////////////// */
+
+/**
+* @brief Create error code
+*
+* @param[in]    code            specifies error code number
+* @param[in]    msg             specifies error message
+* @return       push_adaptor_error_code_h on success, otherwise NULL value
+*/
+push_adaptor_error_code_h push_adaptor_create_error_code(const int64_t code, const char *msg)
+{
+       if (NULL == msg) {
+               return NULL;
+       }
+
+       push_adaptor_error_code_h error_code =
+               (push_adaptor_error_code_h) malloc(sizeof(push_adaptor_error_code_t));
+       if (NULL == error_code) {
+               return NULL;
+       }
+
+       error_code->code = code;
+       error_code->msg = strdup(msg);
+
+       return error_code;
+}
+
+/**
+* @brief Destroy error code
+*
+* @param[in]    error_code      specifies error code handle
+* @return       void
+*/
+void push_adaptor_destroy_error_code(push_adaptor_error_code_h *error_code)
+{
+       if (NULL == *error_code) {
+               return;
+       }
+
+       if (NULL != (*error_code)->msg) {
+               free((*error_code)->msg);
+               (*error_code)->msg = NULL;
+       }
+
+       free(*error_code);
+       *error_code = NULL;
+}
+
+/* //////////////////////////////////////////////////////
+   // Plugin context create / destroy
+   ////////////////////////////////////////////////////// */
+/**
+* @brief Creates plugin context
+*
+* @param[in]    plugin          specifies push adaptor plugin handle
+* @param[in]    push_app_id     specifies push service application ID
+* @return       push_adaptor_plugin_context_h on success, otherwise NULL value
+*/
+push_adaptor_plugin_context_h push_adaptor_create_plugin_context(push_adaptor_plugin_h plugin,
+                                               const char *plugin_uri,
+                                               const char *push_app_id)
+{
+       push_adaptor_warning("Create plugin context");
+
+       if (NULL == plugin) {
+               push_adaptor_error("Invalid argument");
+               return NULL;
+       }
+
+       if (NULL != plugin->handle) {
+               push_adaptor_plugin_context_h plugin_context = NULL;
+
+               plugin_req_enter();
+               plugin->handle->create_context(&plugin_context, push_app_id);
+               plugin_req_exit_void();
+
+               if (NULL != plugin_context) {
+                       plugin_context->plugin_uri = strdup(plugin->handle->plugin_uri);
+                       plugin_context->state = PUSH_ADAPTOR_STATE_DISCONNECTED;
+               }
+               return plugin_context;
+       } else {
+               push_adaptor_error("Plugin handle is null");
+       }
+
+       return NULL;
+}
+
+/**
+* @brief Destroys plugin context
+*
+* @param[in]    plugin          specifies push adaptor plugin handle
+* @param[in]    context         specifies push adaptor plugin context handle
+* @return       void
+*/
+void push_adaptor_destroy_plugin_context(push_adaptor_plugin_h plugin,
+                                               push_adaptor_plugin_context_h plugin_context)
+{
+       push_adaptor_warning("Destroy plugin context");
+
+       if ((NULL == plugin) || (NULL == plugin_context)) {
+               push_adaptor_error("Invalid argument");
+               return;
+       }
+
+       if (NULL != plugin->handle) {
+               plugin_req_enter();
+               plugin->handle->destroy_context(plugin_context);
+               plugin_req_exit_void();
+       } else {
+               push_adaptor_error("Plugin handle is null");
+       }
+}
+
+/* //////////////////////////////////////////////////////
+   // Get plugin by plugin name
+   ////////////////////////////////////////////////////// */
+
+/**
+* @brief Gets plugin with specified unique name
+*
+* @param[in]    adaptor         specifies push adaptor handle
+* @param[in]    plugin_name     specifies plugin name to be searched for
+* @return       push_adaptor_plugin_h on success, otherwise NULL value
+*/
+push_adaptor_plugin_h push_adaptor_get_plugin_by_name(push_adaptor_h adaptor,
+                                               const char *plugin_name)
+{
+       push_adaptor_warning("Get plugin by name: %s", plugin_name);
+
+       if ((NULL == adaptor) || (NULL == plugin_name)) {
+               push_adaptor_error("Invalid argument");
+               return NULL;
+       }
+
+       push_adaptor_plugin_h plugin = NULL;
+       g_mutex_lock(&adaptor->plugins_mutex);
+       int count = g_list_length(adaptor->plugins);
+       int i = 0;
+       for (i = 0; i < count; i++) {
+               push_adaptor_plugin_h temp_plugin = g_list_nth_data(adaptor->plugins, i);
+               if (NULL != temp_plugin) {
+                       if (0 == strcmp(temp_plugin->handle->plugin_uri, plugin_name)) {
+                               push_adaptor_plugin_ref(temp_plugin);
+                               plugin = temp_plugin;
+                               push_adaptor_debug("Plugin is found by name");
+                               break;
+                       }
+               }
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       if (NULL == plugin)
+               push_adaptor_debug("Plugin is not found by name");
+
+       return plugin;
+}
+
+/* //////////////////////////////////////////////////////
+   // Plugin load / unload / get plugin list
+   ////////////////////////////////////////////////////// */
+
+/**
+* @brief Loads plugin from selected path
+*
+* @param[in]    adaptor         specifies push adaptor handle
+* @param[in]    plugin_path     specifies plugin's saved path
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
+*/
+int push_adaptor_load_plugin(push_adaptor_h adaptor,
+                                               const char *plugin_path)
+{
+       push_adaptor_warning("Load plugin by plugin path: %s", plugin_path);
+
+       if ((NULL == adaptor) || (NULL == plugin_path)) {
+               push_adaptor_error("Invalid argument");
+               return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (!adaptor->started) {
+               push_adaptor_error("Push adaptor is not started");
+               return PUSH_ADAPTOR_ERROR_START;
+       }
+
+       push_adaptor_plugin_h plugin = push_adaptor_create_plugin(plugin_path);
+       if (NULL == plugin) {
+               push_adaptor_error("Could not load plugin %s", plugin_path);
+               return PUSH_ADAPTOR_ERROR_CREATE;
+       }
+
+       plugin->adaptor = adaptor;
+       push_adaptor_plugin_ref(plugin);
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       adaptor->plugins = g_list_append(adaptor->plugins, plugin);
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return PUSH_ADAPTOR_ERROR_NONE;
+}
+
+/**
+* @brief Unloads selected plugin
+*
+* @param[in]    adaptor         specifies push adaptor handle
+* @param[in]    plugin          specifies push adaptor plugin handle
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
+*/
+int push_adaptor_unload_plugin(push_adaptor_h adaptor,
+                                               push_adaptor_plugin_h plugin)
+{
+       push_adaptor_warning("Unload plugin");
+
+       if ((NULL == adaptor) || (NULL == plugin)) {
+               push_adaptor_error("Invalid argument");
+               return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (!adaptor->started) {
+               push_adaptor_error("Push adaptor is not started");
+               return PUSH_ADAPTOR_ERROR_START;
+       }
+
+       if (!push_adaptor_has_plugin(adaptor, plugin)) {
+               push_adaptor_error("Push adaptor has no plugin");
+               return PUSH_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       plugin->adaptor = NULL;
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       adaptor->plugins = g_list_remove(adaptor->plugins, plugin);
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       push_adaptor_plugin_unref(plugin);
+
+       return PUSH_ADAPTOR_ERROR_NONE;
+}
+
+/**
+* @brief Get plugin list
+*
+* @param[in]    adaptor         specifies push adaptor handle
+* @return       GList pointer on success, otherwise NULL value
+*/
+GList *push_adaptor_get_plugins(push_adaptor_h adaptor)
+{
+       push_adaptor_warning("Get plugin list");
+
+       if (NULL == adaptor) {
+               push_adaptor_error("Invalid argument");
+               return NULL;
+       }
+
+       GList *plugins = NULL;
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       int plugins_count = g_list_length(adaptor->plugins);
+       int i;
+       for (i = 0; i < plugins_count; i++) {
+               push_adaptor_plugin_h plugin = g_list_nth_data(adaptor->plugins, i);
+               if (NULL != plugin) {
+                       push_adaptor_plugin_ref(plugin);
+                       plugins = g_list_append(plugins, plugin);
+               }
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return plugins;
+}
+
+/* //////////////////////////////////////////////////////
+   // External Push Adaptor APIs
+   ////////////////////////////////////////////////////// */
+
+/**
+* @brief Set server information for Push Plugin
+*
+* @param[in]    plugin         specifies Push Adaptor Plugin handle
+* @param[in]    context        specifies Push Adaptor Plugin Context handle
+* @param[in]    server_info    specifies server information for Push Plugin
+* @param[out]   error          specifies error code
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in push_error_code_t - PUSH_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+push_error_code_t push_adaptor_set_server_info(push_adaptor_plugin_h plugin,
+                                               push_adaptor_plugin_context_h context,
+                                               GHashTable *server_info,
+                                               push_adaptor_error_code_h *error_code)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               push_adaptor_error("Invalid argument");
+
+               *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                               "Invalid argument (plugin or context)");
+
+               return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               push_adaptor_error("Plugin handle is null");
+
+               *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                               "Plugin handle is null");
+
+               return PUSH_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+/*      *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_NONE, */
+/*                                                   "Push adaptor error none"); */
+       push_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->set_server_info(context, server_info);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+/**
+* @brief Connects to push service with Push App ID handed over when creates plugin context
+*
+* @param[in]    plugin          specifies push adaptor plugin handle
+* @param[in]    context         specifies push adaptor plugin context handle
+* @param[out]   error           specifies error code
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
+*/
+push_error_code_t push_adaptor_connect(push_adaptor_plugin_h plugin,
+                                               push_adaptor_plugin_context_h context,
+                                               push_adaptor_error_code_h *error_code)
+{
+       push_adaptor_warning("Connect to push adaptor");
+
+       if ((NULL == plugin) || (NULL == context)) {
+               push_adaptor_error("Invalid argument");
+
+               *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                               "Invalid argument (plugin or context)");
+
+               return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               push_adaptor_error("Plugin handle is null");
+
+               *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                               "Plugin handle is null");
+
+               return PUSH_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+/*     *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_NONE, */
+/*                                                     "Push adaptor error none"); */
+
+       push_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->connect(context);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+/**
+* @brief Disconnects from push service with Push App ID handed over when creates plugin context
+*
+* @param[in]    plugin          specifies push adaptor plugin handle
+* @param[in]    context         specifies push adaptor plugin context handle
+* @param[out]   error           specifies error code
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
+*/
+push_error_code_t push_adaptor_disconnect(push_adaptor_plugin_h plugin,
+                                               push_adaptor_plugin_context_h context,
+                                               push_adaptor_error_code_h *error_code)
+{
+       push_adaptor_warning("Disconnect from push adaptor");
+
+       if ((NULL == plugin) || (NULL == context)) {
+               push_adaptor_error("Invalid argument");
+
+               *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                               "Invalid argument (plugin or context)");
+
+               return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               push_adaptor_error("Plugin handle is null");
+
+               *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                               "Plugin handle is null");
+
+               return PUSH_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+/*     *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_NONE, */
+/*                                                     "Push adaptor error none"); */
+
+       push_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->disconnect(context);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+push_error_code_t push_adaptor_is_connected(push_adaptor_plugin_h plugin,
+                                               push_adaptor_plugin_context_h context,
+                                               int *is_connected)
+{
+       push_adaptor_info("Check push connection");
+
+       if ((NULL == context) || (NULL == is_connected)){
+               return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       *is_connected = context->state;
+
+       return PUSH_ADAPTOR_ERROR_NONE;
+}
+
+/**
+* @brief Asynchronous request to get unread notifications
+*
+* @param[in]    plugin          specifies push adaptor plugin handle
+* @param[in]    context         specifies push adaptor plugin context handle
+* @param[out]   error           specifies error code
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
+*/
+push_error_code_t push_adaptor_request_unread_notification(push_adaptor_plugin_h plugin,
+                                               push_adaptor_plugin_context_h context,
+                                               push_adaptor_error_code_h *error_code)
+{
+       push_adaptor_warning("Request unread notification");
+
+       if ((NULL == plugin) || (NULL == context)) {
+               push_adaptor_error("Invalid argument");
+
+               *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                               "Invalid argument (plugin or context)");
+
+               return PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               push_adaptor_error("Plugin handle is null");
+
+               *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                               "Plugin handle is null");
+
+               return PUSH_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+/*     *error_code = push_adaptor_create_error_code((int64_t) PUSH_ADAPTOR_ERROR_NONE, */
+/*                                                     "Push adaptor error none"); */
+
+       push_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->request_unread_notification(context);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
diff --git a/adaptor/push-adaptor/push-adaptor.h b/adaptor/push-adaptor/push-adaptor.h
new file mode 100644 (file)
index 0000000..6829ac6
--- /dev/null
@@ -0,0 +1,445 @@
+/*
+* Copyright (c) 2011 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 __PUSH_ADAPTOR_H__
+#define __PUSH_ADAPTOR_H__
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+#include <glib.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+/**
+* @brief Push Adaptor error code
+*/
+typedef enum push_error_code_e
+{
+       PUSH_ADAPTOR_ERROR_NONE                     =  0,
+       PUSH_ADAPTOR_ERROR_LAUNCH                    = 1,    /**< 1 ~ 99: internal error*/
+       PUSH_ADAPTOR_ERROR_INIT                      = 2,
+       PUSH_ADAPTOR_ERROR_DEINIT                    = 3,
+       PUSH_ADAPTOR_ERROR_CREATE                    = 4,
+       PUSH_ADAPTOR_ERROR_DESTROY                   = 5,
+       PUSH_ADAPTOR_ERROR_START                     = 6,
+       PUSH_ADAPTOR_ERROR_STOP                      = 7,
+       PUSH_ADAPTOR_ERROR_CONNECT                   = 8,
+       PUSH_ADAPTOR_ERROR_DISCONNECT                = 9,
+       PUSH_ADAPTOR_ERROR_NOT_FOUND                 = 10,
+       PUSH_ADAPTOR_ERROR_CORRUPTED                 = 11,
+       PUSH_ADAPTOR_ERROR_UNSUPPORTED               = 12,
+       PUSH_ADAPTOR_ERROR_INVALID_HANDLE            = 13,
+       PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT          = 14,
+       PUSH_ADAPTOR_ERROR_INVALID_ARGUMENT_TYPE     = 15,
+       PUSH_ADAPTOR_ERROR_NOT_AUTHORIZED            = 16,
+       PUSH_ADAPTOR_ERROR_ADAPTOR_INTERNAL          = 17,
+       PUSH_ADAPTOR_ERROR_PLUGIN_INTERNAL           = 18,
+       PUSH_ADAPTOR_ERROR_SERVER_INTERNAL           = 19,
+       PUSH_ADAPTOR_ERROR_DBUS                      = 20,
+       PUSH_ADAPTOR_ERROR_CALLBACK_TIME_OUT         = 21,
+       PUSH_ADAPTOR_ERROR_MAX
+} push_error_code_t;
+
+/**
+* @brief Push Adaptor plugin handle
+*/
+typedef struct push_adaptor_plugin_s *push_adaptor_plugin_h;
+
+/**
+* @brief Push Adaptor handle
+*/
+typedef struct push_adaptor_s *push_adaptor_h;
+
+/**
+* @brief Push Adaptor plugin context structure
+*/
+typedef struct push_adaptor_plugin_context_s
+{
+       char    *push_app_id;   /**< unique key >*/
+       char    *plugin_uri;
+        void   *plugin_info;
+
+       int     state;          /* Adaptor defined and share with plugin (getter: adaptor, setter: plugin) */
+} push_adaptor_plugin_context_t;
+typedef struct push_adaptor_plugin_context_s *push_adaptor_plugin_context_h;
+
+typedef enum
+{
+       PUSH_ADAPTOR_STATE_DISCONNECTED = 0,
+       PUSH_ADAPTOR_STATE_CONNECTED    = 1,
+} push_adaptor_connection_state_e;
+
+/**
+* @brief Push Adaptor error code
+*/
+typedef struct push_adaptor_error_code_s
+{
+        int64_t code;
+        char   *msg;
+
+} push_adaptor_error_code_t;
+typedef struct push_adaptor_error_code_s *push_adaptor_error_code_h;
+
+/**
+* @brief Push Adaptor notification data
+*/
+typedef struct push_adaptor_notification_data_s
+{
+        char           *data;
+        char           *msg;
+        long long int   time_stamp;
+       char            *sender;
+       char            *app_id;
+       char            *session_info;
+       char            *request_id;
+       int             type;
+} push_adaptor_notification_data_t;
+typedef struct push_adaptor_notification_data_s *push_adaptor_notification_data_h;
+
+/**
+* @brief Callback for service_adaptor_connect_push_service API for Service Adaptor
+*
+* @param[in]    notification   specifies pushed notification message with data, session info, and etc.
+* @param[in]    user_data       specifies user data passed when plugin context is created.
+* @return       void
+* @pre         push_adaptor_connect will invoke this callback.
+* @see
+*/
+typedef void(*push_adaptor_service_on_notification_received_cb)
+                        (push_adaptor_notification_data_h notification, void *user_data);
+
+/**
+* @brief Callback for service_adaptor_connect_push_service API for push plugin
+*
+* @param[in]    notification    specifies pushed notification message with data, session info, and etc.
+* @param[in]    user_data       specifies user_data passed when plugin context is created.
+* @return       void
+* @pre         push_adaptor_connect will invoke this callback.
+* @see
+*/
+typedef void(*push_adaptor_plugin_on_notification_received_cb)
+                        (push_adaptor_notification_data_h notification, void *user_data);
+
+/**
+* @brief Push Adaptor listener for Service Adaptor
+*/
+typedef struct push_adaptor_listener_s
+{
+        push_adaptor_service_on_notification_received_cb        _on_notification_received;
+
+} push_adaptor_listener_t;
+typedef struct push_adaptor_listener_s *push_adaptor_listener_h;
+
+/**
+* @brief Push Adaptor listener for plugins
+*/
+typedef struct push_adaptor_plugin_listener_s
+{
+        push_adaptor_plugin_on_notification_received_cb         _on_notification_received;
+
+} push_adaptor_plugin_listener_t;
+typedef struct push_adaptor_plugin_listener_s *push_adaptor_plugin_listener_h;
+
+/**
+ * @brief Push Adaptor plugin handle
+ */
+typedef struct push_adaptor_plugin_handle_s
+{
+       /**< mandatory >*/
+       push_error_code_t (*create_context)(push_adaptor_plugin_context_h *context,
+                                                       const char *push_app_id);
+
+       /**< mandatory >*/
+       push_error_code_t (*destroy_context)(push_adaptor_plugin_context_h context);
+
+       /**< mandatory >*/
+       push_error_code_t (*destroy_handle)(struct push_adaptor_plugin_handle_s *handle);
+
+       /**< mandatory >*/
+       push_error_code_t (*set_listener)(push_adaptor_plugin_listener_h listener);
+
+       /**< mandatory >*/
+       push_error_code_t (*unset_listener)(void);
+
+       /**< optional >*/
+       push_error_code_t (*set_server_info)(push_adaptor_plugin_context_h context,
+                                                       GHashTable *server_info);
+
+       /**< optional >*/
+       push_error_code_t (*connect)(push_adaptor_plugin_context_h context);
+
+       /**< optional >*/
+        push_error_code_t (*disconnect)(push_adaptor_plugin_context_h context);
+
+       /**< optional >*/
+       push_error_code_t (*request_unread_notification)(push_adaptor_plugin_context_h context);
+
+       /**< mandatory >*/
+       char *plugin_uri;
+
+} push_adaptor_plugin_handle_t;
+typedef struct push_adaptor_plugin_handle_s *push_adaptor_plugin_handle_h;
+
+/**
+* @brief Creates Push Adaptor
+*
+* @param[in]    plugin_dir      specifies directory path where plugins are stored
+* @return      push_adaptor_h on success, otherwise NULL value
+*/
+EXPORT_API
+push_adaptor_h push_adaptor_create(const char *plugins_dir);
+
+/**
+* @brief Destroys push adaptor. If push adaptor was started it is stopped first.
+*
+* @param[in]    adaptor         specifies push adaptor handle to be destroyed
+* @return       void
+*/
+EXPORT_API
+void push_adaptor_destroy(push_adaptor_h adaptor);
+
+/**
+* @brief Starts push adaptor and loads plugins that were found in plugins search dir
+* specified in push_adaptor_create
+*
+* @param[in]    adaptor                specifies push adaptor handle
+* @return      0 on success, otherwise a positive error value
+* @retval      error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+int push_adaptor_start(push_adaptor_h adaptor);
+
+/**
+* @brief Stops push adaptor
+*
+* @param[in]    adaptor         specifies push adaptor handle
+* @return      0 on success, otherwise a positive error value
+* @retval      error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+int push_adaptor_stop(push_adaptor_h adaptor);
+
+/**
+* @brief Registers plugin state listener
+*
+* @param[in]    adaptor         specifies push adaptor handle
+* @param[in]   listener        specifies push adaptor listener handle
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+int push_adaptor_register_listener(push_adaptor_h adaptor,
+                                               push_adaptor_listener_h listener);
+
+/**
+* @brief Unregisters plugin state listener
+*
+* @param[in]    adaptor         specifies push adaptor handle
+* @param[in]    listener       specifies push adaptor listener handle
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+int push_adaptor_unregister_listener(push_adaptor_h adaptor,
+                                               push_adaptor_listener_h listener);
+
+/**
+* @brief Creates plugin context
+*
+* @param[in]    plugin         specifies push adaptor plugin handle
+* @param[in]    push_app_id    specifies push service application ID
+* @return       push_adaptor_plugin_context_h on success, otherwise NULL value
+*/
+EXPORT_API
+push_adaptor_plugin_context_h push_adaptor_create_plugin_context(push_adaptor_plugin_h plugin,
+                                               const char *plugin_uri,
+                                               const char *push_app_id);
+
+/**
+* @brief Destroys plugin context
+*
+* @param[in]    plugin          specifies push adaptor plugin handle
+* @param[in]    context                specifies push adaptor plugin context handle
+* @return       void
+*/
+EXPORT_API
+void push_adaptor_destroy_plugin_context(push_adaptor_plugin_h plugin,
+                                               push_adaptor_plugin_context_h context);
+
+/**
+* @brief Gets plugin with specified unique name
+*
+* @param[in]    adaptor         specifies push adaptor handle
+* @param[in]    plugin_name     specifies plugin name to be searched for
+* @return       push_adaptor_plugin_h on success, otherwise NULL value
+*/
+EXPORT_API
+push_adaptor_plugin_h push_adaptor_get_plugin_by_name(push_adaptor_h adaptor,
+                                               const char *plugin_uri);
+
+/**
+* @brief Loads plugin from selected path
+*
+* @param[in]    adaptor         specifies push adaptor handle
+* @param[in]    plugin_path     specifies plugin's saved path
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+int push_adaptor_load_plugin(push_adaptor_h adaptor,
+                                               const char *plugin_path);
+
+/**
+* @brief Unloads selected plugin
+*
+* @param[in]    adaptor         specifies push adaptor handle
+* @param[in]    plugin          specifies push adaptor plugin handle
+* @return       0 on success, otherwise a positive error value
+* @retval       error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+int push_adaptor_unload_plugin(push_adaptor_h adaptor,
+                                               push_adaptor_plugin_h plugin);
+
+/**
+* @brief Create error code
+*
+* @param[in]   code            specifies error code number
+* @param[in]   msg             specifies error message
+* @return      push_adaptor_error_code_h on success, otherwise NULL value
+*/
+EXPORT_API
+push_adaptor_error_code_h push_adaptor_create_error_code(const int64_t code, const char *msg);
+
+/**
+* @brief Destroy error code
+*
+* @param[in]   error_code      specifies error code handle
+* @return      void
+*/
+EXPORT_API
+void push_adaptor_destroy_error_code(push_adaptor_error_code_h *error_code);
+
+/**
+* @brief Get plugin list
+*
+* @param[in]   adaptor         specifies push adaptor handle
+* @return      GList pointer on success, otherwise NULL value
+*/
+EXPORT_API
+GList *push_adaptor_get_plugins(push_adaptor_h adaptor);
+
+/**
+ * @brief Set server information for Push Plugin
+ *
+ * @param[in]    plugin                specifies Push Adaptor Plugin handle
+ * @param[in]    context       specifies Push Adaptor Plugin Context handle
+ * @param[in]    server_info   specifies server information for Push Plugin
+ * @param[out]   error         specifies error code
+* @return 0 on success, otherwise a positive error value
+ * @retval error code defined in push_error_code_t - PUSH_ADAPTOR_ERROR_NONE if Successful
+ */
+EXPORT_API
+push_error_code_t push_adaptor_set_server_info(push_adaptor_plugin_h plugin,
+                                               push_adaptor_plugin_context_h context,
+                                               GHashTable *server_info,
+                                               push_adaptor_error_code_h *error);
+
+/**
+* @brief Connects to push service with Push App ID handed over when creates plugin context
+*
+* @param[in]    plugin          specifies push adaptor plugin handle
+* @param[in]    context         specifies push adaptor plugin context handle
+* @param[out]   error           specifies error code
+* @return      0 on success, otherwise a positive error value
+* @retval      error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+push_error_code_t push_adaptor_connect(push_adaptor_plugin_h plugin,
+                                               push_adaptor_plugin_context_h context,
+                                               push_adaptor_error_code_h *error);
+
+/**
+* @brief Disconnects from push service with Push App ID handed over when creates plugin context
+*
+* @param[in]    plugin          specifies push adaptor plugin handle
+* @param[in]    context         specifies push adaptor plugin context handle
+* @param[out]   error           specifies error code
+* @return      0 on success, otherwise a positive error value
+* @retval      error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+push_error_code_t push_adaptor_disconnect(push_adaptor_plugin_h plugin,
+                                               push_adaptor_plugin_context_h context,
+                                               push_adaptor_error_code_h *error);
+
+EXPORT_API
+push_error_code_t push_adaptor_is_connected(push_adaptor_plugin_h plugin,
+                                               push_adaptor_plugin_context_h context,
+                                               int *is_connected);
+
+/**
+* @brief Asynchronous request to get unread notifications
+*
+* @param[in]   plugin          specifies push adaptor plugin handle
+* @param[in]    context                specifies push adaptor plugin context handle
+* @param[out]  error           specifies error code
+* @return      0 on success, otherwise a positive error value
+* @retval      error code defined in push_error_code_e - PUSH_ADAPTOR_ERROR_NONE if successful
+*/
+EXPORT_API
+push_error_code_t push_adaptor_request_unread_notification(push_adaptor_plugin_h plugin,
+                                               push_adaptor_plugin_context_h context,
+                                               push_adaptor_error_code_h *error);
+
+
+/*
+EXPORT_API
+push_error_code_t push_adaptor_register(push_adaptor_plugin_h, push_adaptor_plugin_context_h,
+                                        void *svc_in, void *opt_in, void **svc_out, void **opt_out);
+
+EXPORT_API
+push_error_code_t push_adaptor_deregister(push_adaptor_plugin_h, push_adaptor_plugin_context_h,
+                                        void *svc_in, void *opt_in, void **svc_out, void **opt_out);
+
+EXPORT_API
+push_error_code_t push_adaptor_get_notification_data(push_adaptor_plugin_h, push_adaptor_plugin_context_h,
+                                        void *svc_in, void *opt_in, void **svc_out, void **opt_out);
+
+EXPORT_API
+push_error_code_t push_adaptor_get_notification_message(push_adaptor_plugin_h, push_adaptor_plugin_context_h,
+                                        void *svc_in, void *opt_in, void **svc_out, void **opt_out);
+
+EXPORT_API
+push_error_code_t push_adaptor_get_notification_time(push_adaptor_plugin_h, push_adaptor_plugin_context_h,
+                                        void *svc_in, void *opt_in, void **svc_out, void **opt_out);
+
+EXPORT_API
+push_error_code_t push_adaptor_get_unread_notification(push_adaptor_plugin_h, push_adaptor_plugin_context_h,
+                                        void *svc_in, void *opt_in, void **svc_out, void **opt_out);
+
+EXPORT_API
+push_error_code_t push_adaptor_get_registration_id(push_adaptor_plugin_h, push_adaptor_plugin_context_h,
+                                        void *svc_in, void *opt_in, void **svc_out, void **opt_out);
+
+EXPORT_API
+push_error_code_t push_adaptor_free_notification(push_adaptor_plugin_h, push_adaptor_plugin_context_h,
+                                        void *svc_in, void *opt_in, void **svc_out, void **opt_out);
+*/
+
+#endif /* __PUSH_ADAPTOR_H__ */
diff --git a/adaptor/shop-adaptor/shop-adaptor-log.h b/adaptor/shop-adaptor/shop-adaptor-log.h
new file mode 100644 (file)
index 0000000..6133597
--- /dev/null
@@ -0,0 +1,188 @@
+/*\r
+* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved\r
+*\r
+* Licensed under the Apache License, Version 2.0 (the License);\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+* http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an AS IS BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+*/\r
+\r
+#ifndef __SHOP_ADAPTOR_LOG_H__\r
+#define __SHOP_ADAPTOR_LOG_H__\r
+\r
+//#define WORK_IN_LOCAL\r
+\r
+/**\r
+ *  HOW TO USE IT:\r
+ *  First you need to set platform logging on the device:\r
+ *\r
+ *    # dlogctrl set platformlog 1\r
+ *\r
+ *  After reboot you are able to see logs from this application, when you launch dlogutil with a proper filter e.g.:\r
+ *\r
+ *    # dlogutil SHOP_ADAPTOR:D\r
+ *\r
+ *  You may use different logging levels as: D (debug), I (info), W (warning), E (error) or F (fatal).\r
+ *  Higher level messages are included by default e.g. dlogutil CLOUDBOX:W prints warnings but also errors and fatal messages.\r
+ */\r
+\r
+#include <unistd.h>\r
+#include <linux/unistd.h>\r
+\r
+/* These defines must be located before #include <dlog.h> */\r
+#define TIZEN_ENGINEER_MODE\r
+// TODO: Investigate why this macro is defined somewhere else\r
+#ifndef TIZEN_DEBUG_ENABLE\r
+#define TIZEN_DEBUG_ENABLE\r
+#endif\r
+\r
+#ifdef LOG_TAG\r
+#undef LOG_TAG\r
+#endif\r
+/* Literal to filter logs from dlogutil */\r
+#define LOG_TAG "SHOP_ADAPTOR"\r
+\r
+\r
+#ifndef WORK_IN_LOCAL\r
+#include <dlog.h>\r
+#else\r
+#define LOGE(fmt, arg...)\r
+#define LOGD(fmt, arg...)\r
+#define LOGI(fmt, arg...)\r
+#define LOGF(fmt, arg...)\r
+#define LOGW(fmt, arg...)\r
+#endif\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif /* __cplusplus */\r
+\r
+       /**\r
+        *  Colors of font\r
+        */\r
+#define FONT_COLOR_RESET      "\033[0m"\r
+#define FONT_COLOR_BLACK      "\033[30m"             /* Black */\r
+#define FONT_COLOR_RED        "\033[31m"             /* Red */\r
+#define FONT_COLOR_GREEN      "\033[32m"             /* Green */\r
+#define FONT_COLOR_YELLOW     "\033[33m"             /* Yellow */\r
+#define FONT_COLOR_BLUE       "\033[34m"             /* Blue */\r
+#define FONT_COLOR_PURPLE     "\033[35m"             /* Purple */\r
+#define FONT_COLOR_CYAN       "\033[36m"             /* Cyan */\r
+#define FONT_COLOR_WHITE      "\033[37m"             /* White */\r
+#define FONT_COLOR_BOLDBLACK  "\033[1m\033[30m"      /* Bold Black */\r
+#define FONT_COLOR_BOLDRED    "\033[1m\033[31m"      /* Bold Red */\r
+#define FONT_COLOR_BOLDGREEN  "\033[1m\033[32m"      /* Bold Green */\r
+#define FONT_COLOR_BOLDYELLOW "\033[1m\033[33m"      /* Bold Yellow */\r
+#define FONT_COLOR_BOLDBLUE   "\033[1m\033[34m"      /* Bold Blue */\r
+#define FONT_COLOR_BOLDPURPLE "\033[1m\033[35m"      /* Bold Purple */\r
+#define FONT_COLOR_BOLDCYAN   "\033[1m\033[36m"      /* Bold Cyan */\r
+#define FONT_COLOR_BOLDWHITE  "\033[1m\033[37m"      /* Bold White */\r
+\r
+       /**\r
+        *  Gets thread ID\r
+        */\r
+#define shop_adaptor_gettid() syscall(__NR_gettid)\r
+\r
+/**\r
+ *  @brief Macro for returning value if expression is satisfied\r
+ *  @param[in]  expr Expression to be checked\r
+ *  @param[out] val  Value to be returned when expression is true\r
+ */\r
+#define shop_adaptor_retv_if(expr, val) do { \\r
+            if(expr) { \\r
+                LOGE(FONT_COLOR_PURPLE"[%d]"FONT_COLOR_RESET, shop_adaptor_gettid());    \\r
+                return (val); \\r
+            } \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints debug messages\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define shop_adaptor_debug(fmt, arg...) do { \\r
+            LOGD(FONT_COLOR_GREEN"[%d]"fmt""FONT_COLOR_RESET, shop_adaptor_gettid(), ##arg);     \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints info messages\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define shop_adaptor_info(fmt, arg...) do { \\r
+            LOGI(FONT_COLOR_BLUE"[%d]"fmt""FONT_COLOR_RESET, shop_adaptor_gettid() ,##arg);     \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints warning messages\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define shop_adaptor_warning(fmt, arg...) do { \\r
+            LOGW(FONT_COLOR_YELLOW"[%d]"fmt""FONT_COLOR_RESET,shop_adaptor_gettid(), ##arg);     \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints error messages\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define shop_adaptor_error(fmt, arg...) do { \\r
+            LOGE(FONT_COLOR_RED"[%d]"fmt""FONT_COLOR_RESET,shop_adaptor_gettid(), ##arg);     \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints fatal messages\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define shop_adaptor_fatal(fmt, arg...) do { \\r
+            LOGF(FONT_COLOR_BOLDRED"[%d]"fmt""FONT_COLOR_RESET,shop_adaptor_gettid(), ##arg);     \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints debug message on entry to particular function\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define shop_adaptor_debug_func(fmt, arg...) do { \\r
+            LOGD(FONT_COLOR_CYAN"[%d]"fmt""FONT_COLOR_RESET, shop_adaptor_gettid(), ##arg);     \\r
+        } while (0)\r
+\r
+#define plugin_req_enter()                     do { \\r
+               shop_adaptor_info("[ENTER] plugin API call -)) -)) -)) -)) -)) -)) -)) -)) -)) -))"); \\r
+       } while (0)\r
+\r
+#define plugin_req_exit(ret, plugin, error)    do { \\r
+               shop_adaptor_info("[EXIT] plugin API called (%d) ((- ((- ((- ((- ((- ((- ((- ((- ((- ((-", (int)(ret)); \\r
+               if ((error)) { \\r
+                       if ((*error)) { \\r
+                               shop_adaptor_error("plugin issued error (%lld) (%s)", (long long int)((*error)->code), (char *)((*error)->msg)); \\r
+                               char *tem = g_strdup_printf("[PLUGIN_ERROR] URI(%s), MSG(%s)", (char *)((plugin)->handle->plugin_uri), (char *)((*error)->msg)); \\r
+                               if (tem) { \\r
+                                       free((*error)->msg); \\r
+                                       (*error)->msg = tem; \\r
+                               } \\r
+                       } \\r
+               } \\r
+       } while (0)\r
+\r
+#define plugin_req_exit_void()                 do { \\r
+               shop_adaptor_info("[EXIT] plugin API called ((- ((- ((- ((- ((- ((- ((- ((- ((- ((-"); \\r
+       } while (0)\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+\r
+#endif /* __SHOP_ADAPTOR_LOG_H__ */\r
+\r
diff --git a/adaptor/shop-adaptor/shop-adaptor.c b/adaptor/shop-adaptor/shop-adaptor.c
new file mode 100644 (file)
index 0000000..b0af4dc
--- /dev/null
@@ -0,0 +1,876 @@
+/*
+* Copyright (c) 2011 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.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <glib.h>
+
+#include "shop-adaptor.h"
+#include "shop-adaptor-log.h"
+
+/**
+ * Shop adaptor plugin
+ */
+typedef struct shop_adaptor_plugin_s {
+       shop_adaptor_h                  adaptor;                        /* Adaptor */
+       char                            *path;                          /* Plugin library path */
+       shop_adaptor_plugin_handle_h    handle;                         /* Plugin handle */
+       void                            *dl_handle;                     /* Plugin library handle */
+       int                             ref_counter;                    /* Plugin reference counter */
+       GMutex                          ref_counter_mutex;              /* Plugin reference counter mutex */
+       shop_adaptor_plugin_listener_h  plugin_listener;                /* Plugin callback listener */
+       GMutex                          plugin_listener_mutex;          /* Plugin callback listener mutex */
+} shop_adaptor_plugin_t;
+
+/**
+ * Shop adaptor
+ */
+typedef struct shop_adaptor_s {
+       GMutex  shop_adaptor_mutex;             /* Adaptor mutex */
+       int     started;                        /* Started flag */
+       char    *plugins_dir;                   /* Plugins directory path */
+       GList   *plugins;                       /* List of loaded plugins */
+       GMutex  plugins_mutex;                  /* Plugin list mutex */
+       GList   *adaptor_listeners;             /* List of vservice channel listener (for now not effective) */
+       GMutex  adaptor_listeners_mutex;        /* Listener list mutex */
+} shop_adaptor_t;
+
+/**
+ * Creates plugin
+ */
+static shop_adaptor_plugin_h shop_adaptor_create_plugin(const char *plugin_path);
+
+/**
+ * Destroys plugin and deletes all resources associated with it
+ */
+static void shop_adaptor_destroy_plugin(shop_adaptor_plugin_h plugin);
+
+/**
+ * Loads plugins from selected directory
+ */
+static int shop_adaptor_load_plugins_from_directory(shop_adaptor_h adaptor, const char *dir_path);
+
+/**
+ * Checks if plugin is loaded by selected plugin adaptor
+ */
+static int shop_adaptor_has_plugin(shop_adaptor_h adaptor, shop_adaptor_plugin_h plugin);
+
+/**
+ * Increases adaptor's plugin references counter
+ */
+static void shop_adaptor_plugin_ref(shop_adaptor_plugin_h);
+
+/**
+ * Decreases adaptor's plugin references counter
+ */
+static void shop_adaptor_plugin_unref(shop_adaptor_plugin_h);
+
+/* //------------------------------------------------------------------------
+   // Functions implementations
+   //------------------------------------------------------------------------ */
+
+/* //////////////////////////////////////////////////////
+   // Mandatory: External adaptor management function
+   ////////////////////////////////////////////////////// */
+
+EXPORT_API
+shop_adaptor_h shop_adaptor_create(const char *plugins_dir)
+{
+       shop_adaptor_h shop_adaptor = (shop_adaptor_h) malloc(sizeof(shop_adaptor_t));
+       if (NULL == shop_adaptor) {
+           return NULL;
+       }
+
+       shop_adaptor->started = 0;
+       shop_adaptor->plugins_dir = strdup(plugins_dir);
+
+       g_mutex_init(&shop_adaptor->shop_adaptor_mutex);
+       g_mutex_init(&shop_adaptor->plugins_mutex);
+       g_mutex_init(&shop_adaptor->adaptor_listeners_mutex);
+
+       g_mutex_lock(&shop_adaptor->adaptor_listeners_mutex);
+       shop_adaptor->adaptor_listeners = NULL;
+       g_mutex_unlock(&shop_adaptor->adaptor_listeners_mutex);
+
+       g_mutex_lock(&shop_adaptor->plugins_mutex);
+       shop_adaptor->plugins = NULL;
+       g_mutex_unlock(&shop_adaptor->plugins_mutex);
+
+       return shop_adaptor;
+
+}
+
+EXPORT_API
+void shop_adaptor_destroy(shop_adaptor_h adaptor)
+{
+       if (NULL == adaptor) {
+               shop_adaptor_error("Invalid argument");
+               return ;
+       }
+
+       g_mutex_lock(&adaptor->shop_adaptor_mutex);
+       if (adaptor->started) {
+               shop_adaptor_error("Shop adaptor is running. Forcing stop before destroy");
+               shop_adaptor_stop(adaptor);
+       }
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       if (NULL != adaptor->plugins) {
+               g_list_free_full(adaptor->plugins, (GDestroyNotify) shop_adaptor_plugin_unref);
+               adaptor->plugins = NULL;
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+       if (NULL != adaptor->adaptor_listeners) {
+               g_list_free(adaptor->adaptor_listeners);
+               adaptor->adaptor_listeners = NULL;
+       }
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+
+       /*TODO */
+       /*please add destroying lisners if it needed, currently it is not needed */
+
+       free(adaptor->plugins_dir);
+       adaptor->plugins_dir = NULL;
+
+       g_mutex_unlock(&adaptor->shop_adaptor_mutex);
+
+       free(adaptor);
+}
+
+EXPORT_API
+int shop_adaptor_start(shop_adaptor_h adaptor)
+{
+       shop_adaptor_debug("Starting shop adaptor");
+       if (NULL == adaptor) {
+               shop_adaptor_error("Invalid argument");
+               return SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->shop_adaptor_mutex);
+       int result = SHOP_ADAPTOR_ERROR_NONE;
+       if (adaptor->started) {
+               shop_adaptor_error("Storage adaptor is already started");
+               result = SHOP_ADAPTOR_ERROR_START;
+       } else {
+               adaptor->started = 1;
+               result = shop_adaptor_load_plugins_from_directory(adaptor, adaptor->plugins_dir);
+               if (SHOP_ADAPTOR_ERROR_NONE != result) {
+                       adaptor->started = 0;
+                       shop_adaptor_error("Could not load plugins from directory");
+               } else {
+                       shop_adaptor_debug("Storage adaptor started successfully");
+               }
+       }
+       g_mutex_unlock(&adaptor->shop_adaptor_mutex);
+
+       return result;
+}
+
+/**
+ * Stops shop adaptor.
+ */
+EXPORT_API
+int shop_adaptor_stop(shop_adaptor_h adaptor)
+{
+       if (NULL == adaptor) {
+               shop_adaptor_error("Invalid argument");
+               return SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->shop_adaptor_mutex);
+       int result = SHOP_ADAPTOR_ERROR_NONE;
+       if (!adaptor->started) {
+               result = SHOP_ADAPTOR_ERROR_START;
+       } else {
+               if (NULL != adaptor->plugins) {
+                       g_mutex_lock(&adaptor->plugins_mutex);
+                       g_list_free_full(adaptor->plugins, (GDestroyNotify) shop_adaptor_plugin_unref);
+                       adaptor->plugins = NULL;
+                       g_mutex_unlock(&adaptor->plugins_mutex);
+               }
+               adaptor->started = 0;
+               shop_adaptor_debug("Shop adaptor stopped");
+       }
+
+       g_mutex_unlock(&adaptor->shop_adaptor_mutex);
+       return result;
+}
+
+/**
+ * Registers plugin state listener
+ */
+EXPORT_API
+int shop_adaptor_register_listener(shop_adaptor_h adaptor, shop_adaptor_listener_h listener)
+{
+       if ((NULL == adaptor) || (NULL == listener)) {
+               shop_adaptor_error("Invalid argument");
+               return SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+
+       adaptor->adaptor_listeners = g_list_append(adaptor->adaptor_listeners, listener);
+
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+
+       return SHOP_ADAPTOR_ERROR_NONE;
+}
+
+/**
+ * Unregisters plugin state listener
+ */
+EXPORT_API
+int shop_adaptor_unregister_listener(shop_adaptor_h adaptor, shop_adaptor_listener_h listener)
+{
+       if ((NULL == adaptor) || (NULL == listener)) {
+               shop_adaptor_error("Invalid argument");
+               return SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+
+       if (NULL == g_list_find(adaptor->adaptor_listeners, listener)) {
+               g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+               shop_adaptor_error("Could not find listener");
+               return SHOP_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       adaptor->adaptor_listeners = g_list_remove(adaptor->adaptor_listeners, listener);
+
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+
+       return SHOP_ADAPTOR_ERROR_NONE;
+}
+
+/* /////////////////////////////////////////////////////////////
+   // Plugin create / destroy / ref. count / get plugin name
+   ///////////////////////////////////////////////////////////// */
+static shop_adaptor_plugin_h shop_adaptor_create_plugin(const char *plugin_path)
+{
+       if (NULL == plugin_path) {
+               shop_adaptor_error("Invalid argument");
+               return NULL;
+       }
+
+       void *dl_handle = dlopen(plugin_path, RTLD_LAZY);
+       if (NULL == dl_handle) {
+               shop_adaptor_error("Could not load plugin %s: %s", plugin_path, dlerror());
+               return NULL;
+       }
+
+       shop_adaptor_plugin_handle_h (*get_adaptee_handle)(void) = NULL;
+
+       get_adaptee_handle = (shop_adaptor_plugin_handle_h (*)(void)) (dlsym(dl_handle, "create_plugin_handle"));
+       if (NULL == get_adaptee_handle) {
+               dlclose(dl_handle);
+               shop_adaptor_error("Could not get function pointer to create_plugin_handle");
+               return NULL;
+       }
+
+       plugin_req_enter();
+       shop_adaptor_plugin_handle_h handle = get_adaptee_handle();
+       plugin_req_exit_void();
+
+       if (NULL == handle) {
+               dlclose(dl_handle);
+               shop_adaptor_error("Could not get adaptee handle");
+               return NULL;
+       }
+
+       shop_adaptor_plugin_h plugin = (shop_adaptor_plugin_h) malloc(sizeof(shop_adaptor_plugin_t));
+       if (NULL == plugin) {
+               dlclose(dl_handle);
+               shop_adaptor_error("Could not create plugin object");
+               return NULL;
+       }
+
+       plugin->path = g_strdup(plugin_path);
+       plugin->handle = handle;
+       plugin->dl_handle = dl_handle;
+       plugin->ref_counter = 0;
+
+       g_mutex_init(&plugin->ref_counter_mutex);
+       g_mutex_init(&plugin->plugin_listener_mutex);
+
+       shop_adaptor_plugin_listener_h listener =
+                       (shop_adaptor_plugin_listener_h) malloc(sizeof(shop_adaptor_plugin_listener_t));
+
+       plugin_req_enter();
+       plugin->handle->set_listener(listener);
+       plugin_req_exit_void();
+       g_mutex_lock(&plugin->plugin_listener_mutex);
+       plugin->plugin_listener = listener;
+       g_mutex_unlock(&plugin->plugin_listener_mutex);
+
+       return plugin;
+}
+
+static void shop_adaptor_destroy_plugin(shop_adaptor_plugin_h plugin)
+{
+       if (NULL == plugin) {
+               shop_adaptor_error("Invalid argument");
+               return;
+       }
+
+       if (NULL != plugin->handle) {
+               plugin->handle->destroy_handle(plugin->handle);
+
+               g_mutex_lock(&plugin->plugin_listener_mutex);
+               plugin_req_enter();
+               plugin->handle->unset_listener();
+               plugin_req_exit_void();
+               g_mutex_unlock(&plugin->plugin_listener_mutex);
+
+               plugin->handle = NULL;
+       }
+
+       if (NULL != plugin->dl_handle) {
+               dlclose(plugin->dl_handle);
+               plugin->dl_handle = NULL;
+       }
+
+       free(plugin->path);
+       plugin->path = NULL;
+
+       free(plugin);
+}
+
+static int shop_adaptor_load_plugins_from_directory(shop_adaptor_h adaptor, const char *dir_path)
+{
+       char *plugin_path = NULL;
+       DIR *dir = NULL;
+       struct dirent dir_entry, *result = NULL;
+
+       shop_adaptor_debug("Starting load plugins from directory");
+
+       if ((NULL == adaptor) || (NULL == dir_path)) {
+               shop_adaptor_error("Invalid argument");
+               return SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       dir = opendir(dir_path);
+       if (NULL == dir) {
+               shop_adaptor_error("Could not open dir path (%s)", dir_path);
+               return SHOP_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       int ret = SHOP_ADAPTOR_ERROR_NONE;
+       while (0 == (readdir_r(dir, &dir_entry, &result))) {
+
+               if (NULL == result) {
+                       shop_adaptor_error("Could not open directory %s", plugin_path);
+                       break;
+               }
+
+               if (dir_entry.d_type & DT_DIR) {
+                       continue;
+               }
+
+               plugin_path = g_strconcat(dir_path, "/", dir_entry.d_name, NULL);
+               shop_adaptor_plugin_h plugin = shop_adaptor_create_plugin(plugin_path);
+
+               if (NULL != plugin) {
+                       shop_adaptor_debug("Loaded plugin: %s", plugin_path);
+                       plugin->adaptor = adaptor;
+                       shop_adaptor_plugin_ref(plugin);
+                       g_mutex_lock(&adaptor->plugins_mutex);
+                       adaptor->plugins = g_list_append(adaptor->plugins, plugin);
+                       g_mutex_unlock(&adaptor->plugins_mutex);
+               } else {
+                       shop_adaptor_error("Could not load plugin %s", plugin_path);
+               }
+
+               free(plugin_path);
+               plugin_path = NULL;
+       }
+
+       shop_adaptor_debug("End load plugins from directory");
+       closedir(dir);
+       return ret;
+}
+
+
+static int shop_adaptor_has_plugin(shop_adaptor_h adaptor, shop_adaptor_plugin_h plugin)
+{
+       if ((NULL == adaptor) || (NULL == plugin)) {
+               shop_adaptor_error("Invalid argument");
+               return 0;
+       }
+
+       int result = 0;
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       if (NULL != g_list_find(adaptor->plugins, plugin)) {
+               result = 1;
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return result;
+}
+
+static void shop_adaptor_plugin_ref(shop_adaptor_plugin_h plugin)
+{
+       if (NULL == plugin) {
+               shop_adaptor_error("Invalid argument");
+               return;
+       }
+
+       g_mutex_lock(&plugin->ref_counter_mutex);
+       plugin->ref_counter = plugin->ref_counter + 1;
+       if (NULL != plugin->handle) {
+               shop_adaptor_info("plugin name : %s, ref_counter: %d", plugin->handle->plugin_uri, plugin->ref_counter);
+       } else {
+               shop_adaptor_info("ref_counter : %d", plugin->ref_counter);
+       }
+       g_mutex_unlock(&plugin->ref_counter_mutex);
+}
+
+static void shop_adaptor_plugin_unref(shop_adaptor_plugin_h plugin)
+{
+       if (NULL == plugin) {
+               shop_adaptor_error("Invalid argument");
+               return ;
+       }
+
+       int should_destroy = 0;
+
+       g_mutex_lock(&plugin->ref_counter_mutex);
+       plugin->ref_counter = plugin->ref_counter - 1;
+
+       if (NULL != plugin->handle) {
+               shop_adaptor_info("plugin name : %s, ref_counter: %d", plugin->handle->plugin_uri, plugin->ref_counter);
+       } else {
+               shop_adaptor_info("ref_counter : %d", plugin->ref_counter);
+       }
+
+       if (0 >= plugin->ref_counter) {
+               should_destroy = 1;
+       }
+       g_mutex_unlock(&plugin->ref_counter_mutex);
+
+       if (should_destroy) {
+               shop_adaptor_debug("Plugin is being destroyed");
+               shop_adaptor_destroy_plugin(plugin);
+       }
+}
+
+/**
+ * Refresh access token
+ */
+EXPORT_API
+shop_error_code_t shop_adaptor_refresh_access_token(shop_adaptor_plugin_context_h context,
+                                               const char *new_access_token)
+{
+       if ((NULL == context) || (NULL == new_access_token) || (0 >= strlen(new_access_token))) {
+               return SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+       shop_adaptor_debug("New access token : %s", new_access_token);
+
+       free(context->access_token);
+       context->access_token = NULL;
+       context->access_token = strdup(new_access_token);
+
+       return SHOP_ADAPTOR_ERROR_NONE;
+}
+
+EXPORT_API
+shop_error_code_t shop_adaptor_refresh_uid(shop_adaptor_plugin_context_h context,
+               const char *new_uid)
+{
+       if ((NULL == context) || (NULL == new_uid) || (0 >= strlen(new_uid))) {
+               return SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+       shop_adaptor_debug("New uid : %s", new_uid);
+
+       free(context->duid);
+       context->duid = NULL;
+       context->duid = strdup(new_uid);
+
+       return SHOP_ADAPTOR_ERROR_NONE;
+}
+
+/* //////////////////////////////////////////////////////
+   // Create / Destroy error code
+   ////////////////////////////////////////////////////// */
+shop_adaptor_error_code_h shop_adaptor_create_error_code(const int64_t code, const char *msg)
+{
+       if (NULL == msg) {
+               return NULL;
+       }
+
+       shop_adaptor_error_code_h error_code =
+                       (shop_adaptor_error_code_h) malloc(sizeof(shop_adaptor_error_code_t));
+       if (NULL == error_code) {
+           return NULL;
+       }
+
+       error_code->code = code;
+       error_code->msg = strdup(msg);
+
+       return error_code;
+}
+
+void shop_adaptor_destroy_error_code(shop_adaptor_error_code_h *error_code)
+{
+       if ((NULL != error_code) && (NULL != (*error_code))) {
+               free((*error_code)->msg);
+               (*error_code)->msg = NULL;
+               free(*error_code);
+               *error_code = NULL;
+       }
+}
+
+
+/* //////////////////////////////////////////////////////
+   // Plugin context create / destroy
+   ////////////////////////////////////////////////////// */
+shop_adaptor_plugin_context_h shop_adaptor_create_plugin_context(shop_adaptor_plugin_h plugin, char *plugin_uri, char *duid, char *access_token, char *app_id, char *apptype)
+{
+       shop_adaptor_debug("Starting shop_adaptor_create_plugin_context");
+
+       if (NULL == plugin) {
+               shop_adaptor_error("Invalid argument");
+               return NULL;
+       }
+
+       if (NULL != plugin->handle) {
+               shop_adaptor_plugin_context_h plugin_context = NULL;
+
+               plugin_req_enter();
+               plugin->handle->create_context(&plugin_context, duid, access_token, app_id, apptype);
+               plugin_req_exit_void();
+
+               plugin_context->plugin_uri = strdup(plugin->handle->plugin_uri);
+               return plugin_context;
+       } else {
+               shop_adaptor_error("Plugin handle is null");
+       }
+
+       shop_adaptor_debug("End shop_adaptor_create_plugin_context");
+       return NULL;
+}
+
+void shop_adaptor_destroy_plugin_context(shop_adaptor_plugin_h plugin, shop_adaptor_plugin_context_h plugin_context)
+{
+       shop_adaptor_warning("Starting shop_adaptor_get_plugin_by_name");
+
+       if ((NULL == plugin) || (NULL == plugin_context)) {
+               shop_adaptor_error("Invalid argument");
+               return;
+       }
+
+       if (NULL != plugin->handle) {
+               plugin_req_enter();
+               plugin->handle->destroy_context(plugin_context);
+               plugin_req_exit_void();
+       } else {
+               shop_adaptor_error("Plugin handle is null");
+       }
+}
+
+/* //////////////////////////////////////////////////////
+   // Get plugin by plugin name
+   ////////////////////////////////////////////////////// */
+shop_adaptor_plugin_h shop_adaptor_get_plugin_by_name(shop_adaptor_h adaptor, const char *plugin_name)
+{
+       shop_adaptor_warning("Starting shop_adaptor_get_plugin_by_name");
+
+       if ((NULL == adaptor) || (NULL == plugin_name)) {
+               shop_adaptor_error("Invalid argument");
+               return NULL;
+       }
+
+       shop_adaptor_plugin_h plugin = NULL;
+       g_mutex_lock(&adaptor->plugins_mutex);
+       int count = g_list_length(adaptor->plugins);
+       int i = 0;
+       for (i = 0; i < count; i++) {
+               shop_adaptor_plugin_h temp_plugin = (shop_adaptor_plugin_h)g_list_nth_data(adaptor->plugins, i);
+               if (NULL != temp_plugin) {
+                       if (0 == strcmp(temp_plugin->handle->plugin_uri, plugin_name)) {
+                               shop_adaptor_plugin_ref(temp_plugin);
+                               plugin = temp_plugin;
+                               g_mutex_unlock(&adaptor->plugins_mutex);
+                               return plugin;
+                       }
+               }
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       if (NULL == plugin) {
+               shop_adaptor_debug("Plugin is not found by name");
+       }
+
+       return plugin;
+}
+
+/* //////////////////////////////////////////////////////
+   // Plugin load / unload / get plugin list
+   ////////////////////////////////////////////////////// */
+int shop_adaptor_load_plugin(shop_adaptor_h adaptor, const char *plugin_path)
+{
+       if ((NULL == adaptor) || (NULL == plugin_path)) {
+               shop_adaptor_error("Invalid argument");
+               return SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (!adaptor->started) {
+               shop_adaptor_error("Storage adaptor is not started");
+               return SHOP_ADAPTOR_ERROR_START;
+       }
+
+       shop_adaptor_plugin_h plugin = shop_adaptor_create_plugin(plugin_path);
+       if (NULL == plugin) {
+               shop_adaptor_error("Could not load plugin %s", plugin_path);
+               return SHOP_ADAPTOR_ERROR_CREATE;
+       }
+
+       plugin->adaptor = adaptor;
+       shop_adaptor_plugin_ref(plugin);
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       adaptor->plugins = g_list_append(adaptor->plugins, plugin);
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return SHOP_ADAPTOR_ERROR_NONE;
+}
+
+int shop_adaptor_unload_plugin(shop_adaptor_h adaptor, shop_adaptor_plugin_h plugin)
+{
+       if ((NULL == adaptor) || (NULL == plugin)) {
+               shop_adaptor_error("Invalid argument");
+               return SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (!adaptor->started) {
+               shop_adaptor_error("Storage adaptor is not started");
+               return SHOP_ADAPTOR_ERROR_START;
+       }
+
+       if (!shop_adaptor_has_plugin(adaptor, plugin)) {
+               shop_adaptor_error("Storage adaptor has no plugin");
+               return SHOP_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       plugin->adaptor = NULL;
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       adaptor->plugins = g_list_remove(adaptor->plugins, plugin);
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       shop_adaptor_plugin_unref(plugin);
+
+       return SHOP_ADAPTOR_ERROR_NONE;
+}
+
+GList *shop_adaptor_get_plugins(shop_adaptor_h adaptor)
+{
+       if (NULL == adaptor) {
+               shop_adaptor_error("Invalid argument");
+               return NULL;
+       }
+
+       GList *plugins = NULL;
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       int plugins_count = g_list_length(adaptor->plugins);
+       int i;
+       for (i = 0; i < plugins_count; i++) {
+               shop_adaptor_plugin_h plugin = (shop_adaptor_plugin_h)g_list_nth_data(adaptor->plugins, i);
+               if (NULL != plugin) {
+                       shop_adaptor_plugin_ref(plugin);
+                       plugins = g_list_append(plugins, plugin);
+               }
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return plugins;
+
+}
+
+EXPORT_API
+shop_error_code_t shop_adaptor_set_server_info(shop_adaptor_plugin_h plugin,
+                                               shop_adaptor_plugin_context_h context,
+                                               GHashTable *server_info,
+                                               shop_adaptor_error_code_h *error_code)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               shop_adaptor_error("Invalid argument");
+
+               *error_code = shop_adaptor_create_error_code((int64_t) SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                                               "Invalid argument (plugin or context)");
+
+               return SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               shop_adaptor_error("Plugin handle is null");
+
+               *error_code = shop_adaptor_create_error_code((int64_t) SHOP_ADAPTOR_ERROR_INVALID_HANDLE,
+                                                               "Plugin handle is null");
+
+               return SHOP_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       shop_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->set_server_info(context, server_info, error_code);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+/* ////////////////////////////////////////////////////////////
+   // Adaptor Plugin call Functions
+   //////////////////////////////////////////////////////////// */
+EXPORT_API
+shop_error_code_t shop_adaptor_get_item_list_v1(shop_adaptor_plugin_h plugin, shop_adaptor_plugin_context_h context, shop_adaptor_shop_info_s *info, void *user_data, shop_adaptor_shop_item_s ***items, unsigned int *items_len, shop_adaptor_error_code_h *error_code, void **server_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               shop_adaptor_error("Invalid argument");
+
+               *error_code = shop_adaptor_create_error_code(
+                               (int64_t) SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                               "Invalid argument (plugin or context)");
+
+               return SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               shop_adaptor_error("Plugin handle is null");
+
+               *error_code = shop_adaptor_create_error_code(
+                               (int64_t) SHOP_ADAPTOR_ERROR_INVALID_HANDLE,
+                               "Plugin handle is null");
+
+               return SHOP_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       shop_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->get_item_list_v1(context, info, user_data, items, items_len, error_code, server_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+shop_error_code_t shop_adaptor_download_item_package_v1(shop_adaptor_plugin_h plugin, shop_adaptor_plugin_context_h context, shop_adaptor_shop_info_s *info, void *user_data, shop_adaptor_shop_item_s **item, shop_adaptor_error_code_h *error_code, void **server_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               shop_adaptor_error("Invalid argument");
+
+               *error_code = shop_adaptor_create_error_code(
+                               (int64_t) SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                               "Invalid argument (plugin or context)");
+
+               return SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               shop_adaptor_error("Plugin handle is null");
+
+               *error_code = shop_adaptor_create_error_code(
+                               (int64_t) SHOP_ADAPTOR_ERROR_INVALID_HANDLE,
+                               "Plugin handle is null");
+
+               return SHOP_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       shop_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->download_item_package_v1(context, info, user_data, item, error_code, server_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+shop_error_code_t shop_adaptor_download_sticker_v1(shop_adaptor_plugin_h plugin, shop_adaptor_plugin_context_h context, shop_adaptor_shop_info_s *info, void *user_data, shop_adaptor_shop_item_s **item, shop_adaptor_error_code_h *error_code, void **server_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               shop_adaptor_error("Invalid argument");
+
+               *error_code = shop_adaptor_create_error_code(
+                               (int64_t) SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                               "Invalid argument (plugin or context)");
+
+               return SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               shop_adaptor_error("Plugin handle is null");
+
+               *error_code = shop_adaptor_create_error_code(
+                               (int64_t) SHOP_ADAPTOR_ERROR_INVALID_HANDLE,
+                               "Plugin handle is null");
+
+               return SHOP_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       shop_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->download_sticker_v1(context, info, user_data, item, error_code, server_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
+
+EXPORT_API
+shop_error_code_t shop_adaptor_get_panel_url_v1(shop_adaptor_plugin_h plugin, shop_adaptor_plugin_context_h context, shop_adaptor_shop_info_s *info, void *user_data, shop_adaptor_shop_item_s **item, shop_adaptor_error_code_h *error_code, void **server_data)
+{
+       if ((NULL == plugin) || (NULL == context)) {
+               shop_adaptor_error("Invalid argument");
+
+               *error_code = shop_adaptor_create_error_code(
+                               (int64_t) SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                               "Invalid argument (plugin or context)");
+
+               return SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (NULL == plugin->handle) {
+               shop_adaptor_error("Plugin handle is null");
+
+               *error_code = shop_adaptor_create_error_code(
+                               (int64_t) SHOP_ADAPTOR_ERROR_INVALID_HANDLE,
+                               "Plugin handle is null");
+
+               return SHOP_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       if (NULL == info) {
+               shop_adaptor_error("info handle is null");
+
+               *error_code = shop_adaptor_create_error_code(
+                               (int64_t) SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                               "Info handle is null");
+
+               return SHOP_ADAPTOR_ERROR_INVALID_HANDLE;
+       }
+
+       shop_error_code_t ret;
+       plugin_req_enter();
+       ret = plugin->handle->get_panel_url_v1(context, info, user_data, item, error_code, server_data);
+       plugin_req_exit(ret, plugin, error_code);
+
+       return ret;
+}
diff --git a/adaptor/shop-adaptor/shop-adaptor.h b/adaptor/shop-adaptor/shop-adaptor.h
new file mode 100644 (file)
index 0000000..2ae629b
--- /dev/null
@@ -0,0 +1,462 @@
+/*
+* Copyright (c) 2011 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.
+*/
+
+/******************************************************************************
+ * File: shop-adaptor.h
+ * Desc: Shop Adaptor APIs
+ * Created on: Oct, 2014
+ * Auth: Jaehoon Lee <j_hoon85.lee@samsung.com>
+ *
+ *****************************************************************************/
+/**
+ *      @file           shop-adaptor.h
+ *      @brief         Defines interface of Shop Adaptor
+ *      @version    0.1
+ */
+
+#ifndef __SHOP_ADAPTOR_H__
+#define __SHOP_ADAPTOR_H__
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+#include <glib.h>
+#include <stdint.h>
+/**
+ * @ brief Shop adaptor error code
+ */
+typedef enum shop_error_code_e
+{
+       SHOP_ADAPTOR_ERROR_NONE                     =  0,
+       SHOP_ADAPTOR_ERROR_LAUNCH                    = 1,    /**< 1 ~ 99: internal error*/
+       SHOP_ADAPTOR_ERROR_INIT                      = 2,
+       SHOP_ADAPTOR_ERROR_DEINIT                    = 3,
+       SHOP_ADAPTOR_ERROR_CREATE                    = 4,
+       SHOP_ADAPTOR_ERROR_DESTROY                   = 5,
+       SHOP_ADAPTOR_ERROR_START                     = 6,
+       SHOP_ADAPTOR_ERROR_STOP                      = 7,
+       SHOP_ADAPTOR_ERROR_CONNECT                   = 8,
+       SHOP_ADAPTOR_ERROR_DISCONNECT                = 9,
+       SHOP_ADAPTOR_ERROR_NOT_FOUND                 = 10,
+       SHOP_ADAPTOR_ERROR_CORRUPTED                 = 11,
+       SHOP_ADAPTOR_ERROR_UNSUPPORTED               = 12,
+       SHOP_ADAPTOR_ERROR_INVALID_HANDLE            = 13,
+       SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT          = 14,
+       SHOP_ADAPTOR_ERROR_INVALID_ARGUMENT_TYPE     = 15,
+       SHOP_ADAPTOR_ERROR_NOT_AUTHORIZED            = 16,
+       SHOP_ADAPTOR_ERROR_ADAPTOR_INTERNAL          = 17,
+       SHOP_ADAPTOR_ERROR_PLUGIN_INTERNAL           = 18,
+       SHOP_ADAPTOR_ERROR_SERVER_INTERNAL           = 19,
+       SHOP_ADAPTOR_ERROR_DBUS                      = 20,
+       SHOP_ADAPTOR_ERROR_CALLBACK_TIME_OUT         = 21,
+       SHOP_ADAPTOR_ERROR_MAX
+} shop_error_code_t;
+
+
+/**
+ *  @ brief Shop adaptor plugin handle
+ */
+typedef struct shop_adaptor_plugin_s *shop_adaptor_plugin_h;
+
+/**
+ *  @ brief Shop adaptor
+ */
+typedef struct shop_adaptor_s *shop_adaptor_h;
+
+/**
+* @brief Describes infromation about shop
+*/
+typedef struct _service_adaptor_shop_info_s
+{
+       int category_id;                /**< specifies category id of item*/
+       long item_id;                   /**< specifies item id*/
+       long sticker_id;                /**< specifies sticker id*/
+       char *lang_cd;                  /**< specifies display language type*/
+       char *cntry_cd;                 /**< specifies country code*/
+       int rwidth;                     /**< specifies device resolution width*/
+       int rheight;                    /**< specifies device resolution height*/
+       int start_idx;                  /**< default value : 0*/
+       int count;                      /**< default value : 5*/
+} shop_adaptor_shop_info_s;
+
+/**
+* @ brief Describes infromation about item
+*/
+typedef struct _service_adaptor_shop_item_s
+{
+       long item_id;                   /**< specifies item id*/
+       int category_id;                /**< specifies category id of item*/
+       long *sticker_ids;              /**< specifies sticker id*/
+       unsigned int sticker_ids_len; /**< specifies sticker id list length*/
+       char *title;                    /**< specifies title*/
+       char *character;                /**< specifies character*/
+       int version;                    /**< specifies version*/
+       char *download_url;     /**< specifies download_url*/
+       char *panel_url;                /**< specifies panel_url*/
+       char *sticker_url;              /**< specifies sticker_url*/
+       long file_size;                 /**< specifies file_size*/
+       int count;                      /**< specifies count*/
+       char *character_code;           /**< specifies character_code*/
+       long long int startdate;                        /**< specifies startdate*/
+       long long int enddate;                  /**< specifies enddate*/
+       long long int expired_date;             /**< specifies expired_date*/
+       long long int valid_period;             /**< specifies valid_period*/
+} shop_adaptor_shop_item_s;
+
+
+/**
+ * @ brief Shop adaptor plugin context structure
+ */
+typedef struct shop_adaptor_plugin_context_s
+{
+       char *duid;
+       char *access_token;
+       char *appid;
+       char *apptype;
+       char *plugin_uri;
+
+} shop_adaptor_plugin_context_t;
+
+typedef struct shop_adaptor_plugin_context_s *shop_adaptor_plugin_context_h;
+
+
+typedef enum shop_plugin_result_code_e
+{
+       SHOP_PLUGIN_RESULT_SUCCEDED = 0,
+       SHOP_PLUGIN_RESULT_FAILED = -1,
+       SHOP_PLUGIN_RESULT_CANCELED = -2
+} shop_plugin_result_code_t;
+
+/**
+ * @brief Enumerations of signal code for Service Adaptor
+ */
+typedef enum _shop_adaptor_error_e
+{
+       SERVICE_ADAPTOR_ERROR_NONE = 0,
+       SERVICE_ADAPTOR_ERROR_INTERNAL = -1,
+       SERVICE_ADAPTOR_ERROR_DBUS = -2,
+       SERVICE_ADAPTOR_ERROR_MAX
+} shop_adaptor_error_e;
+
+/**
+* @brief Describes infromation about Service Adaptor's error
+*/
+typedef struct shop_adaptor_error_code_s
+{
+       int64_t code;
+        char *msg;
+} shop_adaptor_error_code_t;
+typedef struct shop_adaptor_error_code_s *shop_adaptor_error_code_h;
+
+typedef struct shop_plugin_error_s
+{
+        char *code;
+        char *msg;
+} shop_plugin_error_t;
+
+typedef struct shop_adaptor_listener_s
+{
+} shop_adaptor_listener_t;
+typedef struct shop_adaptor_listener_s *shop_adaptor_listener_h;
+
+
+/**
+ * Shop adaptor listener for plugins (example)
+ * Listener is used by plugins
+ */
+typedef struct shop_adaptor_plugin_listener_s
+{
+} shop_adaptor_plugin_listener_t;
+typedef struct shop_adaptor_plugin_listener_s *shop_adaptor_plugin_listener_h;
+
+/**
+ * @ brief Shop adaptor plugin handle
+ */
+typedef struct shop_adaptor_plugin_handle_s
+{
+       // Mandatory functions to handle plugin in adaptor
+       //struct shop_adaptor_plugin_handle_s * (*create_plugin_handle)(void);
+
+       shop_error_code_t (*create_context)(shop_adaptor_plugin_context_h *context,
+                                               char *duid,
+                                               char *access_token,
+                                               char *app_id,
+                                               char *apptype);
+
+       shop_error_code_t (*destroy_context)(shop_adaptor_plugin_context_h context);
+
+       shop_error_code_t (*destroy_handle)(struct shop_adaptor_plugin_handle_s *handle);
+       shop_error_code_t (*set_listener)(shop_adaptor_plugin_listener_h listener);
+       shop_error_code_t (*unset_listener)(void);
+       // Mandatory end
+       // Optional
+       shop_error_code_t (*get_item_list_v1) (shop_adaptor_plugin_context_h handle,
+                                               shop_adaptor_shop_info_s *info,
+                                               void *user_data,
+                                               shop_adaptor_shop_item_s ***items,
+                                               unsigned int *items_len,
+                                               shop_adaptor_error_code_h *error_code,
+                                               void **server_data);
+
+       shop_error_code_t (*download_item_package_v1)(shop_adaptor_plugin_context_h handle,
+                                               shop_adaptor_shop_info_s *info,
+                                               void *user_data,
+                                               shop_adaptor_shop_item_s **item,
+                                               shop_adaptor_error_code_h *error_code,
+                                               void **server_data);
+
+       shop_error_code_t (*download_sticker_v1)(shop_adaptor_plugin_context_h handle,
+                                               shop_adaptor_shop_info_s *info,
+                                               void *user_data,
+                                               shop_adaptor_shop_item_s **item,
+                                               shop_adaptor_error_code_h *error_code,
+                                               void **server_data);
+
+       shop_error_code_t (*get_panel_url_v1)(shop_adaptor_plugin_context_h handle,
+                                               shop_adaptor_shop_info_s *info,
+                                               void *user_data,
+                                               shop_adaptor_shop_item_s **item,
+                                               shop_adaptor_error_code_h *error_code,
+                                               void **server_data);
+
+       shop_error_code_t (*set_server_info)(shop_adaptor_plugin_context_h handle,
+                                               GHashTable *server_info,
+                                               shop_adaptor_error_code_h *error_code);
+       // Optional end
+
+       // Mandatory
+       char *plugin_uri;               // get from config file
+       // Mandatory end
+
+} shop_adaptor_plugin_handle_t;
+typedef struct shop_adaptor_plugin_handle_s *shop_adaptor_plugin_handle_h;
+
+
+
+/**
+ * @ brief Loads plugin from selected path
+ */
+int shop_adaptor_load_plugin(shop_adaptor_h adaptor, const char *plugin_path);
+
+/**
+ * @ brief Unloads selected plugin
+ */
+int shop_adaptor_unload_plugin(shop_adaptor_h adaptor, shop_adaptor_plugin_h plugin);
+
+/**
+ * @ brief Refresh access token
+ */
+EXPORT_API
+shop_error_code_t shop_adaptor_refresh_access_token(shop_adaptor_plugin_context_h context,
+                                               const char *new_access_token);
+
+/**
+ * @ brief Refresh uid
+ */
+EXPORT_API
+shop_error_code_t shop_adaptor_refresh_uid(shop_adaptor_plugin_context_h context,
+                                               const char *new_uid);
+
+/**
+ * @ brief Create error code
+ */
+EXPORT_API
+shop_adaptor_error_code_h shop_adaptor_create_error_code(const int64_t code, const char *msg);
+
+/**
+ * @ brief Destroy error code
+ */
+EXPORT_API
+void shop_adaptor_destroy_error_code(shop_adaptor_error_code_h *error_code);
+
+/**
+ * @ brief Creates shop adaptor
+ */
+EXPORT_API
+shop_adaptor_h shop_adaptor_create(const char *plugins_dir);
+
+/**
+ * @ brief Destroys shop adaptor
+ * @ brief Destroys shop adaptor. If shop adaptor was started it is stopped first.
+ */
+EXPORT_API
+void shop_adaptor_destroy(shop_adaptor_h adaptor);
+
+/**
+ * @ brief Starts shop adaptor
+ * @ brief Starts shop adaptor and loads plugins that were found in plugins search dir
+ * @ brief specified in shop_adaptor_create
+ */
+EXPORT_API
+int shop_adaptor_start(shop_adaptor_h adaptor);
+
+/**
+ * @ brief Stops shop adaptor.
+ */
+EXPORT_API
+int shop_adaptor_stop(shop_adaptor_h adaptor);
+
+/**
+ * @ brief Registers plugin state listener
+ */
+EXPORT_API
+int shop_adaptor_register_listener(shop_adaptor_h adaptor, shop_adaptor_listener_h listener);
+
+/**
+ * @ brief Unregisters plugin state listener
+ */
+EXPORT_API
+int shop_adaptor_unregister_listener(shop_adaptor_h adaptor, shop_adaptor_listener_h listener);
+
+/**
+ * @ brief Creates plugin context.
+ */
+EXPORT_API
+shop_adaptor_plugin_context_h shop_adaptor_create_plugin_context(shop_adaptor_plugin_h plugin,
+                                               char *plugin_uri,
+                                               char *duid,
+                                               char *access_token,
+                                               char *app_id,
+                                               char *apptype);
+
+/**
+ * @ brief Destroys plugin context.
+ */
+EXPORT_API
+void shop_adaptor_destroy_plugin_context(shop_adaptor_plugin_h plugin, shop_adaptor_plugin_context_h plugin_context);
+
+/**
+ * @ brief Gets plugin with specified unique name
+ */
+EXPORT_API
+shop_adaptor_plugin_h shop_adaptor_get_plugin_by_name(shop_adaptor_h adaptor, const char *plugin_name);
+
+/**
+ * @brief Set server information for Shop Plugin
+ *
+ * @param[in]    plugin                specifies Shop Adaptor Plugin handle
+ * @param[in]    context       specifies Shop Adaptor Plugin Context handle
+ * @param[in]    server_info   specifies server information for Shop Plugin
+ * @param[out]   error         specifies error code
+* @return 0 on success, otherwise a positive error value
+ * @retval error code defined in shop_error_code_t - SHOP_ADAPTOR_ERROR_NONE if Successful
+ */
+EXPORT_API
+shop_error_code_t shop_adaptor_set_server_info(shop_adaptor_plugin_h plugin,
+                                               shop_adaptor_plugin_context_h context,
+                                               GHashTable *server_info,
+                                               shop_adaptor_error_code_h *error_code);
+
+////////////////////////////////////////////////////////////
+// Adaptor Plugin call Functions
+////////////////////////////////////////////////////////////
+
+/**
+* @brief Get List of Item
+*
+* @param[in]   plugin          specifies Shop-adaptor Plugin handle
+* @param[in]   context         specifies Shop-adaptor Plugin context
+* @param[in]   info                    specifies Properties of Items to be requested
+* @param[in]   user_data       specifies Additional Input(Recommend Json Object format, Optional value)
+* @param[out]items             specifies Item List(array)
+* @param[out]items_len         specifies The number of Item List
+* @param[out]  error_code      specifies Error code
+* @param[out]server_data       specifies Reply from Server(JSON format, Optional value)
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in shop_error_code_e - SHOP_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+shop_error_code_t shop_adaptor_get_item_list_v1 (shop_adaptor_plugin_h plugin,
+                                               shop_adaptor_plugin_context_h context,
+                                               shop_adaptor_shop_info_s *info,
+                                               void *user_data,
+                                               shop_adaptor_shop_item_s ***items,
+                                               unsigned int *items_len,
+                                               shop_adaptor_error_code_h *error_code,
+                                               void **server_data);
+
+/**
+* @brief Get Item information for Download
+*
+* @param[in]   plugin          specifies Shop-adaptor Plugin handle
+* @param[in]   context         specifies Shop-adaptor Plugin context
+* @param[in]   info                    specifies Properties of Items to be requested
+* @param[in]   user_data       specifies Additional Input(Recommend Json Object format, Optional value)
+* @param[out]item                      specifies Item List
+* @param[out]  error_code      specifies Error code
+* @param[out]server_data       specifies Reply from Server(JSON format, Optional value)
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in shop_error_code_e - SHOP_ADAPTOR_ERROR_NONE if Successful
+*/
+
+EXPORT_API
+shop_error_code_t shop_adaptor_download_item_package_v1(shop_adaptor_plugin_h plugin,
+                                               shop_adaptor_plugin_context_h context,
+                                               shop_adaptor_shop_info_s *info,
+                                               void *user_data,
+                                               shop_adaptor_shop_item_s **item,
+                                               shop_adaptor_error_code_h *error_code,
+                                               void **server_data);
+
+/**
+* @brief Get Sticker information for Download
+*
+* @param[in]   plugin          specifies Shop-adaptor Plugin handle
+* @param[in]   context         specifies Shop-adaptor Plugin context
+* @param[in]   info                    specifies Properties of Items to be requested
+* @param[in]   user_data       specifies Additional Input(Recommend Json Object format, Optional value)
+* @param[out]item                      specifies Item List
+* @param[out]  error_code      specifies Error code
+* @param[out]server_data       specifies Reply from Server(JSON format, Optional value)
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in shop_error_code_e - SHOP_ADAPTOR_ERROR_NONE if Successful
+*/
+
+EXPORT_API
+shop_error_code_t shop_adaptor_download_sticker_v1(shop_adaptor_plugin_h plugin,
+                                               shop_adaptor_plugin_context_h context,
+                                               shop_adaptor_shop_info_s *info,
+                                               void *user_data,
+                                               shop_adaptor_shop_item_s **item,
+                                               shop_adaptor_error_code_h *error_code,
+                                               void **server_data);
+
+/**
+* @brief Get Item Panel URL
+*
+* @param[in]   plugin          specifies Shop-adaptor Plugin handle
+* @param[in]   context         specifies Shop-adaptor Plugin context
+* @param[in]   info                    specifies Properties of Items to be requested
+* @param[in]   user_data       specifies Additional Input(Recommend Json Object format, Optional value)
+* @param[out]item                      specifies Item List
+* @param[out]  error_code      specifies Error code
+* @param[out]server_data       specifies Reply from Server(JSON format, Optional value)
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in shop_error_code_e - SHOP_ADAPTOR_ERROR_NONE if Successful
+*/
+
+EXPORT_API
+shop_error_code_t shop_adaptor_get_panel_url_v1(shop_adaptor_plugin_h plugin,
+                                               shop_adaptor_plugin_context_h context,
+                                               shop_adaptor_shop_info_s *info,
+                                               void *user_data,
+                                               shop_adaptor_shop_item_s **item,
+                                               shop_adaptor_error_code_h *error_code,
+                                               void **server_data);
+
+#endif /* __SHOP_ADAPTOR_H__ */
+
diff --git a/adaptor/storage-adaptor/storage-adaptor-log.h b/adaptor/storage-adaptor/storage-adaptor-log.h
new file mode 100644 (file)
index 0000000..5593807
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+* Copyright (c) 2011 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 __STORAGE_ADAPTOR_LOG_H__
+#define __STORAGE_ADAPTOR_LOG_H__
+
+/**
+ *  HOW TO USE IT:
+ *  First you need to set platform logging on the device:
+ *
+ *    # dlogctrl set platformlog 1
+ *
+ *  After reboot you are able to see logs from this application, when you launch dlogutil with a proper filter e.g.:
+ *
+ *    # dlogutil STORAGE_ADAPTOR:D
+ *
+ *  You may use different logging levels as: D (debug), I (info), W (warning), E (error) or F (fatal).
+ *  Higher level messages are included by default e.g. dlogutil CLOUDBOX:W prints warnings but also errors and fatal messages.
+ */
+
+#include <unistd.h>
+#include <linux/unistd.h>
+
+/* These defines must be located before #include <dlog.h> */
+#define TIZEN_ENGINEER_MODE
+// TODO: Investigate why this macro is defined somewhere else
+#ifndef TIZEN_DEBUG_ENABLE
+#define TIZEN_DEBUG_ENABLE
+#endif
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+/* Literal to filter logs from dlogutil */
+#define LOG_TAG "STORAGE_ADAPTOR"
+
+#include <dlog.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+       /**
+        *  Colors of font
+        */
+#define FONT_COLOR_RESET      "\033[0m"
+#define FONT_COLOR_BLACK      "\033[30m"             /* Black */
+#define FONT_COLOR_RED        "\033[31m"             /* Red */
+#define FONT_COLOR_GREEN      "\033[32m"             /* Green */
+#define FONT_COLOR_YELLOW     "\033[33m"             /* Yellow */
+#define FONT_COLOR_BLUE       "\033[34m"             /* Blue */
+#define FONT_COLOR_PURPLE     "\033[35m"             /* Purple */
+#define FONT_COLOR_CYAN       "\033[36m"             /* Cyan */
+#define FONT_COLOR_WHITE      "\033[37m"             /* White */
+#define FONT_COLOR_BOLDBLACK  "\033[1m\033[30m"      /* Bold Black */
+#define FONT_COLOR_BOLDRED    "\033[1m\033[31m"      /* Bold Red */
+#define FONT_COLOR_BOLDGREEN  "\033[1m\033[32m"      /* Bold Green */
+#define FONT_COLOR_BOLDYELLOW "\033[1m\033[33m"      /* Bold Yellow */
+#define FONT_COLOR_BOLDBLUE   "\033[1m\033[34m"      /* Bold Blue */
+#define FONT_COLOR_BOLDPURPLE "\033[1m\033[35m"      /* Bold Purple */
+#define FONT_COLOR_BOLDCYAN   "\033[1m\033[36m"      /* Bold Cyan */
+#define FONT_COLOR_BOLDWHITE  "\033[1m\033[37m"      /* Bold White */
+
+       /**
+        *  Gets thread ID
+        */
+#define storage_adaptor_gettid() syscall(__NR_gettid)
+
+/**
+ *  @brief Macro for returning value if expression is satisfied
+ *  @param[in]  expr Expression to be checked
+ *  @param[out] val  Value to be returned when expression is true
+ */
+#define storage_adaptor_retv_if(expr, val) do { \
+            if(expr) { \
+                LOGE(FONT_COLOR_PURPLE"[%d]"FONT_COLOR_RESET, storage_adaptor_gettid());    \
+                return (val); \
+            } \
+        } while (0)
+
+/**
+ * @brief Prints debug messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define storage_adaptor_debug(fmt, arg...) do { \
+            LOGD(FONT_COLOR_GREEN"[%d]"fmt""FONT_COLOR_RESET, storage_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints info messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define storage_adaptor_info(fmt, arg...) do { \
+            LOGI(FONT_COLOR_BLUE"[%d]"fmt""FONT_COLOR_RESET, storage_adaptor_gettid() ,##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints warning messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define storage_adaptor_warning(fmt, arg...) do { \
+            LOGW(FONT_COLOR_YELLOW"[%d]"fmt""FONT_COLOR_RESET,storage_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints error messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define storage_adaptor_error(fmt, arg...) do { \
+            LOGE(FONT_COLOR_RED"[%d]"fmt""FONT_COLOR_RESET,storage_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints fatal messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define storage_adaptor_fatal(fmt, arg...) do { \
+            LOGF(FONT_COLOR_BOLDRED"[%d]"fmt""FONT_COLOR_RESET,storage_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints debug message on entry to particular function
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define storage_adaptor_debug_func(fmt, arg...) do { \
+            LOGD(FONT_COLOR_CYAN"[%d]"fmt""FONT_COLOR_RESET, storage_adaptor_gettid(), ##arg);     \
+        } while (0)
+
+#define storage_adaptor_check_param_equal(compare, val, ret_val, exception_handling) {\
+       if ( compare == val ) {\
+               LOGD(FONT_COLOR_PURPLE "[%d]<Line :%d>" "Parameter Check catched (equal) \n : Expected(%p) Value(%p)" FONT_COLOR_RESET, storage_adaptor_gettid(), __LINE__, compare, val);\
+               exception_handling;\
+               return ret_val;\
+       }\
+}
+
+#define plugin_req_enter()                     do { \
+               storage_adaptor_info("[ENTER] plugin API call -)) -)) -)) -)) -)) -)) -)) -)) -)) -))"); \
+       } while (0)
+
+#define plugin_req_exit(ret, plugin, error)    do { \
+               storage_adaptor_info("[EXIT] plugin API called (%d) ((- ((- ((- ((- ((- ((- ((- ((- ((- ((-", (int)(ret)); \
+               if ((error)) { \
+                       if ((*error)) { \
+                               storage_adaptor_error("plugin issued error (%lld) (%s)", (long long int)((*error)->code), (char *)((*error)->msg)); \
+                               char *tem = g_strdup_printf("[PLUGIN_ERROR] URI(%s), MSG(%s)", (char *)((plugin)->handle->plugin_uri), (char *)((*error)->msg)); \
+                               if (tem) { \
+                                       free((*error)->msg); \
+                                       (*error)->msg = tem; \
+                               } \
+                       } \
+               } \
+       } while (0)
+
+#define plugin_req_exit_void()                 do { \
+               storage_adaptor_info("[EXIT] plugin API called ((- ((- ((- ((- ((- ((- ((- ((- ((- ((-"); \
+       } while (0)
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __STORAGE_ADAPTOR_LOG_H__ */
diff --git a/adaptor/storage-adaptor/storage-adaptor.c b/adaptor/storage-adaptor/storage-adaptor.c
new file mode 100644 (file)
index 0000000..c2f39ad
--- /dev/null
@@ -0,0 +1,7538 @@
+/*
+* Copyright (c) 2011 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.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <glib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <plugin_message.h>
+
+#include "storage-adaptor.h"
+#include "storage-adaptor-log.h"
+
+#define PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE           40960
+#define PLUGIN_MESSAGE_LISTENER_CMD_APPEND_FD          "append;"
+#define PLUGIN_MESSAGE_LISTENER_CMD_STOP               "stop;"
+
+#define STORAGE_PLUGIN_INTERFACE_CREATE_CONTEXT                "create_context"
+#define STORAGE_PLUGIN_INTERFACE_DESTROY_CONTEXT       "destroy_context"
+#define STORAGE_PLUGIN_INTERFACE_MAKE_DIRECTORY                "make_directory"
+#define STORAGE_PLUGIN_INTERFACE_GET_LIST              "get_list"
+#define STORAGE_PLUGIN_INTERFACE_REMOVE_DIRECTORY      "remove_directory"
+#define STORAGE_PLUGIN_INTERFACE_UPLOAD_FILE_SYNC      "upload_file_sync"
+#define STORAGE_PLUGIN_INTERFACE_DOWNLOAD_FILE_SYNC    "download_file_sync"
+#define STORAGE_PLUGIN_INTERFACE_DELETE_FILE           "delete_file"
+#define STORAGE_PLUGIN_INTERFACE_MOVE_DIRECTORY                "move_directory"
+#define STORAGE_PLUGIN_INTERFACE_MOVE_FILE             "move_file"
+#define STORAGE_PLUGIN_INTERFACE_SET_TRANSFER_STATE    "set_transfer_state"
+#define STORAGE_PLUGIN_INTERFACE_GET_TRANSFER_STATE    "get_transfer_state"
+#define STORAGE_PLUGIN_INTERFACE_GET_ROOT_FOLDER_PATH  "get_root_folder_path"
+
+/* for 2.4 public functions */
+#define STORAGE_PLUGIN_INTERFACE_START_UPLOAD_TASK     "start_upload_task"
+#define STORAGE_PLUGIN_INTERFACE_START_DOWNLOAD_TASK   "start_download_task"
+#define STORAGE_PLUGIN_INTERFACE_START_DOWNLOAD_THUMB_TASK     "start_download_thumb_task"
+#define STORAGE_PLUGIN_INTERFACE_CANCEL_UPLOAD_TASK    "cancel_upload_task"
+#define STORAGE_PLUGIN_INTERFACE_CANCEL_DOWNLOAD_TASK  "cancel_download_task"
+#define STORAGE_PLUGIN_INTERFACE_CANCEL_DOWNLOAD_THUMB_TASK    "cancel_download_thumb_task"
+
+#define STORAGE_PLUGIN_CALLBACK_DOWNLOAD_FILE_ASYNC_CB "download_async_cb"
+#define STORAGE_PLUGIN_CALLBACK_UPLOAD_FILE_ASYNC_CB   "upload_async_cb"
+#define STORAGE_PLUGIN_CALLBACK_PROGRESS_CB            "progress_cb"
+
+#define IF_IS_PLUGIN_THAN_RETURN_NULL()                do {if (!g_process_identity) return NULL; } while (0)
+#define SAFE_ADD_STRING(x)                     (x) ? (x) : ("")
+
+typedef enum {
+       PLUGIN_TYPE_INHOUSE     = 0,
+       PLUGIN_TYPE_3RD_PARTY   = 1,
+} storage_plugin_type_e;
+
+
+#ifndef FORK_PLUGIN_ARCHITECTURE
+GHashTable     *g_file_uid_list = NULL;
+#endif
+
+/**
+ * Storage adaptor plugin
+ */
+typedef struct storage_adaptor_plugin_s {
+       storage_adaptor_h                       adaptor;                /* Adaptor */
+       char                                    *path;                  /* Plugin library path */
+       storage_adaptor_plugin_handle_h         handle;                 /* Plugin handle */
+       void                                    *dl_handle;             /* Plugin library handle */
+       int                                     ref_counter;            /* Plugin reference counter */
+       GMutex                                  ref_counter_mutex;      /* Plugin reference counter mutex */
+       storage_adaptor_plugin_listener_h       plugin_listener;        /* Plugin callback listener */
+       GMutex                                  plugin_listener_mutex;  /* Plugin callback listener mutex */
+
+       GMutex                                  message_mutex;
+       storage_plugin_type_e                   type;
+       int                                     pid;
+       int                                     rd;
+       int                                     wd;
+       GList                                   *contexts;
+       GMutex                                  contexts_mutex;
+} storage_adaptor_plugin_t;
+
+/**
+ * Storage adaptor
+ */
+typedef struct storage_adaptor_s {
+       GMutex  storage_adaptor_mutex;          /* Adaptor mutex */
+       int     started;                        /* Started flag */
+       char    *plugins_dir;                   /* Plugins directory path */
+       GList   *plugins;                       /* List of loaded plugins */
+       GMutex  plugins_mutex;                  /* Plugin list mutex */
+       GList   *adaptor_listeners;             /* List of vservice channel listener (for now not effective) */
+       GMutex  adaptor_listeners_mutex;        /* Listener list mutex */
+
+       int     rd_cmd[2];
+       GList   *rd_list;
+       GMutex  rd_mutex;
+       pthread_t       plugin_listener;
+} storage_adaptor_t;
+
+static int g_process_identity = -1;
+
+static storage_adaptor_plugin_h g_child_plugin = NULL;
+
+/**
+ * Creates plugin
+ */
+static storage_adaptor_plugin_h storage_adaptor_create_plugin(const char *plugin_path);
+
+/**
+ * Destroys plugin and deletes all resources associated with it
+ */
+static void storage_adaptor_destroy_plugin(storage_adaptor_plugin_h plugin);
+
+/**
+ * Loads plugins from selected directory
+ */
+static int storage_adaptor_load_plugins_from_directory(storage_adaptor_h adaptor,
+                                               const char *dir_path);
+
+/**
+ * Checks if plugin is loaded by selected plugin adaptor
+ */
+static int storage_adaptor_has_plugin(storage_adaptor_h adaptor,
+                                               storage_adaptor_plugin_h plugin);
+
+/*     TDB Temp */
+
+#define GET_PLUGIN_PID() getpid()
+
+int _get_plugin_fd_from_file_uid(long long int file_uid)
+{
+       return ((int) (0xffff & file_uid));
+}
+
+long long int _get_file_uid_from_plugin_fd(int plugin_fd)
+{
+       long long int plugin_section = 0LL;
+       #ifdef FORK_PLUGIN_ARCHITECTURE
+               /* TODO it must be changed to another index (not support 64bit) */
+               plugin_section = ((long long int) GET_PLUGIN_PID()) << (sizeof(int)*8);
+       #endif
+
+       return (plugin_section | (long long int)plugin_fd);
+}
+
+/**
+ * Increases adaptor's plugin references counter
+ */
+void storage_adaptor_plugin_ref(storage_adaptor_plugin_h);
+
+/**
+ * Decreases adaptor's plugin references counter
+ */
+void storage_adaptor_plugin_unref(storage_adaptor_plugin_h);
+
+
+/* ///////////////////////////////////////////////////////////////////////////////
+   /////////////  Internal function prototype (for forked plugin)  ///////////////
+   /////////////////////////////////////////////////////////////////////////////// */
+
+
+/* To be used by adaptor */
+void *_storage_adaptor_plugin_message_collector(void *data);
+void __storage_adaptor_transfer_message(const char *msg);
+int __storage_adaptor_parse_message_cmd(storage_adaptor_h adaptor, char *msg);
+void _storage_adaptor_send_cmd_add_fd(storage_adaptor_h adaptor, int fd);
+void _storage_adaptor_send_cmd_stop_listen(storage_adaptor_h adaptor);
+
+static int storage_adaptor_send_message_to_plugin_sync(storage_adaptor_plugin_h plugin,
+                                               plugin_message_h send_message,
+                                               plugin_message_h *receive_message);
+
+/* To be used by adaptor (virtual plugin handle) */
+storage_adaptor_plugin_handle_h __storage_adaptor_create_3rd_party_plugin_handle(const char *plugin_uri);
+
+storage_error_code_t storage_plugin_send_create_context(storage_adaptor_plugin_context_h *context,
+                                                       const char *app_id,
+                                                       const char *app_secret,
+                                                       const char *access_token,
+                                                       const char *cid,
+                                                       const char *uid);
+
+storage_error_code_t storage_plugin_send_destroy_context(storage_adaptor_plugin_context_h context);
+
+storage_error_code_t storage_plugin_send_set_server_info(storage_adaptor_plugin_context_h context,
+                                                       GHashTable *server_info,
+                                                       void *request,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+storage_error_code_t storage_plugin_send_make_directory(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *folder_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+storage_error_code_t storage_plugin_send_remove_directory(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *folder_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+storage_error_code_t storage_plugin_send_get_list(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *folder_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h **file_info_list,
+                                                       int *file_info_list_len,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+storage_error_code_t storage_plugin_send_upload_file_sync(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       const char *upload_file_local_path,
+                                                       const int publish,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+storage_error_code_t storage_plugin_send_download_file_sync(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       const char *download_file_local_path,
+                                                       void *request,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+storage_error_code_t storage_plugin_send_delete_file(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+storage_error_code_t storage_plugin_send_move_directory(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *folder_name,
+                                                       const char *dest_parent_folder_storage_path,
+                                                       const char *new_folder_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+storage_error_code_t storage_plugin_send_move_file(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       const char *dest_parent_folder_storage_path,
+                                                       const char *new_file_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+storage_error_code_t storage_plugin_send_set_transfer_state(storage_adaptor_plugin_context_h context,
+                                                       void *transfer_request_id,
+                                                       storage_adaptor_transfer_state_e state,
+                                                       void *request,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+storage_error_code_t storage_plugin_send_get_transfer_state(storage_adaptor_plugin_context_h context,
+                                                       void *transfer_request_id,
+                                                       void *request,
+                                                       storage_adaptor_transfer_state_e *state,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+storage_error_code_t storage_plugin_send_get_root_folder_path(storage_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       char **root_folder_path,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+storage_error_code_t storage_plugin_send_start_upload_task(storage_adaptor_plugin_context_h context,
+                                                       int fd,
+                                                       const char *upload_dir,
+                                                       const char *file_path,
+                                                       bool need_progress,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *user_data);
+
+storage_error_code_t storage_plugin_send_start_download_task(storage_adaptor_plugin_context_h context,
+                                                       const char *storage_dir,
+                                                       const char *file_path,
+                                                       int fd,
+                                                       bool need_progress,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *user_data);
+
+storage_error_code_t storage_plugin_send_start_download_thumb_task(storage_adaptor_plugin_context_h context,
+                                                       const char *storage_dir,
+                                                       const char *file_path,
+                                                       int fd,
+                                                       int thumbnail_size,
+                                                       bool need_progress,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *user_data);
+
+storage_error_code_t storage_plugin_send_cancel_upload_task(storage_adaptor_plugin_context_h context,
+                                                       int fd,
+                                                       storage_adaptor_error_code_h *error);
+
+storage_error_code_t storage_plugin_send_cancel_download_task(storage_adaptor_plugin_context_h context,
+                                                       int fd,
+                                                       storage_adaptor_error_code_h *error);
+
+storage_error_code_t storage_plugin_send_cancel_download_thumb_task(storage_adaptor_plugin_context_h context,
+                                                       int fd,
+                                                       storage_adaptor_error_code_h *error);
+
+/* To be used by forked plugin */
+void *_storage_plugin_request_collector(void *data);
+storage_adaptor_plugin_context_h __storage_plugin_get_context_by_context_id(storage_adaptor_plugin_h plugin, int context_id);
+void __storage_plugin_progress_command(storage_adaptor_plugin_h plugin, char *order, char **result);
+
+
+storage_adaptor_file_info_h _get_file_info_from_message_array(plugin_message_array_h message_array, int index);
+
+int _message_array_set_file_info(plugin_message_array_h message_array, int index, storage_adaptor_file_info_h file_info);
+
+/**
+ * Definition of callback function variables for vservice channel (= infra adaptor) (example)
+ */
+/* private feature */
+storage_adaptor_service_download_file_async_reply_cb   _service_adaptor_download_file_async_reply      = NULL;
+storage_adaptor_service_upload_file_async_reply_cb     _service_adaptor_upload_file_async_reply        = NULL;
+storage_adaptor_service_file_transfer_progress_reply_cb        _service_adaptor_file_transfer_progress_reply   = NULL;
+
+/* public feature */
+storage_adaptor_service_download_state_changed_reply_cb        _service_adaptor_download_state_changed_reply   = NULL;
+storage_adaptor_service_upload_state_changed_reply_cb  _service_adaptor_upload_state_changed_reply     = NULL;
+storage_adaptor_service_task_progress_reply_cb _service_adaptor_task_progress_reply    = NULL;
+
+/**
+ * Gets a message from plugin (callback) when a sms message is received (sample)
+ */
+/* private feature */
+void storage_adaptor_download_file_async_reply_cb(void *request_id,
+                                               char *download_file_local_path,
+                                               storage_adaptor_error_code_h error,
+                                               void *response)
+{
+       if (NULL != _service_adaptor_download_file_async_reply) {
+               _service_adaptor_download_file_async_reply(request_id,
+                               download_file_local_path, error, response);
+       }
+}
+
+void storage_adaptor_upload_file_async_reply_cb(void *request_id,
+                                               storage_adaptor_file_info_h file_info,
+                                               storage_adaptor_error_code_h error,
+                                               void *response)
+{
+       if (NULL != _service_adaptor_upload_file_async_reply) {
+               _service_adaptor_upload_file_async_reply(request_id,
+                               file_info, error, response);
+       }
+}
+
+void storage_adaptor_file_transfer_progress_reply_cb(void *request_id,
+                                               unsigned long long progress_size_byte,
+                                               unsigned long long total_size_byte,
+                                               storage_adaptor_error_code_h error,
+                                               void *response)
+{
+       if (NULL != _service_adaptor_file_transfer_progress_reply) {
+               _service_adaptor_file_transfer_progress_reply(request_id,
+                               progress_size_byte, total_size_byte, error, response);
+       }
+}
+
+/* public feature */
+void storage_adaptor_download_state_changed_reply_cb(int file_descriptor,
+                                               storage_adaptor_transfer_state_e state,
+                                               storage_adaptor_error_code_h error,
+                                               void *user_data)
+{
+       if ((state == STORAGE_ADAPTOR_TRANSFER_STATE_FINISHED)
+                       || (state == STORAGE_ADAPTOR_TRANSFER_STATE_CANCELED)
+                       || (state == STORAGE_ADAPTOR_TRANSFER_STATE_FAILED)) {
+               close(file_descriptor);
+       }
+
+       if (NULL != _service_adaptor_download_state_changed_reply) {
+               long long int file_uid = _get_file_uid_from_plugin_fd(file_descriptor);
+               _service_adaptor_download_state_changed_reply(file_uid,
+                               state, error, user_data);
+       }
+}
+
+void storage_adaptor_upload_state_changed_reply_cb(int file_descriptor,
+                                               storage_adaptor_transfer_state_e state,
+                                               storage_adaptor_file_info_h file_info,
+                                               storage_adaptor_error_code_h error,
+                                               void *user_data)
+{
+       if ((state == STORAGE_ADAPTOR_TRANSFER_STATE_FINISHED)
+                       || (state == STORAGE_ADAPTOR_TRANSFER_STATE_CANCELED)
+                       || (state == STORAGE_ADAPTOR_TRANSFER_STATE_FAILED)) {
+               close(file_descriptor);
+       }
+
+       if (NULL != _service_adaptor_upload_state_changed_reply) {
+               long long int file_uid = _get_file_uid_from_plugin_fd(file_descriptor);
+               _service_adaptor_upload_state_changed_reply(file_uid,
+                               state, file_info, error, user_data);
+       }
+}
+
+void storage_adaptor_task_progress_reply_cb(int file_descriptor,
+                                               unsigned long long progress_size_byte,
+                                               unsigned long long total_size_byte,
+                                               storage_adaptor_error_code_h error,
+                                               void *user_data)
+{
+       if (NULL != _service_adaptor_task_progress_reply) {
+               long long int file_uid = _get_file_uid_from_plugin_fd(file_descriptor);
+               _service_adaptor_task_progress_reply(file_uid,
+                               progress_size_byte, total_size_byte);
+       }
+}
+
+/* //------------------------------------------------------------------------
+   // Functions implementations
+   //------------------------------------------------------------------------ */
+
+/* //////////////////////////////////////////////////////////
+   // Adaptor Defined Plugin Function
+   ////////////////////////////////////////////////////////// */
+
+storage_error_code_t storage_plugin_open_file(storage_adaptor_plugin_context_h context,
+                                               const char *file_path,
+                                               storage_adaptor_file_access_mode_e mode,
+                                               int *file_descriptor,
+                                               storage_adaptor_error_code_h *error)
+{
+       storage_error_code_t ret = STORAGE_ADAPTOR_ERROR_NONE;
+
+       if ((NULL == file_descriptor) || (NULL == file_path)) {
+               if (NULL != error) {
+                       *error = storage_adaptor_create_error_code((int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                       "Invalid parameter");
+               }
+               ret = STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       } else {
+               int fd;
+               if (STORAGE_ADAPTOR_FILE_ACCESS_READ == mode) {
+                       fd = open(file_path, mode);
+               } else if (STORAGE_ADAPTOR_FILE_ACCESS_WRITE == mode) {
+                       fd = open(file_path, mode, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+               } else {
+                       if (NULL != error) {
+                               *error = storage_adaptor_create_error_code((int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                                               "Invalid parameter (file mode)");
+                       }
+                       ret = STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+                       return ret;
+               }
+
+               if (fd < 0) {
+                       ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+                       int64_t error_code;
+                       if (EEXIST == errno) {
+                               error_code = (int64_t) STORAGE_PLUGIN_ERROR_FILE_AREADY_EXIST;
+                       } else if (EACCES == errno) {
+                               error_code = (int64_t) STORAGE_PLUGIN_ERROR_FILE_ACCESS_DENIED;
+                       } else {
+                               error_code = (int64_t) STORAGE_PLUGIN_ERROR_FILE_OPEN_FAILED;
+                       }
+                       if (NULL != error) {
+                               *error = storage_adaptor_create_error_code(error_code,
+                                               "File open failed");
+                       }
+               } else {
+                       *file_descriptor = fd;
+               }
+       }
+       return ret;
+}
+
+storage_error_code_t storage_plugin_close_file(storage_adaptor_plugin_context_h context,
+                                               int file_descriptor,
+                                               storage_adaptor_error_code_h *error)
+{
+       storage_error_code_t ret = STORAGE_ADAPTOR_ERROR_NONE;
+
+       int r = close(file_descriptor);
+       if (r) {
+               storage_adaptor_debug("close ret : %d", r);
+       }
+
+       return ret;
+}
+
+
+/* //////////////////////////////////////////////////////
+   // Mandatory: External adaptor management function
+   ////////////////////////////////////////////////////// */
+storage_adaptor_h storage_adaptor_create(const char *plugins_dir)
+{
+       if (NULL == plugins_dir) {
+               storage_adaptor_error("Invalid argument""(plugins_dir: %p", plugins_dir);
+               return NULL;
+       }
+
+       storage_adaptor_h storage_adaptor = (storage_adaptor_h) malloc(sizeof(storage_adaptor_t));
+
+       if (NULL == storage_adaptor) {
+               storage_adaptor_error("Critical : Memory allocation failed");
+               return NULL;
+       }
+
+       /* for forked plugin */
+       if (pipe(storage_adaptor->rd_cmd) == -1) {
+               free(storage_adaptor);
+               return NULL;
+       }
+       g_mutex_init(&storage_adaptor->rd_mutex);
+       storage_adaptor->rd_list = NULL;
+
+       storage_adaptor->started = 0;
+       storage_adaptor->plugins_dir = strdup(plugins_dir);
+
+       g_mutex_init(&storage_adaptor->storage_adaptor_mutex);
+       g_mutex_init(&storage_adaptor->plugins_mutex);
+       g_mutex_init(&storage_adaptor->adaptor_listeners_mutex);
+
+       g_mutex_lock(&storage_adaptor->adaptor_listeners_mutex);
+       storage_adaptor->adaptor_listeners = NULL;
+       g_mutex_unlock(&storage_adaptor->adaptor_listeners_mutex);
+
+       g_mutex_lock(&storage_adaptor->plugins_mutex);
+       storage_adaptor->plugins = NULL;
+       g_mutex_unlock(&storage_adaptor->plugins_mutex);
+
+       #ifndef FORK_PLUGIN_ARCHITECTURE
+               g_file_uid_list = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, free);
+       #endif
+
+       return storage_adaptor;
+}
+
+void storage_adaptor_destroy(storage_adaptor_h adaptor)
+{
+       if (NULL == adaptor) {
+               storage_adaptor_error("Invalid argument""(adaptor: %p)", adaptor);
+               return ;
+       }
+
+       g_mutex_lock(&adaptor->storage_adaptor_mutex);
+       if (0 != adaptor->started) {
+               storage_adaptor_error("Storage adaptor is running. Forcing stop before destroy");
+               storage_adaptor_stop(adaptor);
+       }
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       if (NULL != adaptor->plugins) {
+               g_list_free_full(adaptor->plugins, (GDestroyNotify) storage_adaptor_plugin_unref);
+               adaptor->plugins = NULL;
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+       if (NULL != adaptor->adaptor_listeners) {
+               g_list_free(adaptor->adaptor_listeners);
+               adaptor->adaptor_listeners = NULL;
+       }
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+
+       _service_adaptor_download_file_async_reply      = NULL;
+       _service_adaptor_upload_file_async_reply        = NULL;
+       _service_adaptor_file_transfer_progress_reply   = NULL;
+       _service_adaptor_download_state_changed_reply   = NULL;
+       _service_adaptor_upload_state_changed_reply     = NULL;
+       _service_adaptor_task_progress_reply    = NULL;
+
+       free(adaptor->plugins_dir);
+       adaptor->plugins_dir = NULL;
+
+       g_mutex_unlock(&adaptor->storage_adaptor_mutex);
+
+       #ifndef FORK_PLUGIN_ARCHITECTURE
+               g_hash_table_destroy(g_file_uid_list);
+       #endif
+
+       /* For forked plugin */
+       g_list_free(adaptor->rd_list);
+       close(adaptor->rd_cmd[0]);
+       close(adaptor->rd_cmd[1]);
+
+       free(adaptor);
+}
+
+int storage_adaptor_start(storage_adaptor_h adaptor)
+{
+       storage_adaptor_debug("Starting storage adaptor");
+       if (NULL == adaptor) {
+               storage_adaptor_error("Invalid argument""(adaptor: %p)", adaptor);
+               return STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->storage_adaptor_mutex);
+       int result = STORAGE_ADAPTOR_ERROR_NONE;
+       if (0 != adaptor->started) {
+               storage_adaptor_error("Storage adaptor is already started");
+               result = STORAGE_ADAPTOR_ERROR_START;
+       } else {
+               adaptor->started = 1;
+
+               pthread_t pid;
+               if (pthread_create(&pid, NULL, _storage_adaptor_plugin_message_collector, (void *)adaptor)) {
+                       adaptor->started = 0;
+                       storage_adaptor_error("Could not create 3rd party plugin listener");
+                       result = STORAGE_ADAPTOR_ERROR_NOT_FOUND;
+               } else if (STORAGE_ADAPTOR_ERROR_NONE != (result = storage_adaptor_load_plugins_from_directory(adaptor, adaptor->plugins_dir))) {
+                       _storage_adaptor_send_cmd_stop_listen(adaptor);
+                       adaptor->started = 0;
+                       storage_adaptor_error("Could not load plugins from directory");
+                       result = STORAGE_ADAPTOR_ERROR_NOT_FOUND;
+               } else {
+                       adaptor->plugin_listener = pid;
+                       storage_adaptor_info("Storage adaptor started successfully");
+               }
+       }
+       g_mutex_unlock(&adaptor->storage_adaptor_mutex);
+
+       return result;
+}
+
+int storage_adaptor_stop(storage_adaptor_h adaptor)
+{
+       if (NULL == adaptor) {
+               storage_adaptor_error("Invalid argument""(adaptor: %p)", adaptor);
+               return STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->storage_adaptor_mutex);
+
+       /* For forked plugin */
+       storage_adaptor_debug("stop plugin listener");
+       _storage_adaptor_send_cmd_stop_listen(adaptor);
+       pthread_join(adaptor->plugin_listener, NULL);
+
+       int result = STORAGE_ADAPTOR_ERROR_NONE;
+       if (0 == adaptor->started) {
+               result = STORAGE_ADAPTOR_ERROR_START;
+       } else {
+               if (NULL != adaptor->plugins) {
+                       g_mutex_lock(&adaptor->plugins_mutex);
+                       g_list_free_full(adaptor->plugins, (GDestroyNotify) storage_adaptor_plugin_unref);
+                       adaptor->plugins = NULL;
+                       g_mutex_unlock(&adaptor->plugins_mutex);
+               }
+               adaptor->started = 0;
+               storage_adaptor_debug("Storage adaptor stopped");
+       }
+
+       g_mutex_unlock(&adaptor->storage_adaptor_mutex);
+       return result;
+}
+
+int storage_adaptor_register_listener(storage_adaptor_h adaptor,
+                                               storage_adaptor_listener_h listener)
+{
+       if ((NULL == adaptor) || (NULL == listener)) {
+               storage_adaptor_error("Invalid argument""(adaptor: %p, listener: %p)", adaptor, listener);
+               return STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+
+       adaptor->adaptor_listeners = g_list_append(adaptor->adaptor_listeners, listener);
+
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+
+       _service_adaptor_download_file_async_reply =
+                       (storage_adaptor_service_download_file_async_reply_cb) listener->download_file_async_reply;
+       _service_adaptor_upload_file_async_reply =
+                       (storage_adaptor_service_upload_file_async_reply_cb) listener->upload_file_async_reply;
+       _service_adaptor_file_transfer_progress_reply =
+                       (storage_adaptor_service_file_transfer_progress_reply_cb) listener->file_transfer_progress_reply;
+       _service_adaptor_download_state_changed_reply =
+                       (storage_adaptor_service_download_state_changed_reply_cb) listener->download_state_changed_reply;
+       _service_adaptor_upload_state_changed_reply =
+                       (storage_adaptor_service_upload_state_changed_reply_cb) listener->upload_state_changed_reply;
+       _service_adaptor_task_progress_reply =
+                       (storage_adaptor_service_task_progress_reply_cb) listener->task_progress_reply;
+
+       return STORAGE_ADAPTOR_ERROR_NONE;
+}
+
+int storage_adaptor_unregister_listener(storage_adaptor_h adaptor,
+                                               storage_adaptor_listener_h listener)
+{
+       if ((NULL == adaptor) || (NULL == listener)) {
+               storage_adaptor_error("Invalid argument""(adaptor: %p, listener: %p)", adaptor, listener);
+               return STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+
+       if (NULL == g_list_find(adaptor->adaptor_listeners, listener)) {
+               g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+               storage_adaptor_error("Could not find listener");
+               return STORAGE_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       adaptor->adaptor_listeners = g_list_remove(adaptor->adaptor_listeners, listener);
+
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+
+       _service_adaptor_download_file_async_reply      = NULL;
+       _service_adaptor_upload_file_async_reply        = NULL;
+       _service_adaptor_file_transfer_progress_reply   = NULL;
+       _service_adaptor_download_state_changed_reply   = NULL;
+       _service_adaptor_upload_state_changed_reply     = NULL;
+       _service_adaptor_task_progress_reply    = NULL;
+
+       return STORAGE_ADAPTOR_ERROR_NONE;
+}
+
+/* /////////////////////////////////////////////////////////////
+   // Plugin create / destroy / ref. count / get plugin name
+   ///////////////////////////////////////////////////////////// */
+static storage_adaptor_plugin_h storage_adaptor_create_plugin(const char *plugin_path)
+{
+       if (NULL == plugin_path) {
+               storage_adaptor_error("Invalid argument (plugin_path is null)");
+               return NULL;
+       }
+
+       void *dl_handle = dlopen(plugin_path, RTLD_LAZY);
+       if (NULL == dl_handle) {
+               storage_adaptor_error("Could not load plugin %s: %s", plugin_path, dlerror());
+               return NULL;
+       }
+
+       storage_adaptor_plugin_handle_h (*get_adaptee_handle)(void) = NULL;
+
+       get_adaptee_handle = (storage_adaptor_plugin_handle_h (*)(void)) (dlsym(dl_handle, "create_plugin_handle"));
+       if (NULL == get_adaptee_handle) {
+               dlclose(dl_handle);
+               storage_adaptor_error("Could not get function pointer to create_plugin_handle");
+               return NULL;
+       }
+
+       plugin_req_enter();
+       storage_adaptor_plugin_handle_h handle = get_adaptee_handle();
+       plugin_req_exit_void();
+
+       if (NULL == handle) {
+               dlclose(dl_handle);
+               storage_adaptor_error("Could not get adaptee handle");
+               return NULL;
+       }
+       /* TBD not fixed */
+       handle->open_file = storage_plugin_open_file;
+       handle->close_file = storage_plugin_close_file;
+
+       storage_adaptor_plugin_h plugin = (storage_adaptor_plugin_h) calloc(1, sizeof(storage_adaptor_plugin_t));
+       if (NULL == plugin) {
+               dlclose(dl_handle);
+               storage_adaptor_error("Could not create plugin object");
+               return NULL;
+       }
+
+       storage_adaptor_plugin_listener_h listener =
+                       (storage_adaptor_plugin_listener_h) calloc(1, sizeof(storage_adaptor_plugin_listener_t));
+
+       if (NULL == listener) {
+               free(plugin);
+               dlclose(dl_handle);
+               storage_adaptor_error("Could not create listener object");
+               return NULL;
+       }
+
+       plugin->path = g_strdup(plugin_path);
+       plugin->handle = handle;
+       plugin->dl_handle = dl_handle;
+       plugin->ref_counter = 0;
+
+       plugin->type = PLUGIN_TYPE_INHOUSE;
+
+       g_mutex_init(&plugin->ref_counter_mutex);
+       g_mutex_init(&plugin->plugin_listener_mutex);
+       g_mutex_init(&plugin->contexts_mutex);
+       plugin->contexts = NULL;
+
+       listener->storage_adaptor_download_file_async_reply     = storage_adaptor_download_file_async_reply_cb;
+       listener->storage_adaptor_upload_file_async_reply       = storage_adaptor_upload_file_async_reply_cb;
+       listener->storage_adaptor_file_transfer_progress_reply  = storage_adaptor_file_transfer_progress_reply_cb;
+       listener->storage_adaptor_download_state_changed_reply  = storage_adaptor_download_state_changed_reply_cb;
+       listener->storage_adaptor_upload_state_changed_reply    = storage_adaptor_upload_state_changed_reply_cb;
+       listener->storage_adaptor_task_progress_reply   = storage_adaptor_task_progress_reply_cb;
+
+
+       plugin_req_enter();
+       plugin->handle->set_listener(listener);
+       plugin_req_exit_void();
+
+       g_mutex_lock(&plugin->plugin_listener_mutex);
+       plugin->plugin_listener = listener;
+       g_mutex_unlock(&plugin->plugin_listener_mutex);
+
+       return plugin;
+}
+
+static void storage_adaptor_destroy_plugin(storage_adaptor_plugin_h plugin)
+{
+       if (NULL == plugin) {
+               storage_adaptor_error("Invalid argument""(plugin: %p)", plugin);
+               return;
+       }
+
+       if (NULL != plugin->handle) {
+               plugin->handle->destroy_handle(plugin->handle);
+
+               g_mutex_lock(&plugin->plugin_listener_mutex);
+
+               plugin_req_enter();
+               plugin->handle->unset_listener();
+               plugin_req_exit_void();
+
+               g_mutex_unlock(&plugin->plugin_listener_mutex);
+
+               plugin->handle = NULL;
+       }
+
+       if (NULL != plugin->dl_handle) {
+               dlclose(plugin->dl_handle);
+               plugin->dl_handle = NULL;
+       }
+
+       free(plugin->path);
+       plugin->path = NULL;
+
+       free(plugin);
+}
+
+static int storage_adaptor_load_plugins_from_directory(storage_adaptor_h adaptor,
+                                               const char *dir_path)
+{
+       char *plugin_path = NULL;
+       DIR *dir = NULL;
+       struct dirent dir_entry, *result = NULL;
+
+       storage_adaptor_debug("Starting load plugins from directory");
+
+       if ((NULL == adaptor) || (NULL == dir_path)) {
+               storage_adaptor_error("Invalid argument""(adaptor: %p, dir_path: %p)", adaptor, dir_path);
+               return STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       dir = opendir(dir_path);
+       if (NULL == dir) {
+               storage_adaptor_error("Could not open dir path (%s)", dir_path);
+               return STORAGE_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       int ret = STORAGE_ADAPTOR_ERROR_NONE;
+       while (0 == (readdir_r(dir, &dir_entry, &result))) {
+
+               if (NULL == result) {
+                       storage_adaptor_error("Could not open directory %s", plugin_path);
+                       break;
+               }
+
+               if (dir_entry.d_type & DT_DIR) {
+                       continue;
+               }
+
+               plugin_path = g_strconcat(dir_path, "/", dir_entry.d_name, NULL);
+               storage_adaptor_plugin_h plugin = storage_adaptor_create_plugin(plugin_path);
+
+               if (NULL != plugin) {
+                       storage_adaptor_debug("Loaded plugin: %s", plugin_path);
+                       plugin->adaptor = adaptor;
+                       storage_adaptor_plugin_ref(plugin);
+                       g_mutex_lock(&adaptor->plugins_mutex);
+                       adaptor->plugins = g_list_append(adaptor->plugins, plugin);
+                       g_mutex_unlock(&adaptor->plugins_mutex);
+               } else {
+                       storage_adaptor_error("Could not load plugin %s", plugin_path);
+               }
+
+               g_free(plugin_path);
+               plugin_path = NULL;
+       }
+
+       storage_adaptor_debug("End load plugins from directory");
+       closedir(dir);
+       return ret;
+}
+
+static int storage_adaptor_has_plugin(storage_adaptor_h adaptor,
+                                               storage_adaptor_plugin_h plugin)
+{
+       if ((NULL == adaptor) || (NULL == plugin)) {
+               storage_adaptor_error("Invalid argument""(adaptor: %p, plugin: %p)", adaptor, plugin);
+               return 0;
+       }
+
+       int result = 0;
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       if (NULL != g_list_find(adaptor->plugins, plugin)) {
+               result = 1;
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return result;
+}
+
+void storage_adaptor_plugin_ref(storage_adaptor_plugin_h plugin)
+{
+       if (NULL == plugin) {
+               storage_adaptor_error("Invalid argument""(plugin: %p)", plugin);
+               return;
+       }
+
+       g_mutex_lock(&plugin->ref_counter_mutex);
+       plugin->ref_counter = plugin->ref_counter + 1;
+       if (NULL != plugin->handle) {
+               storage_adaptor_info("plugin name : %s, ref_counter: %d",
+                               plugin->handle->plugin_uri, plugin->ref_counter);
+       } else {
+               storage_adaptor_info("ref_counter: %d", plugin->ref_counter);
+       }
+       g_mutex_unlock(&plugin->ref_counter_mutex);
+}
+
+void storage_adaptor_plugin_unref(storage_adaptor_plugin_h plugin)
+{
+       if (NULL == plugin) {
+               storage_adaptor_error("Invalid argument""(plugin: %p)", plugin);
+               return ;
+       }
+
+       int should_destroy = 0;
+
+       g_mutex_lock(&plugin->ref_counter_mutex);
+       plugin->ref_counter = plugin->ref_counter - 1;
+       if (NULL != plugin->handle) {
+               storage_adaptor_info("plugin name : %s, ref_counter: %d",
+                               plugin->handle->plugin_uri, plugin->ref_counter);
+       } else {
+               storage_adaptor_info("ref_counter: %d", plugin->ref_counter);
+       }
+       if (0 >= plugin->ref_counter) {
+               should_destroy = 1;
+       }
+       g_mutex_unlock(&plugin->ref_counter_mutex);
+
+       if (should_destroy) {
+               storage_adaptor_debug("Plugin is being destroyed");
+               storage_adaptor_destroy_plugin(plugin);
+       }
+}
+
+/* For 3rd party plugin packages */
+int storage_adaptor_load_plugin_from_package(storage_adaptor_h adaptor,
+                                               const char *package_id,
+                                               const char *plugin_path)
+{
+       int adaptor_fd[2];
+       int plugin_fd[2];
+
+       if (pipe(adaptor_fd) == -1) {
+               storage_adaptor_debug("pipe creation error, can not load plugin package");
+       } else if (pipe(plugin_fd) == -1) {
+               close(adaptor_fd[0]);
+               close(adaptor_fd[1]);
+               storage_adaptor_debug("pipe creation error[2], can not load plugin package");
+       } else {
+               g_process_identity = fork();
+               if (0 == g_process_identity) {  /* child */
+                       storage_adaptor_debug_func("[CHILD PROCESS] forked success (PID : %d, id : %d)", (int)getpid());
+
+                       storage_adaptor_plugin_h plugin = NULL;
+                       plugin = storage_adaptor_create_plugin(plugin_path);
+                       if (NULL == plugin) {
+                               storage_adaptor_error("[CHILD PROCESS] Load plugin failed");
+                               exit(1);
+                       }
+                       g_child_plugin = plugin;
+                       plugin->rd = plugin_fd[0];
+                       close(plugin_fd[1]);
+                       plugin->wd = adaptor_fd[1];
+                       close(adaptor_fd[0]);
+                       void *temp = _storage_plugin_request_collector((void *)plugin);
+                       storage_adaptor_debug_func("[CHILD PROCESS] exit %p", temp);
+                       exit(0);
+               } else if (0 < g_process_identity) {    /* parent */
+                       storage_adaptor_debug_func("[PARENT PROCESS] forked success (PID : %d)", (int)getpid());
+                       storage_adaptor_plugin_h _plugin = (storage_adaptor_plugin_h) calloc(1, sizeof(storage_adaptor_plugin_t));
+                       if (NULL == _plugin) {
+                               storage_adaptor_error("[PARENT PROCESS] memory allocation failed");
+                               exit(1);
+                       }
+
+                       _plugin->ref_counter = 0;
+                       g_mutex_init(&_plugin->ref_counter_mutex);
+                       g_mutex_init(&_plugin->message_mutex);
+
+                       _plugin->handle = __storage_adaptor_create_3rd_party_plugin_handle(package_id);
+
+                       _plugin->type = PLUGIN_TYPE_3RD_PARTY;
+                       _plugin->pid = g_process_identity;
+                       _plugin->rd = adaptor_fd[0];
+                       close(adaptor_fd[1]);
+                       _plugin->wd = plugin_fd[1];
+                       close(plugin_fd[0]);
+
+                       _storage_adaptor_send_cmd_add_fd(adaptor, _plugin->rd);
+
+                       _plugin->adaptor = adaptor;
+                       storage_adaptor_plugin_ref(_plugin);
+                       g_mutex_lock(&adaptor->plugins_mutex);
+                       adaptor->plugins = g_list_append(adaptor->plugins, _plugin);
+                       g_mutex_unlock(&adaptor->plugins_mutex);
+               } else {
+                       close(adaptor_fd[0]);
+                       close(adaptor_fd[1]);
+                       close(plugin_fd[0]);
+                       close(plugin_fd[1]);
+                       storage_adaptor_debug("fork error, can not load plugin package");
+               }
+       }
+
+       return 0;
+}
+
+/* //////////////////////////////////////////////////////
+   // Plugin context create / destroy
+   ////////////////////////////////////////////////////// */
+storage_adaptor_plugin_context_h storage_adaptor_create_plugin_context(storage_adaptor_plugin_h plugin,
+                                               const char *app_id,
+                                               const char *app_secret,
+                                               const char *access_token,
+                                               const char *cid,
+                                               const char *uid,
+                                               const char *service_name)
+{
+       storage_adaptor_debug("Starting storage_adaptor_create_plugin_context");
+
+       if (NULL == plugin) {
+               storage_adaptor_error("Invalid argument""(plugin: %p)", plugin);
+               return NULL;
+       }
+
+       if (NULL != plugin->handle) {
+               storage_adaptor_plugin_context_h plugin_context = NULL;
+
+               if (plugin->type == PLUGIN_TYPE_3RD_PARTY) {
+                       plugin_context = (storage_adaptor_plugin_context_h) calloc(1, sizeof(storage_adaptor_plugin_context_t));
+                       if (NULL == plugin_context) {
+                               return NULL;
+                       }
+                       plugin_context->plugin_handle = plugin;
+               }
+
+               plugin_req_enter();
+               plugin->handle->create_context(&plugin_context, SAFE_ADD_STRING(app_id), SAFE_ADD_STRING(app_secret),
+                               SAFE_ADD_STRING(access_token), SAFE_ADD_STRING(cid), SAFE_ADD_STRING(uid));
+               plugin_req_exit_void();
+
+               if (NULL == plugin_context) {
+                       storage_adaptor_error("Create context failed");
+                       return NULL;
+               }
+
+               /* For forked plugin */
+               g_mutex_lock(&plugin->contexts_mutex);
+               plugin->contexts = g_list_append(plugin->contexts, (gpointer)plugin_context);
+               g_mutex_unlock(&plugin->contexts_mutex);
+
+               plugin_context->plugin_uri = strdup(plugin->handle->plugin_uri);
+               plugin_context->service_name = strdup(service_name ? service_name : "");
+               return plugin_context;
+       } else {
+               storage_adaptor_error("Plugin handle is null");
+       }
+
+       storage_adaptor_debug("End storage_adaptor_create_plugin_context");
+       return NULL;
+}
+
+void storage_adaptor_destroy_plugin_context(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h plugin_context)
+{
+       if ((NULL == plugin) || (NULL == plugin_context)) {
+               storage_adaptor_error("Invalid argument""(plugin: %p, plugin_context: %p)", plugin, plugin_context);
+               return;
+       }
+
+       free(plugin_context->plugin_uri);
+       plugin_context->plugin_uri = NULL;
+/*     free(plugin_context->service_name); */
+/*     plugin_context->service_name = NULL; */
+
+       if (NULL != plugin->handle) {
+               plugin_req_enter();
+               plugin->handle->destroy_context(plugin_context);
+               plugin_req_exit_void();
+       } else {
+               storage_adaptor_error("Plugin handle is null");
+       }
+}
+
+/* //////////////////////////////////////////////////////
+   // Get plugin by plugin name
+   ////////////////////////////////////////////////////// */
+storage_adaptor_plugin_h storage_adaptor_get_plugin_by_name(storage_adaptor_h adaptor,
+                                               const char *plugin_uri)
+{
+       storage_adaptor_debug("Starting storage_adaptor_get_plugin_by_name");
+
+       if ((NULL == adaptor) || (NULL == plugin_uri)) {
+               storage_adaptor_error("Invalid argument""(adaptor: %p, plugin_uri: %p)", adaptor, plugin_uri);
+               return NULL;
+       }
+
+       storage_adaptor_plugin_h plugin = NULL;
+       g_mutex_lock(&adaptor->plugins_mutex);
+       int count = g_list_length(adaptor->plugins);
+       int i = 0;
+       for (i = 0; i < count; i++) {
+               storage_adaptor_plugin_h temp_plugin = g_list_nth_data(adaptor->plugins, i);
+               if (NULL != temp_plugin) {
+                       if (0 == strcmp(temp_plugin->handle->plugin_uri, plugin_uri)) {
+                               storage_adaptor_plugin_ref(temp_plugin);
+                               plugin = temp_plugin;
+                               g_mutex_unlock(&adaptor->plugins_mutex);
+                               return plugin;
+                       }
+               }
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return plugin;
+}
+
+/* //////////////////////////////////////////////////////
+   // Plugin load / unload / get plugin list
+   ////////////////////////////////////////////////////// */
+int storage_adaptor_load_plugin(storage_adaptor_h adaptor,
+                                               const char *plugin_path)
+{
+       if ((NULL == adaptor) || (NULL == plugin_path)) {
+               storage_adaptor_error("Invalid argument""(adaptor: %p, plugin_path: %p)", adaptor, plugin_path);
+               return STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (0 == adaptor->started) {
+               storage_adaptor_error("Storage adaptor is not started");
+               return STORAGE_ADAPTOR_ERROR_START;
+       }
+
+       storage_adaptor_plugin_h plugin = storage_adaptor_create_plugin(plugin_path);
+       if (NULL == plugin) {
+               storage_adaptor_error("Could not load plugin %s", plugin_path);
+               return STORAGE_ADAPTOR_ERROR_CREATE;
+       }
+
+       plugin->adaptor = adaptor;
+       storage_adaptor_plugin_ref(plugin);
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       adaptor->plugins = g_list_append(adaptor->plugins, plugin);
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return STORAGE_ADAPTOR_ERROR_NONE;
+}
+
+int storage_adaptor_unload_plugin(storage_adaptor_h adaptor,
+                                               storage_adaptor_plugin_h plugin)
+{
+       if ((NULL == adaptor) || (NULL == plugin)) {
+               storage_adaptor_error("Invalid argument""(adaptor: %p, plugin: %p)", adaptor, plugin);
+               return STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       if (0 == adaptor->started) {
+               storage_adaptor_error("Storage adaptor is not started");
+               return STORAGE_ADAPTOR_ERROR_START;
+       }
+
+       if (!storage_adaptor_has_plugin(adaptor, plugin)) {
+               storage_adaptor_error("Storage adaptor has no plugin");
+               return STORAGE_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       plugin->adaptor = NULL;
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       adaptor->plugins = g_list_remove(adaptor->plugins, plugin);
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       storage_adaptor_plugin_unref(plugin);
+
+       return STORAGE_ADAPTOR_ERROR_NONE;
+}
+
+GList *storage_adaptor_get_plugins(storage_adaptor_h adaptor)
+{
+       if (NULL == adaptor) {
+               storage_adaptor_error("Invalid argument""(adaptor: %p)", adaptor);
+               return NULL;
+       }
+
+       GList *plugins = NULL;
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       int plugins_count = g_list_length(adaptor->plugins);
+       int i = 0;
+       for (i = 0; i < plugins_count; i++) {
+               storage_adaptor_plugin_h plugin = g_list_nth_data(adaptor->plugins, i);
+               if (NULL != plugin) {
+                       storage_adaptor_plugin_ref(plugin);
+                       plugins = g_list_append(plugins, plugin);
+               }
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return plugins;
+}
+
+/* ////////////////////////////////////////////////////////////
+   // Adaptor Etc Functions
+   //////////////////////////////////////////////////////////// */
+
+/* Get plugin name by plugin */
+void storage_adaptor_get_plugin_uri(storage_adaptor_plugin_h plugin,
+                                               char **plugin_uri)
+{
+       if ((NULL == plugin) || (NULL == plugin_uri)) {
+               storage_adaptor_error("Invalid argument""(plugin: %p)", plugin);
+               return;
+       }
+       if ((NULL != plugin->handle) && (NULL != plugin->handle->plugin_uri)) {
+               *plugin_uri = strdup(plugin->handle->plugin_uri);
+       }
+}
+
+/**
+ * Refresh access token
+ */
+EXPORT_API
+storage_error_code_t storage_adaptor_refresh_access_token(storage_adaptor_plugin_context_h context,
+                                               const char *new_access_token)
+{
+       if ((NULL == context) || (NULL == new_access_token) || (0 >= strlen(new_access_token))) {
+               return STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+       storage_adaptor_debug("New access token : %s", new_access_token);
+
+       free(context->access_token);
+       context->access_token = NULL;
+       context->access_token = strdup(new_access_token);
+
+       return STORAGE_ADAPTOR_ERROR_NONE;
+}
+
+
+EXPORT_API
+storage_error_code_t storage_adaptor_refresh_uid(storage_adaptor_plugin_context_h context,
+                                               const char *new_uid)
+{
+       if ((NULL == context) || (NULL == new_uid) || (0 >= strlen(new_uid))) {
+               return STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+       storage_adaptor_debug("New uid : %s", new_uid);
+
+       free(context->uid);
+       context->uid = NULL;
+       context->uid = strdup(new_uid);
+
+       return STORAGE_ADAPTOR_ERROR_NONE;
+}
+
+
+
+storage_adaptor_error_code_h storage_adaptor_create_error_code(const int64_t code,
+                                               const char *msg)
+{
+       if (NULL == msg) {
+               return NULL;
+       }
+       storage_adaptor_error_code_h error_code =
+                       (storage_adaptor_error_code_h) calloc(1, sizeof(storage_adaptor_error_code_t));
+       if (NULL != error_code) {
+               error_code->code = code;
+               error_code->msg = strdup(msg);
+       }
+
+       return error_code;
+}
+
+void storage_adaptor_destroy_error_code(storage_adaptor_error_code_h *error_code)
+{
+       if ((NULL != error_code) && (NULL != (*error_code))) {
+               free((*error_code)->msg);
+               (*error_code)->msg = NULL;
+               free(*error_code);
+               *error_code = NULL;
+       }
+
+}
+
+storage_adaptor_file_info_h storage_adaptor_create_file_info(void)
+{
+       storage_adaptor_file_info_h _file_info = NULL;
+       _file_info = (storage_adaptor_file_info_h) calloc(1, sizeof(storage_adaptor_file_info_t));
+
+       storage_adaptor_media_meta_s *_media_meta = NULL;
+       _media_meta = (storage_adaptor_media_meta_s *) calloc(1, sizeof(storage_adaptor_media_meta_s));
+
+       storage_adaptor_cloud_meta_s *_cloud_meta = NULL;
+       _cloud_meta = (storage_adaptor_cloud_meta_s *) calloc(1, sizeof(storage_adaptor_cloud_meta_s));
+
+       if ((NULL == _file_info) || (NULL == _media_meta) || (NULL == _cloud_meta)) {
+               free(_file_info);
+               free(_media_meta);
+               free(_cloud_meta);
+
+               return NULL;
+       }
+
+       _media_meta->mime_type          = NULL;
+       _media_meta->title              = NULL;
+       _media_meta->album              = NULL;
+       _media_meta->artist             = NULL;
+       _media_meta->genere             = NULL;
+       _media_meta->recorded_date      = NULL;
+       _media_meta->width              = -1;
+       _media_meta->height             = -1;
+       _media_meta->duration           = -1;
+       _media_meta->copyright          = NULL;
+       _media_meta->track_num          = NULL;
+       _media_meta->description        = NULL;
+       _media_meta->composer           = NULL;
+       _media_meta->year               = NULL;
+       _media_meta->bitrate            = -1;
+       _media_meta->samplerate         = -1;
+       _media_meta->channel            = -1;
+       _media_meta->extra_media_meta   = NULL;
+
+       _cloud_meta->service_name       = NULL;
+       _cloud_meta->usage_byte         = 0ULL;
+       _cloud_meta->quota_byte         = 0ULL;
+       _cloud_meta->extra_cloud_meta   = NULL;
+
+       _file_info->plugin_uri          = NULL;
+       _file_info->object_id           = NULL;
+       _file_info->storage_path        = NULL;
+       _file_info->file_size           = 0ULL;
+
+       /* private only!! */
+       _file_info->revision            = -1;
+       _file_info->timestamp           = 0ULL;
+       _file_info->type                = NULL;
+       _file_info->deleted             = -1;
+       _file_info->expired_time        = 0ULL;
+       _file_info->download_count      = -0U;
+       _file_info->max_download_count  = -0U;
+       _file_info->file_info_index     = -1;
+       _file_info->tag                 = NULL;
+       _file_info->file_share_token    = NULL;
+
+       /* public */
+       _file_info->created_time        = 0ULL;
+       _file_info->modified_time       = 0ULL;
+       _file_info->file_info_index     = -1;
+       _file_info->content_type        = STORAGE_ADAPTOR_CONTENT_TYPE_DEFAULT;
+       _file_info->media_meta          = _media_meta;
+       _file_info->cloud_meta          = _cloud_meta;
+       _file_info->extra_file_info     = NULL;
+
+       return _file_info;
+}
+
+int storage_adaptor_destroy_file_info(storage_adaptor_file_info_h *file_info)
+{
+       if (NULL == file_info) {
+               return 1;
+       }
+
+       if (NULL == *file_info) {
+               return 0;
+       }
+       storage_adaptor_file_info_h _file_info = *file_info;
+
+       free(_file_info->plugin_uri);
+       free(_file_info->object_id);
+       free(_file_info->storage_path);
+       free(_file_info->extra_file_info);
+       free(_file_info->type);
+       free(_file_info->tag);
+
+       storage_adaptor_media_meta_s *_media_meta = _file_info->media_meta;
+
+       if (NULL != _media_meta) {
+               free(_media_meta->mime_type);
+               free(_media_meta->title);
+               free(_media_meta->album);
+               free(_media_meta->artist);
+               free(_media_meta->genere);
+               free(_media_meta->recorded_date);
+               free(_media_meta->copyright);
+               free(_media_meta->track_num);
+               free(_media_meta->description);
+               free(_media_meta->composer);
+               free(_media_meta->year);
+               free(_media_meta->extra_media_meta);
+       }
+
+       storage_adaptor_cloud_meta_s *_cloud_meta = _file_info->cloud_meta;
+
+       if (NULL != _cloud_meta) {
+               free(_cloud_meta->service_name);
+               free(_cloud_meta->extra_cloud_meta);
+       }
+
+
+       if (NULL != _file_info->file_share_token) {
+               free(_file_info->file_share_token->public_token);
+               _file_info->file_share_token->public_token = NULL;
+
+               free(_file_info->file_share_token->auth_code);
+               _file_info->file_share_token->auth_code = NULL;
+
+               free(_file_info->file_share_token);
+       }
+
+       _file_info->plugin_uri          = NULL;
+       _file_info->object_id           = NULL;
+       _file_info->storage_path        = NULL;
+       _file_info->revision            = -1;
+       _file_info->timestamp           = 0ULL;
+       _file_info->type                = NULL;
+       _file_info->file_size           = 0ULL;
+       _file_info->deleted             = -1;
+       _file_info->expired_time        = 0ULL;
+       _file_info->download_count      = 0U;
+       _file_info->max_download_count  = 0U;
+       _file_info->file_info_index     = -1;
+       _file_info->tag                 = NULL;
+       _file_info->file_share_token    = NULL;
+
+
+       free((*file_info)->media_meta);
+       free((*file_info)->cloud_meta);
+       free(*file_info);
+       *file_info = NULL;
+
+       return STORAGE_ADAPTOR_ERROR_NONE;
+}
+
+void __assign_error_code(storage_adaptor_error_code_h *error, const int64_t code, const char *msg)
+{
+       if (NULL != error) {
+               *error = storage_adaptor_create_error_code(code, msg);
+       }
+}
+
+/* ////////////////////////////////////////////////////////////
+   // Adaptor Plugin call Functions
+   //////////////////////////////////////////////////////////// */
+
+
+
+/* ////////////////////// Public feature //////////////////////////// */
+
+EXPORT_API
+storage_error_code_t storage_adaptor_open_file(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *file_path,
+                                               storage_adaptor_file_access_mode_e mode,
+                                               long long int *file_uid,
+                                               storage_adaptor_error_code_h *error)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, file_uid, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (file_uid)"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->open_file, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (open file)"));
+
+       int plugin_fd = 0;
+       storage_error_code_t ret = plugin->handle->open_file(context, file_path, mode, &plugin_fd, error);
+       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+               *file_uid = _get_file_uid_from_plugin_fd(plugin_fd);
+
+               #ifndef FORK_PLUGIN_ARCHITECTURE
+               long long int *buf = (long long int *) calloc(1, sizeof(long long int));
+               if (NULL != buf) {
+                       *buf = *file_uid;
+                       g_hash_table_insert(g_file_uid_list, (void *)&plugin_fd, (void *)buf);
+               }
+               #endif
+
+               #ifdef DEBUG_ADAPTOR_PARAMS
+                       storage_adaptor_debug_func("plugin fd (%d), file uid(%lld)", plugin_fd, *file_uid);
+               #endif
+       }
+
+       return ret;
+}
+
+EXPORT_API
+storage_error_code_t storage_adaptor_close_file(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               long long int file_uid,
+                                               storage_adaptor_error_code_h *error)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->close_file, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (close file)"));
+
+       int plugin_fd = _get_plugin_fd_from_file_uid(file_uid);
+       storage_error_code_t ret = plugin->handle->close_file(context, plugin_fd, error);
+
+       #ifndef FORK_PLUGIN_ARCHITECTURE
+               g_hash_table_remove(g_file_uid_list, (void *)&plugin_fd);
+       #endif
+
+       #ifdef DEBUG_ADAPTOR_PARAMS
+               storage_adaptor_debug_func("plugin fd (%d), file uid(%lld)", plugin_fd, file_uid);
+       #endif
+
+       return ret;
+}
+
+EXPORT_API
+storage_error_code_t storage_adaptor_start_upload_task(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               long long int src_file_descriptor,              /* read only opened */
+                                               const char *upload_dir_path,
+                                               const char *file_name,
+                                               bool need_progress,
+                                               storage_adaptor_error_code_h *error,
+                                               void *user_data)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->start_upload_task, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (start_upload_task)"));
+
+       storage_error_code_t ret = STORAGE_ADAPTOR_ERROR_NONE;
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s START ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] file_uid (%lld)", src_file_descriptor);
+       storage_adaptor_debug_func("[in] path (%s / %s)", upload_dir_path, file_name);
+       storage_adaptor_debug_func("[in] need progress (%d)", need_progress ? 1 : 0);
+#endif
+
+       int plugin_fd = _get_plugin_fd_from_file_uid(src_file_descriptor);
+       plugin_req_enter();
+       ret = plugin->handle->start_upload_task(context, plugin_fd,
+                       upload_dir_path, file_name, need_progress, error, user_data);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+}
+
+EXPORT_API
+storage_error_code_t storage_adaptor_start_download_task(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *storage_dir_path,
+                                               const char *file_name,
+                                               long long int dst_file_descriptor,              /* write only opened */
+                                               bool need_progress,
+                                               storage_adaptor_error_code_h *error,
+                                               void *user_data)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->start_download_task, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (start_download_task)"));
+
+       storage_error_code_t ret = STORAGE_ADAPTOR_ERROR_NONE;
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s START ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] file_uid (%lld)", dst_file_descriptor);
+       storage_adaptor_debug_func("[in] path (%s / %s)", storage_dir_path, file_name);
+       storage_adaptor_debug_func("[in] need progress (%d)", need_progress ? 1 : 0);
+#endif
+
+       int plugin_fd = _get_plugin_fd_from_file_uid(dst_file_descriptor);
+       plugin_req_enter();
+       ret = plugin->handle->start_download_task(context, storage_dir_path, file_name,
+                       plugin_fd, need_progress, error, user_data);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+}
+
+EXPORT_API
+storage_error_code_t storage_adaptor_start_download_thumb_task(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *storage_dir_path,
+                                               const char *file_name,
+                                               long long int dst_file_descriptor,              /* write only opened */
+                                               int thumbnail_size,                     /* level (defined plugin SPEC) */
+                                               bool need_progress,
+                                               storage_adaptor_error_code_h *error,
+                                               void *user_data)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->start_download_thumb_task, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (start_download_thumb_task)"));
+
+       storage_error_code_t ret = STORAGE_ADAPTOR_ERROR_NONE;
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s START ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] file_uid (%lld)", dst_file_descriptor);
+       storage_adaptor_debug_func("[in] path (%s / %s)", storage_dir_path, file_name);
+       storage_adaptor_debug_func("[in] need progress (%d)", need_progress ? 1 : 0);
+#endif
+
+       int plugin_fd = _get_plugin_fd_from_file_uid(dst_file_descriptor);
+       plugin_req_enter();
+       ret = plugin->handle->start_download_thumb_task(context, storage_dir_path, file_name,
+                       plugin_fd, thumbnail_size, need_progress, error, user_data);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+}
+
+
+EXPORT_API
+storage_error_code_t storage_adaptor_cancel_upload_task(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               long long int file_uid,
+                                               storage_adaptor_error_code_h *error)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->cancel_upload_task, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (cancel_upload_task)"));
+
+       storage_error_code_t ret = STORAGE_ADAPTOR_ERROR_NONE;
+
+       int plugin_fd = _get_plugin_fd_from_file_uid(file_uid);
+       plugin_req_enter();
+       ret = plugin->handle->cancel_upload_task(context, plugin_fd, error);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+}
+
+EXPORT_API
+storage_error_code_t storage_adaptor_cancel_download_task(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               long long int file_uid,
+                                               storage_adaptor_error_code_h *error)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->cancel_download_task, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (cancel_download_task)"));
+
+       storage_error_code_t ret = STORAGE_ADAPTOR_ERROR_NONE;
+
+       int plugin_fd = _get_plugin_fd_from_file_uid(file_uid);
+       plugin_req_enter();
+       ret = plugin->handle->cancel_download_task(context, plugin_fd, error);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+
+}
+
+EXPORT_API
+storage_error_code_t storage_adaptor_cancel_download_thumb_task(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               long long int file_uid,
+                                               storage_adaptor_error_code_h *error)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->cancel_download_thumb_task, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (cancel_download_thumb_task)"));
+
+       storage_error_code_t ret = STORAGE_ADAPTOR_ERROR_NONE;
+
+       int plugin_fd = _get_plugin_fd_from_file_uid(file_uid);
+       plugin_req_enter();
+       ret = plugin->handle->cancel_download_thumb_task(context, plugin_fd, error);
+       plugin_req_exit(ret, plugin, error);
+
+       return ret;
+
+}
+
+/* ////////////////////// Common feature //////////////////////////// */
+
+/**
+* @brief Set server information for Storage Plugin
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   server_info                     specifies server information for Storage Plugin
+* @param[in]   request                         specifies optional parameter
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_set_server_info(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               GHashTable *server_info,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->set_server_info, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (set_server_info)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s START ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->uid);
+       storage_adaptor_debug_func("[in] server_info [addr(%p)]", server_info);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->set_server_info(
+                       context, server_info, request, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Makes a directory at cloud
+* @param[in]    upload_file_local_path          specifies local path of the file to be uploaded
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    parent_folder_storage_path      specifies path to locate the folder you want to create
+* @param[in]    folder_name                     specifies folder name to be created at cloud
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info                       specifies Storage Adaptor File Info handle
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_make_directory(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *folder_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->make_directory, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (make_directory)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s START ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->uid);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] folder_name (%s)", folder_name);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->make_directory(
+                       context, parent_folder_storage_path, folder_name, request, file_info, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != file_info) && (NULL != (*file_info))) {
+               storage_adaptor_debug_func("[out] file_info->storage_path (%s)", (*file_info)->storage_path);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Removes a directory at cloud
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    parent_folder_storage_path      specifies parent folder path of folder you want to delete
+* @param[in]    folder_name                     specifies folder name to be deleted from cloud
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info                       specifies Storage Adaptor File Info handle
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_remove_directory(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *folder_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->remove_directory, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (remove_directory)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->uid);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] folder_name (%s)", folder_name);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->remove_directory(context, parent_folder_storage_path,
+                       folder_name, request, file_info, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != file_info) && (NULL != (*file_info))) {
+               storage_adaptor_debug_func("[out] file_info->storage_path (%s)", (*file_info)->storage_path);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Requests folder and file list in a folder
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    parent_folder_storage_path      specifies parent folder path of folder you want to get list
+* @param[in]    folder_name                     specifies folder name you want to get list
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info_list                  specifies Storage Adaptor File Info handle
+* @param[out]   file_info_list_len              specifies length of the file_info_list
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_list(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *folder_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h **file_info_list,
+                                               int *file_info_list_len,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->list, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (list)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->uid);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] folder_name (%s)", folder_name);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->list(context, parent_folder_storage_path,
+                       folder_name, request, file_info_list, file_info_list_len, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       storage_adaptor_debug_func("[out] file_info_list_len (%d)", *file_info_list_len);
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Uploads a file to cloud (Sync)
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    parent_folder_storage_path      specifies folder path of file you want to upload
+* @param[in]    file_name                       specifies file name to be uploaded to cloud
+* @param[in]    upload_file_local_path          specifies local path of the file to be uploaded
+* @param[in]    publish                         specifies Allow to share file with no authentication
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info                       specifies Storage Adaptor File Info handle
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_upload_file_sync(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               const char *upload_file_local_path,
+                                               const int publish,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->upload_file_sync, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (upload_file_sync)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->uid);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] file_name (%s)", file_name);
+       storage_adaptor_debug_func("[in] upload_file_local_path (%s)", upload_file_local_path);
+       storage_adaptor_debug_func("[in] publish (%d)", publish);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->upload_file_sync(context, parent_folder_storage_path,
+                       file_name, upload_file_local_path, publish, request, file_info, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != file_info) && (NULL != (*file_info))) {
+               storage_adaptor_debug_func("[out] file_info->storage_path (%s)", (*file_info)->storage_path);
+               if ((1 == publish) && (NULL != (*file_info)->file_share_token)) {
+                       storage_adaptor_debug_func("[out] file_info->file_share_token->public_token (%s)",
+                                       (*file_info)->file_share_token->public_token);
+                       storage_adaptor_debug_func("[out] file_info->file_share_token->auth_code (%s)",
+                                       (*file_info)->file_share_token->auth_code);
+               }
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Downloads a file to local (Sync)
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    parent_folder_storage_path      specifies folder path of file you want to download
+* @param[in]    file_name                       specifies file name to be downloaded to local
+* @param[in]    download_file_local_path        specifies local path to download
+* @param[in]    request                         specifies optional parameter
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_download_file_sync(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               const char *download_file_local_path,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->download_file_sync, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (download_file_sync)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->uid);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] file_name (%s)", file_name);
+       storage_adaptor_debug_func("[in] download_file_local_path (%s)", download_file_local_path);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->download_file_sync(context, parent_folder_storage_path,
+                       file_name, download_file_local_path, request, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+storage_error_code_t storage_adaptor_download_thumbnail(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *folder_path,
+                                               const char *file_name,
+                                               const char *download_path,
+                                               int thumbnail_size,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->download_thumbnail, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (download_thumbnail)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->uid);
+       storage_adaptor_debug_func("[in] folder_path (%s)", folder_path);
+       storage_adaptor_debug_func("[in] file_name (%s)", file_name);
+       storage_adaptor_debug_func("[in] download_path (%s)", download_path);
+       storage_adaptor_debug_func("[in] thumbnail_size (%d)", thumbnail_size);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->download_thumbnail(context, folder_path,
+                       file_name, download_path, thumbnail_size, request, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+
+
+/**
+* @brief Removes a file at cloud
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    parent_folder_storage_path      specifies folder path of file you want to delete
+* @param[in]    file_name                       specifies file name to be deleted from cloud
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info                       specifies Storage Adaptor File Info handle
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_delete_file(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->delete_file, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (delete_file)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->uid);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] file_name (%s)", file_name);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->delete_file(context, parent_folder_storage_path,
+                       file_name, request, file_info, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != file_info) && (NULL != (*file_info))) {
+               storage_adaptor_debug_func("[out] file_info->storage_path (%s)", (*file_info)->storage_path);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Move a folder into destination folder
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    parent_folder_storage_path      specifies parent folder path of folder you want to move
+* @param[in]    folder_name                     specifies folder name to be moved
+* @param[in]    dest_parent_folder_storage_path specifies new parent folder path
+* @param[in]    new_folder_name                 specifies new folder name
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info                       specifies Storage Adaptor File Info handle
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_move_directory(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *folder_name,
+                                               const char *dest_parent_folder_storage_path,
+                                               const char *new_folder_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->move_directory, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (move_directory)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->uid);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] folder_name (%s)", folder_name);
+       storage_adaptor_debug_func("[in] dest_parent_folder_storage_path (%s)", dest_parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] new_folder_name (%s)", new_folder_name);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->move_directory(context, parent_folder_storage_path,
+                       folder_name, dest_parent_folder_storage_path, new_folder_name, request, file_info, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != file_info) && (NULL != (*file_info))) {
+               storage_adaptor_debug_func("[out] file_info->storage_path (%s)", (*file_info)->storage_path);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Move a file into destination folder
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    parent_folder_storage_path      specifies folder path of file you want to move
+* @param[in]    file_name                       specifies file name to be moved
+* @param[in]    dest_parent_folder_storage_path specifies new folder path
+* @param[in]    new_file_name                   specifies new file name
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info                       specifies Storage Adaptor File Info handle
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_move_file(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               const char *dest_parent_folder_storage_path,
+                                               const char *new_file_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->move_file, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (move_file)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->uid);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] file_name (%s)", file_name);
+       storage_adaptor_debug_func("[in] dest_parent_folder_storage_path (%s)", dest_parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] new_file_name (%s)", new_file_name);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->move_file(context, parent_folder_storage_path,
+                       file_name, dest_parent_folder_storage_path, new_file_name, request, file_info, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != file_info) && (NULL != (*file_info))) {
+               storage_adaptor_debug_func("[out] file_info->storage_path (%s)", (*file_info)->storage_path);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Get state of file transfer request
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    transfer_request_id             specifies unique id for file transfer request
+* @param[in]    request                         specifies optional parameter
+* @param[out]   state                          specifies current state of transfer request
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_get_transfer_state(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               void *transfer_request_id,
+                                               void *request,
+                                               storage_adaptor_transfer_state_e *state,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->get_transfer_state, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (get_transfer_state)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->get_transfer_state(context,  transfer_request_id,
+                       request, state, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if (NULL != state) {
+               storage_adaptor_debug_func("[out] state (%d)", *state);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Set state of file transfer request
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    transfer_request_id             specifies unique id for file transfer request
+* @param[in]    state                          specifies state to set
+* @param[in]    request                         specifies optional parameter
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_set_transfer_state(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               void *transfer_request_id,
+                                               storage_adaptor_transfer_state_e state,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->set_transfer_state, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (set_transfer_state)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->uid);
+       storage_adaptor_debug_func("[in] state(%d)", state);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->set_transfer_state(context, transfer_request_id,
+                       state, request, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+storage_error_code_t storage_adaptor_get_root_folder_path(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               void *request,
+                                               char **root_folder_path,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, root_folder_path, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (root_folder_path)"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->get_root_folder_path, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (get_root_folder_path)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->uid);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->get_root_folder_path(context, request, root_folder_path, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if (NULL != *root_folder_path) {
+               storage_adaptor_debug_func("[out] root_folder_path (%s)", *root_folder_path);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/* ////////////////////// Private feature //////////////////////////// */
+
+/**
+* @brief Uploads a file to cloud (Async)
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    parent_folder_storage_path      specifies folder path of file you want to upload
+* @param[in]    file_name                       specifies file name to be uploaded to cloud
+* @param[in]    upload_file_local_path          specifies local path of the file to be uploaded
+* @param[in]    publish                         specifies Allow to share file with no authentication
+* @param[in]    request                         specifies optional parameter
+* @param[out]   transfer_request_id             specifies
+* @param[out]   error                           specifies error code
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_upload_file_async(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               const char *upload_file_local_path,
+                                               const int publish,
+                                               void *request,
+                                               void *transfer_request_id,
+                                               storage_adaptor_error_code_h *error)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->upload_file_async, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (upload_file_async)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] file_name (%s)", file_name);
+       storage_adaptor_debug_func("[in] upload_file_local_path (%s)", upload_file_local_path);
+       storage_adaptor_debug_func("[in] publish (%d)", publish);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->upload_file_async(context, parent_folder_storage_path,
+                       file_name, upload_file_local_path, publish, request, transfer_request_id);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Downloads a file to local (Async)
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    parent_folder_storage_path      specifies folder path of file you want to download
+* @param[in]    file_name                       specifies file name to be downloaded to local
+* @param[in]    download_file_local_path        specifies local path to download
+* @param[in]    request                         specifies optional parameter
+* @param[out]   transfer_request_id             specifies
+* @param[out]   error                           specifies error code
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_download_file_async(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               const char *download_file_local_path,
+                                               void *request,
+                                               void *transfer_request_id,
+                                               storage_adaptor_error_code_h *error)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->download_file_async, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (download_file_async)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] file_name (%s)", file_name);
+       storage_adaptor_debug_func("[in] download_file_local_path (%s)", download_file_local_path);
+       storage_adaptor_debug_func("[in] request (addr : %p)", request);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->download_file_async(context, parent_folder_storage_path,
+                       file_name, download_file_local_path, request, transfer_request_id);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+
+/**
+* @brief Sets metadata of file at cloud
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    parent_folder_storage_path      specifies folder path of file you want to set meta data
+* @param[in]    file_name                       specifies file name to be updated meta data
+* @param[in]    meta_data                       specifies meta data (A pair of Key, Value)
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info                       specifies Storage Adaptor File Info handle
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_set_meta(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               const void *meta_data,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->set_meta, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (set_meta)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] file_name (%s)", file_name);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->set_meta(context, parent_folder_storage_path,
+                       file_name, meta_data, request, file_info, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != file_info) && (NULL != (*file_info))) {
+               storage_adaptor_debug_func("[out] file_info->storage_path (%s)", (*file_info)->storage_path);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Gets metatdata of file at cloud
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    parent_folder_storage_path      specifies folder path of file you want to get meta data
+* @param[in]    file_name                       specifies file name
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info                       specifies Storage Adaptor File Info handle
+* @param[out]   meta_data                       specifies meta data (A pair of Key, Value)
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_get_meta(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               void **meta_data,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->get_meta, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (get_meta)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] file_name (%s)", file_name);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->get_meta(context, parent_folder_storage_path,
+                       file_name, request, file_info, meta_data, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != file_info) && (NULL != (*file_info))) {
+               storage_adaptor_debug_func("[out] file_info->storage_path (%s)", (*file_info)->storage_path);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Set up Multi Channel Upload
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    parent_folder_storage_path      specifies folder path of file you want to upload
+* @param[in]    file_name                       specifies file name to be uploaded to cloud
+* @param[in]    upload_file_local_path          specifies local path of the file to be uploaded
+* @param[in]    chunk_size_byte                 specifies size of chunk
+* @param[in]    request                         specifies optional parameter
+* @param[out]   mupload_key                     specifies Multi Channel Upload key
+* @param[out]   chunk_count                     specifies total number of chunks
+* @param[out]   file_info                       specifies Storage Adaptor File Info handle
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_start_mupload(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               const char *upload_file_local_path,
+                                               const unsigned long long chunk_size,
+                                               void *request,
+                                               char **mupload_key,
+                                               int *chunk_count,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->start_mupload, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (start_mupload)"));
+
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] file_name (%s)", file_name);
+       storage_adaptor_debug_func("[in] chunk_size (%llu)", chunk_size);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->start_mupload(context, parent_folder_storage_path,
+                       file_name, upload_file_local_path, chunk_size, request, mupload_key, chunk_count,
+                       file_info, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != file_info) && (NULL != (*file_info))) {
+               storage_adaptor_debug_func("[out] file_info->storage_path (%s)", (*file_info)->storage_path);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Uploads a chunk to cloud
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    mupload_key                     specifies Multi Channel Upload key
+* @param[in]    chunk_number                    specifies number of chunk (Starting at 1)
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info                       specifies Storage Adaptor File Info handle
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_upload_mupload(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *mupload_key,
+                                               const int chunk_number,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->upload_mupload, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (upload_mupload)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] mupload_key (%s)", mupload_key);
+       storage_adaptor_debug_func("[in] chunk_number (%d)", chunk_number);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->upload_mupload(context, mupload_key,
+                       chunk_number, request, file_info, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != file_info) && (NULL != (*file_info))) {
+               storage_adaptor_debug_func("[out] file_info->storage_path (%s)", (*file_info)->storage_path);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Ends Multi channel Upload
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    mupload_key                     specifies Multi Channel Upload key
+* @param[in]    publish                         specifies Allow to share file with no authentication
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info                       specifies Storage Adaptor File Info handle
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_end_mupload(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *mupload_key,
+                                               const int publish,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->end_mupload, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (end_mupoad)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] mupload_key (%s)", mupload_key);
+       storage_adaptor_debug_func("[in] publish (%d)", publish);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->end_mupload(context, mupload_key,
+                       publish, request, file_info, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != file_info) && (NULL != (*file_info))) {
+               storage_adaptor_debug_func("[out] file_info->storage_path (%s)", (*file_info)->storage_path);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Requests list of chunks uploaded
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    mupload_key                     specifies Multi Channel Upload key
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info_list                  specifies Storage Adaptor File Info handle
+* @param[out]   file_info_list_len              specifies length of the file_info_list
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_list_mupload(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *mupload_key,
+                                               void *request,
+                                               storage_adaptor_file_info_h **file_info_list,
+                                               int *file_info_list_len,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->list_mupload, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (list_mupload)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] mupload_key (%s)", mupload_key);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->list_mupload(context, mupload_key,
+                       request, file_info_list, file_info_list_len, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if (NULL != file_info_list_len) {
+               storage_adaptor_debug_func("[out] file_info_list_len (%d)", *file_info_list_len);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Cancels all operations
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    mupload_key                     specifies Multi Channel Upload key
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info                       specifies Storage Adaptor File Info handle
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_cancel_mupload(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *mupload_key,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->cancel_mupload, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (cancel_mupload)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] mupload_key (%s)", mupload_key);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->cancel_mupload(context, mupload_key,
+                       request, file_info, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != file_info) && (NULL != (*file_info))) {
+               storage_adaptor_debug_func("[out] file_info->storage_path (%s)", (*file_info)->storage_path);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Starts Transaction
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    request                         specifies optional parameter
+* @param[out]   tx_key                          specifies Transaction key
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_start_transaction(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               void *request,
+                                               char **tx_key,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->start_transaction, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (start_transacion)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->start_transaction(context, request,
+                       tx_key, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if (NULL != tx_key) {
+               storage_adaptor_debug_func("[out] tx_key (%s)", *tx_key);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Uploads a file
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    tx_key                          specifies Transaction key
+* @param[in]    tx_seq                          specifies Transaction sequesnce (Starting at 1)
+* @param[in]    parent_folder_storage_path      specifies folder path of file you want to upload
+* @param[in]    file_name                       specifies file name to be uploaded to cloud
+* @param[in]    upload_file_local_path          specifies local path of the file to be uploaded
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info                       specifies Storage Adaptor File Info handle
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_upload_file_transaction(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *tx_key,
+                                               const int tx_seq,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               const char *upload_file_local_path,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->upload_file_transaction, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (upload_file_transaction)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] tx_key (%s)", tx_key);
+       storage_adaptor_debug_func("[in] tx_seq (%d)", tx_seq);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] file_name (%s)", file_name);
+       storage_adaptor_debug_func("[in] upload_file_local_path (%s)", upload_file_local_path);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->upload_file_transaction(context, tx_key,
+                       tx_seq, parent_folder_storage_path, file_name, upload_file_local_path, request, file_info, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != file_info) && (NULL != (*file_info))) {
+               storage_adaptor_debug_func("[out] file_info->storage_path (%s)", (*file_info)->storage_path);
+
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Updates a folder
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    tx_key                          specifies Transaction key
+* @param[in]    tx_seq                          specifies Transaction sequesnce (Starting at 1)
+* @param[in]    parent_folder_storage_path      specifies folder path of folder you want to update
+* @param[in]    folder_name                     specifies folder name to be updated
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info                       specifies Storage Adaptor File Info handle
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_set_dir_transaction(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *tx_key,
+                                               const int tx_seq,
+                                               const char *parent_folder_storage_path,
+                                               const char *folder_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->set_dir_transaction, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (set_dir_transaction)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] tx_key (%s)", tx_key);
+       storage_adaptor_debug_func("[in] tx_seq (%d)", tx_seq);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] folder_name (%s)", folder_name);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->set_dir_transaction(context, tx_key,
+                       tx_seq, parent_folder_storage_path, folder_name, request, file_info, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != file_info) && (NULL != (*file_info))) {
+               storage_adaptor_debug_func("[out] file_info->storage_path (%s)", (*file_info)->storage_path);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Removes a file
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    tx_key                          specifies Transaction key
+* @param[in]    tx_seq                          specifies Transaction sequesnce (Starting at 1)
+* @param[in]    parent_folder_storage_path      specifies folder path of file you want to delete
+* @param[in]    file_name                       specifies file name to be deleted from cloud
+* @param[in]    request                         specifies optional parameter
+* @param[in]    upload_file_local_path          specifies local path of the file to be uploaded
+* @param[out]   file_info                       specifies Storage Adaptor File Info handle
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_delete_file_transaction(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *tx_key,
+                                               const int tx_seq,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->delete_file_transaction, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (delete_file_transaction)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] tx_key (%s)", tx_key);
+       storage_adaptor_debug_func("[in] tx_seq (%d)", tx_seq);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] file_name (%s)", file_name);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->delete_file_transaction(context, tx_key,
+                       tx_seq, parent_folder_storage_path, file_name, request, file_info, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != file_info) && (NULL != (*file_info))) {
+               storage_adaptor_debug_func("[out] file_info->storage_path (%s)", (*file_info)->storage_path);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Removes a folder
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    tx_key                          specifies Transaction key
+* @param[in]    tx_seq                          specifies Transaction sequesnce (Starting at 1)
+* @param[in]    parent_folder_storage_path      specifies folder path of folder you want to delete
+* @param[in]    folder_name                     specifies folder name to be deleted
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info                       specifies Storage Adaptor File Info handle
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_delete_dir_transaction(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *tx_key,
+                                               const int tx_seq,
+                                               const char *parent_folder_storage_path,
+                                               const char *folder_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->delete_dir_transaction, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (delete_dir_transaction)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] tx_key (%s)", tx_key);
+       storage_adaptor_debug_func("[in] tx_seq (%d)", tx_seq);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] folder_name (%s)", folder_name);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->delete_dir_transaction(context, tx_key,
+                       tx_seq, parent_folder_storage_path, folder_name, request, file_info, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != file_info) && (NULL != (*file_info))) {
+               storage_adaptor_debug_func("[out] file_info->storage_path (%s)", (*file_info)->storage_path);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Ends Transaction
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    tx_key                          specifies Transaction key
+* @param[in]    tx_count                        specifies Transaction order count
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info_list                  specifies Storage Adaptor File Info handle
+* @param[out]   file_info_list_len              specifies length of the file_info_list
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_end_transaction(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *tx_key,
+                                               const int tx_count,
+                                               void *request,
+                                               storage_adaptor_file_info_h **file_info_list,
+                                               int *file_info_list_len,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->end_transaction, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (end_transaction)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] tx_key (%s)", tx_key);
+       storage_adaptor_debug_func("[in] tx_count (%d)", tx_count);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->end_transaction(context, tx_key,
+                       tx_count, request, file_info_list, file_info_list_len, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if (NULL != file_info_list_len) {
+               storage_adaptor_debug_func("[out] file_info_list_len (%d)", *file_info_list_len);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Requests Transaction list
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    tx_key                          specifies Transaction key
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info_list                  specifies Storage Adaptor File Info handle
+* @param[out]   file_info_list_len              specifies length of the file_info_list
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_list_transaction(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *tx_key,
+                                               void *request,
+                                               storage_adaptor_file_info_h **file_info_list,
+                                               int *file_info_list_len,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->list_transaction, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (list_transaction)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] tx_key (%s)", tx_key);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->list_transaction(context, tx_key,
+                       request, file_info_list, file_info_list_len, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if (NULL != file_info_list_len) {
+               storage_adaptor_debug_func("[out] file_info_list_len (%d)", *file_info_list_len);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Cancels all transactions
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    tx_key                          specifies Transaction key
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info_list                  specifies Storage Adaptor File Info handle
+* @param[out]   file_info_list_len              specifies length of the file_info_list
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a negative error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_cancel_transaction(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *tx_key,
+                                               void *request,
+                                               storage_adaptor_file_info_h **file_info_list,
+                                               int *file_info_list_len,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->cancel_transaction, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (cancel_transaction)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] tx_key (%s)", tx_key);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->cancel_transaction(context, tx_key,
+                       request, file_info_list, file_info_list_len, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if (NULL != file_info_list_len) {
+               storage_adaptor_debug_func("[out] file_info_list_len (%d)", *file_info_list_len);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Uploads multiple files to cloud
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    parent_folder_storage_path      specifies folder path of files you want to upload
+* @param[in]    upload_file_local_path_list     specifies local path list of the files to be uploaded
+* @param[in]    upload_list_len                 specifies total number of files to be uploaded
+* @param[in]    request                         specifies optional parameter
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_multi_file_upload(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char **upload_file_local_path_list,
+                                               const int upload_list_len,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->multi_file_upload, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (multi_file_upload)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] upload_list_len (%d)", upload_list_len);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->multi_file_upload(context, parent_folder_storage_path,
+                       upload_file_local_path_list, upload_list_len, request, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Downloads multiple files in a folder
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    parent_folder_storage_path      specifies folder path of files you want to download
+* @param[in]    file_name_list                  specifies file name list to be downloaded
+* @param[in]    file_name_list_len              specifies total number of files to be downloaded
+* @param[in]    download_folder_local_path      specifies local folder path to download files
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info_list                  specifies Storage Adaptor File Info handle
+* @param[out]   file_info_list_len              specifies length of the file_info_list
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_multi_file_download(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name_list,
+                                               const int file_name_list_len,
+                                               const char *download_folder_local_path,
+                                               void *request,
+                                               storage_adaptor_file_info_h **file_info_list,
+                                               int *file_info_list_len,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->multi_file_download, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (multi_file_download)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] download_list_len (%d)", file_name_list_len);
+       storage_adaptor_debug_func("[in] download_folder_local_path (%s)", download_folder_local_path);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->multi_file_download(context, parent_folder_storage_path,
+                       file_name_list, file_name_list_len, download_folder_local_path, request, file_info_list,
+                       file_info_list_len, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if (NULL != file_info_list_len) {
+               storage_adaptor_debug_func("[out] file_info_list_len (%d)", *file_info_list_len);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Requests current server timestamp
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    request                         specifies optional parameter
+* @param[out]   timestamp                       specifies server timestamp
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_get_timestamp(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               void *request,
+                                               unsigned long long *timestamp,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->get_timestamp, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (get_timestamp)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->get_timestamp(context, request,
+                       timestamp, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if (NULL != timestamp) {
+               storage_adaptor_debug_func("[out] timestamp (%llu)", *timestamp);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Requests a file info by public token
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    public_token                    specifies token for Download, Get API
+                                               (when terminal upload file and add publish=true parameter, or
+* @param[in]    auth_code                       specifies Authentication code for public APIs
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info                       specifies Storage Adaptor File Info handle
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_get_file_info_by_public_token(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *public_token,
+                                               const char *auth_code,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->get_file_info_by_public_token, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (get_file_info_by_public_token)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] public_token (%s)", public_token);
+       storage_adaptor_debug_func("[in] auth_code (%s)", auth_code);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->get_file_info_by_public_token(context, public_token,
+                       auth_code, request, file_info, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != file_info) && (NULL != (*file_info))) {
+               storage_adaptor_debug_func("[out] file_info->storage_path (%s)", (*file_info)->storage_path);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Downloads a file by public token (Sync)
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    public_token                    specifies token for Download, Get API
+                                               (when terminal upload file and add publish=true parameter, or
+* @param[in]    auth_code                       specifies Authentication code for public APIs
+* @param[in]    download_file_local_path        specifies local path to download
+* @param[in]    request                         specifies optional parameter
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_download_file_sync_by_public_token(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *public_token,
+                                               const char *auth_code,
+                                               const char *download_file_local_path,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->download_file_sync_by_public_token, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (download_file_sync_by_public_token)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] public_token (%s)", public_token);
+       storage_adaptor_debug_func("[in] auth_code (%s)", auth_code);
+       storage_adaptor_debug_func("[in] download_file_local_path (%s)", download_file_local_path);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->download_file_sync_by_public_token(context, public_token,
+                       auth_code, download_file_local_path, request, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Downloads a file by public token (Async)
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    public_token                    specifies token for Download, Get API
+                                               (when terminal upload file and add publish=true parameter, or
+* @param[in]    auth_code                       specifies Authentication code for public APIs
+* @param[in]    download_file_local_path        specifies local path to download
+* @param[in]    request                         specifies optional parameter
+* @param[out]   transfer_request_id             specifies
+* @param[out]   error                           specifies error code
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_download_file_async_by_public_token(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *public_token,
+                                               const char *auth_code,
+                                               const char *download_file_local_path,
+                                               void *request,
+                                               void *transfer_request_id,
+                                               storage_adaptor_error_code_h *error)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->download_file_async_by_public_token, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (download_file_async_by_public_token)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] public_token (%s)", public_token);
+       storage_adaptor_debug_func("[in] auth_code (%s)", auth_code);
+       storage_adaptor_debug_func("[in] download_file_local_path (%s)", download_file_local_path);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->download_file_async_by_public_token(context, public_token,
+                       auth_code, download_file_local_path, request, transfer_request_id);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       storage_adaptor_debug_func("[out] request_id [addr(%p)]", transfer_request_id);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Authenticates public auth code
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    public_token                    specifies token for Download, Get API
+                                               (when terminal upload file and add publish=true parameter, or
+* @param[in]    auth_code                       specifies Authentication code for public APIs
+* @param[in]    request                         specifies optional parameter
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_auth_public_authcode_by_public_token(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *public_token,
+                                               const char *auth_code,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->auth_public_authcode_by_public_token, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (auth_public_authcode_by_public_token)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] public_token (%s)", public_token);
+       storage_adaptor_debug_func("[in] auth_code (%s)", auth_code);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->auth_public_authcode_by_public_token(context, public_token,
+                       auth_code, request, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Removes multiple files in a folder
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    parent_folder_storage_path      specifies folder path of files you want to delete
+* @param[in]    file_name_list                  specifies file name list to be deleted
+* @param[in]    file_name_list_len              specifies total number of files to be deleted
+* @param[in]    request                         specifies optional parameter
+* @param[out]   file_info_list                  specifies Storage Adaptor File Info handle
+* @param[out]   file_info_list_len              specifies length of the file_info_list
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_delete_multi_file_in_folder(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char **file_name_list,
+                                               const int file_name_list_len,
+                                               void *request,
+                                               storage_adaptor_file_info_h **file_info_list,
+                                               int *file_info_list_len,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->delete_multi_file_in_folder, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (delete_multi_file_in_folder)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path (%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] file_name_list_len (%d)", file_name_list_len);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->delete_multi_file_in_folder(context, parent_folder_storage_path,
+                       file_name_list, file_name_list_len, request, file_info_list, file_info_list_len, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if (NULL != file_info_list_len) {
+               storage_adaptor_debug_func("[out] file_info_list_len (%d)", *file_info_list_len);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Requests policy for upload
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    request                         specifies optional parameter
+* @param[out]   allowed_extension               specifies
+* @param[out]   allowed_extension_len           specifies length of allowed_extension
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_get_policy(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               void *request,
+                                               char ***allowed_extension,
+                                               int *allowed_extension_len,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->get_policy, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (get_policy)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->get_policy(context, request,
+                       allowed_extension, allowed_extension_len, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if (NULL != allowed_extension_len) {
+               storage_adaptor_debug_func("[out] allowed_extension_len (%d)", *allowed_extension_len);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Requests quota of user
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    request                         specifies optional parameter
+* @param[out]   total_usage                     specifies total usage of user
+* @param[out]   total_quota                     specifies total quota of user
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_get_quota(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               void *request,
+                                               unsigned long long *total_usage,
+                                               unsigned long long *total_quota,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->get_quota, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (get_quota)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->get_quota(context, request,
+                       total_usage, total_quota, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if (NULL != total_usage) {
+               storage_adaptor_debug_func("[out] total_usage (%llu)", *total_usage);
+       }
+       if (NULL != total_quota) {
+               storage_adaptor_debug_func("[out] total_quota (%llu)", *total_quota);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Requests Redirect URL mapped with public token (Not yet supported)
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    public_token                    specifies token for Download, Get API
+                                               (when terminal upload file and add publish=true parameter, or
+* @param[in]    request                         specifies optional parameter
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_redirect_url_by_public_token(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *public_token,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->redirect_url_by_public_token, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (redirect_url_by_public_token)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] public_token (%s)", public_token);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->redirect_url_by_public_token(context, public_token,
+                       request, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Creates Upload URL (Not yet supported)
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    parent_folder_storage_path      specifies folder path of files you want to upload
+* @param[in]    file_name                       specifies file name to be uploaded
+* @param[in]    x_upload_content_length         specifies length of content
+* @param[in]    request                         specifies optional parameter
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_create_resuming_upload_url(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               const unsigned long long x_upload_content_length,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->create_resuming_upload_url, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (create_resuming_upload_url)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] parent_folder_storage_path(%s)", parent_folder_storage_path);
+       storage_adaptor_debug_func("[in] file_name(%s)", file_name);
+       storage_adaptor_debug_func("[in] x_upload_content_length(%llu)", x_upload_content_length);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->create_resuming_upload_url(context, parent_folder_storage_path,
+                       file_name, x_upload_content_length, request, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Creates chunk Upload URL (Not yet supported)
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    mupload_key                     specifies Multi Channel Upload key
+* @param[in]    chunk_number                    specifies number of chunk (Starting at 1)
+* @param[in]    x_upload_content_length         specifies length of content
+* @param[in]    request                         specifies optional parameter
+* @param[out]   rupload_key                     specifies Resuming Upload key
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_create_resuming_chunk_upload_url(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *mupload_key,
+                                               const int chunk_number,
+                                               const unsigned long long x_upload_content_length,
+                                               void *request,
+                                               char **rupload_key,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->create_resuming_chunk_upload_url, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (create_resuming_chunk_upload_url)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] mupload_key(%s)", mupload_key);
+       storage_adaptor_debug_func("[in] chunk_number(%d)", chunk_number);
+       storage_adaptor_debug_func("[in] x_upload_content_length(%llu)", x_upload_content_length);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->create_resuming_chunk_upload_url(context, mupload_key,
+                       chunk_number, x_upload_content_length, request, rupload_key, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if (NULL != rupload_key) {
+               storage_adaptor_debug_func("[out] rupload_key (%s)", *rupload_key);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Resumes Upload (Not yet supported)
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    rupload_key                     specifies Resuming Upload key
+* @param[in]    content_range                   specifies range of content
+* @param[in]    content_length                  specifies length of content
+* @param[in]    request                         specifies optional parameter
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_resuming_upload(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *rupload_key,
+                                               const char *change_range,
+                                               const unsigned long long content_length,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->resuming_upload, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (resuming_upload)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] rupload_key(%s)", rupload_key);
+       storage_adaptor_debug_func("[in] change_range(%d)", change_range);
+       storage_adaptor_debug_func("[in] content_length(%llu)", content_length);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->resuming_upload(context, rupload_key,
+                       change_range, content_length, request, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+/**
+* @brief Get progress of file transfer request
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    transfer_request_id             specifies unique id for file transfer request
+* @param[in]    request                         specifies optional parameter
+* @param[out]   progress_size                   specifies current progress size
+* @param[out]   total_size                      specifies total size to transfer
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+storage_error_code_t storage_adaptor_get_transfer_progress(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               void *transfer_request_id,
+                                               void *request,
+                                               unsigned long long *progress_size_byte,
+                                               unsigned long long *total_size_byte,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response)
+{
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (plugin)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin, STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT, "Invalid argument (context)"));
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle, STORAGE_ADAPTOR_ERROR_INVALID_HANDLE,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_INVALID_HANDLE, "Invalid plugin handle"));
+
+
+       storage_adaptor_check_param_equal(NULL, plugin->handle->get_transfer_progress, STORAGE_ADAPTOR_ERROR_UNSUPPORTED,
+                __assign_error_code(error, (int64_t) STORAGE_ADAPTOR_ERROR_UNSUPPORTED, "Plugin does not support this API (get_transfer_progress)"));
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("========== %s ==========", __FUNCTION__);
+       storage_adaptor_debug_func("[in] Context [app_id(%s) access_token(%s) cid(%s) uid(%s)]",
+                       context->app_id, context->access_token, context->cid, context->uid);
+       storage_adaptor_debug_func("[in] tansfer_request_id [addr(%p)]", transfer_request_id);
+       storage_adaptor_debug_func("[in] request [addr(%p)]", request);
+#endif
+
+       plugin_req_enter();
+       storage_error_code_t ret = plugin->handle->get_transfer_progress(context, transfer_request_id,
+                       request, progress_size_byte, total_size_byte, error, response);
+       plugin_req_exit(ret, plugin, error);
+
+#ifdef DEBUG_ADAPTOR_PARAMS
+       storage_adaptor_debug_func("[out] return code (%d)", ret);
+       if (NULL != progress_size_byte) {
+               storage_adaptor_debug_func("[out] progress size : %10llubyte", *progress_size_byte);
+       }
+       if (NULL != total_size_byte) {
+               storage_adaptor_debug_func("[out] total    size : %10llubyte", *total_size_byte);
+       }
+       if ((NULL != error) && (NULL != *error)) {
+               storage_adaptor_debug_func("[out] error->code (%llu)", (*error)->code);
+               storage_adaptor_debug_func("[out] error->msg (%s)", (*error)->msg);
+       }
+       storage_adaptor_debug_func("[out] response [addr(%p)]", response);
+       storage_adaptor_debug_func("========== %s END ==========", __FUNCTION__);
+#endif
+
+       return ret;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* ///////////////////////////////////////////////////////////////////////////////
+   ///////////////////////////////////////////////////////////////////////////////
+   ////////////  Internal function description (for forked plugin)  //////////////
+   ///////////////////////////////////////////////////////////////////////////////
+   /////////////////////////////////////////////////////////////////////////////// */
+
+void *_storage_adaptor_plugin_message_collector(void *data)
+{
+       storage_adaptor_h adaptor = (storage_adaptor_h) data;
+
+       storage_adaptor_info("3rd party plugin listener run");
+       int i, lagest_fd = -1;
+       fd_set read_set;
+       struct timeval tv;
+       tv.tv_sec = 10L;                /* TODO change to define or meaningful value */
+       char msg_buf[PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE] = {0, };
+       int buf_size, rcv_len;
+       GList *dead_list = NULL;
+
+       while (1) {
+               /* Clears and sets fds for select */
+               FD_ZERO(&read_set);
+               FD_SET(adaptor->rd_cmd[0], &read_set);
+               lagest_fd = adaptor->rd_cmd[0];
+
+               /* Sets plugin fds for select */
+               for (i = 0; i < g_list_length(adaptor->rd_list); i++) {
+                       int fd = (int) g_list_nth_data(adaptor->rd_list, i);
+                       FD_SET(fd, &read_set);
+                       if (lagest_fd < fd) {
+                               lagest_fd = fd;
+                       }
+               }
+
+               /* Select with timeout (for avoid blocking issue) */
+               int stmt = select((lagest_fd + 1), &read_set, NULL, NULL, &tv);
+               IF_IS_PLUGIN_THAN_RETURN_NULL();
+               if (stmt == 0) {
+/*                     storage_adaptor_debug("select refrech by timeout(%ld sec) [id : %d]", tv.tv_sec, g_process_identity); */
+                       if (0L >= tv.tv_sec) {
+/*                             storage_adaptor_debug("Resets selector timeout sec"); */
+                               tv.tv_sec = 10L;
+                       }
+                       IF_IS_PLUGIN_THAN_RETURN_NULL();
+               } else if (stmt > 0) {
+                       /* Checking message queue with Plugin processes. */
+                       for (i = 0; i < g_list_length(adaptor->rd_list); i++) {
+                               IF_IS_PLUGIN_THAN_RETURN_NULL();
+                               int fd = (int) g_list_nth_data(adaptor->rd_list, i);
+                               if (FD_ISSET(fd, &read_set)) {
+                                       IF_IS_PLUGIN_THAN_RETURN_NULL();
+                                       /* pre-read buf size */
+                                       rcv_len = read(fd, &buf_size, sizeof(int));
+                                       if (0 >= rcv_len) {
+                                               storage_adaptor_debug("Child process dead (Remove from listening queue)");
+                                               dead_list = g_list_append(dead_list, (gpointer)fd);
+                                               continue;
+                                       }
+                                       /* allocates and read buf data */
+                                       memset(msg_buf, 0, PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE);
+                                       buf_size %= (PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE - 1);
+                                       rcv_len = read(fd, msg_buf, buf_size);
+                                       storage_adaptor_debug("read message [%s][%d]", msg_buf, rcv_len);
+
+                                       if (0 < rcv_len) {
+                                               /* transfer data to adaptor */
+                                               __storage_adaptor_transfer_message(msg_buf);
+                                       } else {
+                                               storage_adaptor_debug("Child process dead (Remove from listening queue)");
+                                               dead_list = g_list_append(dead_list, (gpointer)fd);
+                                       }
+                               }
+                       }
+
+                       /* Checking message queue with Adaptor internal command. */
+                       IF_IS_PLUGIN_THAN_RETURN_NULL();
+                       if (FD_ISSET(adaptor->rd_cmd[0], &read_set)) {
+                               int fd = adaptor->rd_cmd[0];
+                               IF_IS_PLUGIN_THAN_RETURN_NULL();
+                               /* pre-read buf size */
+                               rcv_len = read(fd, &buf_size, sizeof(int));
+
+                               if (0 >= rcv_len) {
+                                       storage_adaptor_debug("Parent process dead : Listener break");
+                                       break;
+                               }
+
+                               /* allocates and read buf data */
+                               memset(msg_buf, 0, PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE);
+                               buf_size %= (PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE - 1);
+                               rcv_len = read(fd, msg_buf, buf_size);
+                               storage_adaptor_debug("read message [%s][%d]", msg_buf, rcv_len);
+
+                               if (0 >= rcv_len) {
+                                       storage_adaptor_debug("Parent process dead : Listener break");
+                                       break;
+                               }
+
+                               /* parse cmd message (e.g. append read_fd / change timeout sec / stop listener) */
+                               int cmd_ret = __storage_adaptor_parse_message_cmd(adaptor, msg_buf);
+                               if (0 > cmd_ret) {
+                                       storage_adaptor_info("3rd party plugin listener stopped by adaptor cmd");
+                                       break;
+                               }
+                       }
+
+                       /* Remove fd with disconnected plugin. */
+                       for (i = 0; i < g_list_length(dead_list); i++) {
+                               adaptor->rd_list = g_list_remove(adaptor->rd_list, (gpointer) g_list_nth_data(dead_list, i));
+                       }
+                       g_list_free(dead_list);
+                       dead_list = NULL;
+               } else {
+                       storage_adaptor_error("plugin message listener error (errno : %d)", errno);
+               }
+       }
+       storage_adaptor_info("3rd party plugin listener stopped");
+
+       return data;
+}
+
+void __storage_adaptor_transfer_message(const char *msg)
+{
+       plugin_message_h t_msg = NULL;
+       int ret = 0;
+       ret = plugin_message_deserialize(msg, &t_msg);
+       if (!ret) {
+               pmnumber req_type, req_id;
+               ret = plugin_message_get_value_number(t_msg, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE, &req_type);
+               if (!ret && (PLUGIN_MESSAGE_TYPE_FUNCTION == req_type)) {
+                       storage_adaptor_debug("Message function type : function");
+                       ret = plugin_message_get_value_number(t_msg, PLUGIN_MESSAGE_ELEMENT_REQUEST_ID, &req_id);
+                       if (!ret) {
+                               storage_adaptor_debug("Send plugin data to requester");
+                               int hooked_fd = (int) req_id;
+                               int len = strlen(msg);
+                               ret = write(hooked_fd, &len, sizeof(int));
+                               ret = write(hooked_fd, msg, sizeof(char) * len);
+                       } else {
+                               storage_adaptor_debug("Couldn't get request id");
+                       }
+               } else if (!ret && (PLUGIN_MESSAGE_TYPE_CALLBACK == req_type)) {
+                       storage_adaptor_debug("Message function type : callback");
+                       /*TODO call callback function */
+                       char *callback_name = NULL;
+                       ret = plugin_message_get_value_string(t_msg, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME, &callback_name);
+                       storage_adaptor_error("Callback name : %s", callback_name);
+                       if (NULL == callback_name) {
+                               storage_adaptor_error("Function name parsing error");
+                       } else if (0 == strncmp(STORAGE_PLUGIN_CALLBACK_DOWNLOAD_FILE_ASYNC_CB,
+                                               callback_name,
+                                               strlen(STORAGE_PLUGIN_CALLBACK_DOWNLOAD_FILE_ASYNC_CB))) {
+                               pmnumber fd, state, ret_code;
+                               char *ret_msg = NULL;
+                               int param_idx = 1;
+                               storage_adaptor_error_code_h error = NULL;
+                               ret = plugin_message_get_value_number(t_msg, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+                               ret = plugin_message_get_value_string(t_msg, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_msg);
+                               if (NULL != ret_msg) {
+                                       error = storage_adaptor_create_error_code((int64_t) ret_code, ret_msg);
+                               }
+                               ret = plugin_message_get_param_number(t_msg, param_idx++, &fd);
+                               ret = plugin_message_get_param_number(t_msg, param_idx++, &state);
+
+                               storage_adaptor_download_state_changed_reply_cb((int)fd, (storage_adaptor_transfer_state_e)state, error, NULL);
+                               storage_adaptor_destroy_error_code(&error);
+                       } else if (0 == strncmp(STORAGE_PLUGIN_CALLBACK_UPLOAD_FILE_ASYNC_CB,
+                                               callback_name,
+                                               strlen(STORAGE_PLUGIN_CALLBACK_UPLOAD_FILE_ASYNC_CB))) {
+                               pmnumber fd, state, ret_code;
+                               char *ret_msg = NULL;
+                               int param_idx = 1;
+                               storage_adaptor_error_code_h error = NULL;
+                               storage_adaptor_file_info_h file_info = NULL;
+                               ret = plugin_message_get_value_number(t_msg, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+                               ret = plugin_message_get_value_string(t_msg, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_msg);
+                               if (NULL != ret_msg) {
+                                       error = storage_adaptor_create_error_code((int64_t) ret_code, ret_msg);
+                               }
+                               ret = plugin_message_get_param_number(t_msg, param_idx++, &fd);
+                               ret = plugin_message_get_param_number(t_msg, param_idx++, &state);
+
+                               plugin_message_array_h file_info_message = NULL;
+                               ret = plugin_message_get_param_array(t_msg, param_idx++, &file_info_message);
+                               if ((0 == ret) && (NULL != file_info_message)) {
+                                       file_info = _get_file_info_from_message_array(file_info_message, param_idx++);
+                               }
+
+                               storage_adaptor_upload_state_changed_reply_cb((int)fd,
+                                               (storage_adaptor_transfer_state_e)state, file_info, error, NULL);
+
+                               storage_adaptor_destroy_file_info(&file_info);
+                               plugin_message_array_destroy(file_info_message);
+                               storage_adaptor_destroy_error_code(&error);
+                       } else if (0 == strncmp(STORAGE_PLUGIN_CALLBACK_PROGRESS_CB,
+                                               callback_name,
+                                               strlen(STORAGE_PLUGIN_CALLBACK_PROGRESS_CB))) {
+                               pmnumber fd, progress, total, ret_code;
+                               char *ret_msg = NULL;
+                               int param_idx = 1;
+                               storage_adaptor_error_code_h error = NULL;
+                               ret = plugin_message_get_value_number(t_msg, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+                               ret = plugin_message_get_value_string(t_msg, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_msg);
+                               if (NULL != ret_msg) {
+                                       error = storage_adaptor_create_error_code((int64_t) ret_code, ret_msg);
+                               }
+                               ret = plugin_message_get_param_number(t_msg, param_idx++, &fd);
+                               ret = plugin_message_get_param_number(t_msg, param_idx++, &progress);
+                               ret = plugin_message_get_param_number(t_msg, param_idx++, &total);
+
+                               storage_adaptor_task_progress_reply_cb((int)fd,
+                                               (unsigned long long)progress, (unsigned long long)total, error, NULL);
+                               storage_adaptor_destroy_error_code(&error);
+                       } else {
+                               storage_adaptor_error("Invalid callback name : %s", callback_name);
+                       }
+                       free(callback_name);
+               } else {
+                       storage_adaptor_warning("Received message parsing fail.");
+               }
+               plugin_message_destroy(t_msg);
+       }
+}
+
+int __storage_adaptor_parse_message_cmd(storage_adaptor_h adaptor, char *msg)
+{
+       char *cmd_data = NULL;
+       if (0 == strncmp(PLUGIN_MESSAGE_LISTENER_CMD_APPEND_FD, msg, strlen(PLUGIN_MESSAGE_LISTENER_CMD_APPEND_FD))) {
+               cmd_data = msg + strlen(PLUGIN_MESSAGE_LISTENER_CMD_APPEND_FD);
+               int fd = atoi(cmd_data);
+
+               adaptor->rd_list = g_list_append(adaptor->rd_list, (gpointer)fd);
+       } else if (0 == strncmp(PLUGIN_MESSAGE_LISTENER_CMD_STOP, msg, strlen(PLUGIN_MESSAGE_LISTENER_CMD_STOP))) {
+               return -1;
+       }
+
+       return 0;
+}
+
+
+void _storage_adaptor_send_cmd_add_fd(storage_adaptor_h adaptor, int fd)
+{
+       char cmd_buf[256] = {0, };
+       snprintf(cmd_buf, 255, "%s%d", PLUGIN_MESSAGE_LISTENER_CMD_APPEND_FD, fd);
+       int len = strlen(cmd_buf);
+       int wr_ret;
+
+       g_mutex_lock(&adaptor->rd_mutex);
+       wr_ret = write(adaptor->rd_cmd[1], &len, sizeof(int));
+       wr_ret = write(adaptor->rd_cmd[1], cmd_buf, sizeof(char) * len);
+       g_mutex_unlock(&adaptor->rd_mutex);
+       storage_adaptor_debug("writed (%d)(%s)", wr_ret, cmd_buf);
+}
+
+void _storage_adaptor_send_cmd_stop_listen(storage_adaptor_h adaptor)
+{
+       char cmd_buf[256] = {0, };
+       snprintf(cmd_buf, 255, "%s", PLUGIN_MESSAGE_LISTENER_CMD_STOP);
+       int len = strlen(cmd_buf);
+       int wr_ret;
+
+       g_mutex_lock(&adaptor->rd_mutex);
+       wr_ret = write(adaptor->rd_cmd[1], &len, sizeof(int));
+       wr_ret = write(adaptor->rd_cmd[1], cmd_buf, sizeof(char) * len);
+       g_mutex_unlock(&adaptor->rd_mutex);
+       storage_adaptor_debug("writed (%d)(%s)", wr_ret, cmd_buf);
+}
+
+static int storage_adaptor_send_message_to_plugin_sync(storage_adaptor_plugin_h plugin,
+                                               plugin_message_h send_message,
+                                               plugin_message_h *receive_message)
+{
+       int io_ret = 0;
+       int wfd = plugin->wd;
+       int sync_hook[2];
+
+       if (pipe(sync_hook) != -1) {
+               char read_buf[PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE] = {0, };
+
+               plugin_message_set_value_number(send_message, PLUGIN_MESSAGE_ELEMENT_REQUEST_ID, (pmnumber) sync_hook[1]);
+               char *stream = NULL;
+               io_ret = plugin_message_serialize(send_message, &stream);
+               int len = strlen(stream);
+
+               g_mutex_lock(&plugin->message_mutex);
+               io_ret = write(wfd, &len, sizeof(len));
+               io_ret = write(wfd, stream, sizeof(char) * len);
+               g_mutex_unlock(&plugin->message_mutex);
+               free(stream);
+               stream = NULL;
+               len = 0;
+
+               io_ret = read(sync_hook[0], &len, sizeof(len));
+               memset(read_buf, 0, PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE);
+               len %= (PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE - 1);
+               if (0 < len) {
+                       io_ret = read(sync_hook[0], read_buf, len);
+               }
+               storage_adaptor_debug("io ret : %d", io_ret);
+               close(sync_hook[0]);
+               close(sync_hook[1]);
+
+               plugin_message_h _rcv;
+               if (0 < strlen(read_buf)) {
+                       io_ret = plugin_message_deserialize(read_buf, &_rcv);
+                       if (!io_ret) {
+                               *receive_message = _rcv;
+                       }
+               }
+       } else {
+               io_ret = -1;
+       }
+
+       return io_ret;
+}
+
+storage_adaptor_plugin_handle_h __storage_adaptor_create_3rd_party_plugin_handle(const char *plugin_uri)
+{
+       storage_adaptor_plugin_handle_h handle = (storage_adaptor_plugin_handle_h) calloc(1, sizeof(storage_adaptor_plugin_handle_t));
+
+       if (NULL == handle) {
+               return handle;
+       }
+
+       handle->create_context = storage_plugin_send_create_context;
+       handle->destroy_context = storage_plugin_send_destroy_context;
+       handle->set_server_info = storage_plugin_send_set_server_info;
+       handle->make_directory = storage_plugin_send_make_directory;
+       handle->remove_directory = storage_plugin_send_remove_directory;
+       handle->list = storage_plugin_send_get_list;
+       handle->upload_file_sync = storage_plugin_send_upload_file_sync;
+       handle->download_file_sync = storage_plugin_send_download_file_sync;
+       handle->delete_file = storage_plugin_send_delete_file;
+       handle->move_directory = storage_plugin_send_move_directory;
+       handle->move_file = storage_plugin_send_move_file;
+       handle->set_transfer_state = storage_plugin_send_set_transfer_state;
+       handle->get_transfer_state = storage_plugin_send_get_transfer_state;
+       handle->get_root_folder_path = storage_plugin_send_get_root_folder_path;
+
+       handle->start_upload_task = storage_plugin_send_start_upload_task;
+       handle->start_download_task = storage_plugin_send_start_download_task;
+       handle->start_download_thumb_task = storage_plugin_send_start_download_thumb_task;
+       handle->cancel_upload_task = storage_plugin_send_cancel_upload_task;
+       handle->cancel_download_task = storage_plugin_send_cancel_download_task;
+       handle->cancel_download_thumb_task = storage_plugin_send_cancel_download_thumb_task;
+
+       handle->plugin_uri = strdup(plugin_uri);
+
+       return handle;
+}
+
+storage_adaptor_file_info_h _get_file_info_from_message_array(plugin_message_array_h message_array, int index)
+{
+       storage_adaptor_file_info_h file_info = NULL;
+
+       if (NULL == message_array) {
+               return file_info;
+       }
+
+/*
+       //TODO
+       _media_meta->mime_type          = NULL;
+       _media_meta->title              = NULL;
+       _media_meta->album              = NULL;
+       _media_meta->artist             = NULL;
+       _media_meta->genere             = NULL;
+       _media_meta->recorded_date      = NULL;
+       _media_meta->width              = -1;
+       _media_meta->height             = -1;
+       _media_meta->duration           = -1;
+       _media_meta->copyright          = NULL;
+       _media_meta->track_num          = NULL;
+       _media_meta->description        = NULL;
+       _media_meta->composer           = NULL;
+       _media_meta->year               = NULL;
+       _media_meta->bitrate            = -1;
+       _media_meta->samplerate         = -1;
+       _media_meta->channel            = -1;
+       _media_meta->extra_media_meta   = NULL;
+
+       _cloud_meta->service_name       = NULL;
+       _cloud_meta->usage_byte         = 0ULL;
+       _cloud_meta->quota_byte         = 0ULL;
+       _cloud_meta->extra_cloud_meta   = NULL;
+*/
+
+       char *plugin_uri                = NULL;
+       char *object_id                 = NULL;
+       char *storage_path              = NULL;
+       pmnumber file_size              = 0LL;
+       pmnumber created_time           = 0LL;
+       pmnumber modified_time          = 0LL;
+       pmnumber file_info_index        = -1LL;
+       pmnumber content_type           = (pmnumber)STORAGE_ADAPTOR_CONTENT_TYPE_DEFAULT;
+       char *extra_file_info           = NULL;
+
+       int ret = 0;
+       ret = plugin_message_array_get_element(message_array, index, &plugin_uri, &object_id, &storage_path,
+                       &file_size, &created_time, &modified_time, &file_info_index, &content_type, &extra_file_info);
+
+       if (0 == ret) {
+               file_info = storage_adaptor_create_file_info();
+
+               if (NULL != file_info) {
+                       file_info->plugin_uri           = plugin_uri;
+                       file_info->object_id            = object_id;
+                       file_info->storage_path         = storage_path;
+                       file_info->file_size            = (unsigned long long) file_size;
+                       file_info->created_time         = (unsigned long long) created_time;
+                       file_info->modified_time        = (unsigned long long) modified_time;
+                       file_info->file_info_index      = (long long int) file_info_index;
+                       file_info->content_type         = (int) content_type;
+                       file_info->extra_file_info      = extra_file_info;
+               } else {
+                       free(plugin_uri);
+                       free(object_id);
+                       free(extra_file_info);
+               }
+       }
+
+       return file_info;
+}
+
+int _message_array_set_file_info(plugin_message_array_h message_array, int index, storage_adaptor_file_info_h file_info)
+{
+       int ret = STORAGE_ADAPTOR_ERROR_NONE;
+       if ((NULL == message_array) || (NULL == file_info)) {
+               return -1;
+       }
+
+/*
+       //TODO
+       _media_meta->mime_type          = NULL;
+       _media_meta->title              = NULL;
+       _media_meta->album              = NULL;
+       _media_meta->artist             = NULL;
+       _media_meta->genere             = NULL;
+       _media_meta->recorded_date      = NULL;
+       _media_meta->width              = -1;
+       _media_meta->height             = -1;
+       _media_meta->duration           = -1;
+       _media_meta->copyright          = NULL;
+       _media_meta->track_num          = NULL;
+       _media_meta->description        = NULL;
+       _media_meta->composer           = NULL;
+       _media_meta->year               = NULL;
+       _media_meta->bitrate            = -1;
+       _media_meta->samplerate         = -1;
+       _media_meta->channel            = -1;
+       _media_meta->extra_media_meta   = NULL;
+
+       _cloud_meta->service_name       = NULL;
+       _cloud_meta->usage_byte         = 0ULL;
+       _cloud_meta->quota_byte         = 0ULL;
+       _cloud_meta->extra_cloud_meta   = NULL;
+*/
+
+       char *plugin_uri                = SAFE_ADD_STRING(file_info->plugin_uri);
+       char *object_id                 = SAFE_ADD_STRING(file_info->object_id);
+       char *storage_path              = SAFE_ADD_STRING(file_info->storage_path);
+       pmnumber file_size              = (pmnumber) file_info->file_size;
+       pmnumber created_time           = (pmnumber) file_info->created_time;
+       pmnumber modified_time          = (pmnumber) file_info->modified_time;
+       pmnumber file_info_index        = (pmnumber) file_info->file_info_index;
+       pmnumber content_type           = (pmnumber) file_info->content_type;
+       char *extra_file_info           = SAFE_ADD_STRING(file_info->extra_file_info);
+
+       ret = plugin_message_array_add_element(message_array, plugin_uri, object_id, storage_path,
+                       file_size, created_time, modified_time, file_info_index, content_type, extra_file_info);
+
+       return ret;
+}
+
+storage_error_code_t storage_plugin_send_create_context(storage_adaptor_plugin_context_h *context,
+                                                       const char *app_id,
+                                                       const char *app_secret,
+                                                       const char *access_token,
+                                                       const char *cid,
+                                                       const char *uid)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = (*context)->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               (*context)->context_id = (int) (intptr_t)(*context);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) (*context)->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_CREATE_CONTEXT);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               int param_index = 1;
+               plugin_message_set_param_string(message, param_index++, app_id);
+               plugin_message_set_param_string(message, param_index++, app_secret);
+               plugin_message_set_param_string(message, param_index++, access_token);
+               plugin_message_set_param_string(message, param_index++, cid);
+               plugin_message_set_param_string(message, param_index++, uid);
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Create context successed");
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Create context failed (%d)(%s)", ret, ret_msg);
+                               free(ret_msg);
+                               ret_msg = NULL;
+
+                               free(*context);
+                               (*context) = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+storage_error_code_t storage_plugin_send_destroy_context(storage_adaptor_plugin_context_h context)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_DESTROY_CONTEXT);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Destroy context successed");
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Destroy context failed (%d)(%s)", ret, ret_msg);
+                               free(ret_msg);
+                               ret_msg = NULL;
+
+                               storage_adaptor_debug("Force release memory by adaptor process");
+                               free(context->access_token);
+                               free(context);
+                               context = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+storage_error_code_t storage_plugin_send_set_server_info(storage_adaptor_plugin_context_h context,
+                                                       GHashTable *server_info,
+                                                       void *request,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response)
+{
+       return STORAGE_ADAPTOR_ERROR_UNSUPPORTED;
+}
+
+storage_error_code_t storage_plugin_send_make_directory(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *folder_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_MAKE_DIRECTORY);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               int param_index = 1;
+               plugin_message_set_param_string(message, param_index++, parent_folder_storage_path);
+               plugin_message_set_param_string(message, param_index++, folder_name);
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Make directory successed");
+
+                               if (NULL != file_info) {
+                                       storage_adaptor_debug("Get file info");
+                                       int param_idx = 1;
+                                       int param_ret;
+                                       plugin_message_array_h file_info_message = NULL;
+                                       param_ret = plugin_message_get_param_array(result_message, param_idx++, &file_info_message);
+                                       if ((0 == param_ret) && (NULL != file_info_message)) {
+                                               *file_info = _get_file_info_from_message_array(file_info_message, param_idx++);
+                                       }
+                                       plugin_message_array_destroy(file_info_message);
+                               }
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Make directory failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       storage_adaptor_error_code_h error_code = storage_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+
+storage_error_code_t storage_plugin_send_remove_directory(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *folder_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_REMOVE_DIRECTORY);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               int param_index = 1;
+               plugin_message_set_param_string(message, param_index++, parent_folder_storage_path);
+               plugin_message_set_param_string(message, param_index++, folder_name);
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Remove directory successed");
+
+                               if (NULL != file_info) {
+                                       storage_adaptor_debug("Get file info");
+                                       int param_idx = 1;
+                                       int param_ret;
+                                       plugin_message_array_h file_info_message = NULL;
+                                       param_ret = plugin_message_get_param_array(result_message, param_idx++, &file_info_message);
+                                       if ((0 == param_ret) && (NULL != file_info_message)) {
+                                               *file_info = _get_file_info_from_message_array(file_info_message, param_idx++);
+                                       }
+                                       plugin_message_array_destroy(file_info_message);
+                               }
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Remove directory failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       storage_adaptor_error_code_h error_code = storage_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+storage_error_code_t storage_plugin_send_get_list(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *folder_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h **file_info_list,
+                                                       int *file_info_list_len,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_REMOVE_DIRECTORY);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               int param_index = 1;
+               plugin_message_set_param_string(message, param_index++, parent_folder_storage_path);
+               plugin_message_set_param_string(message, param_index++, folder_name);
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Get list successed");
+
+                               int param_ret;
+                               pmnumber len;
+                               param_ret = plugin_message_get_param_number(result_message, 2, &len);
+                               if ((0 == ret) && (NULL != file_info_list) && (len > 0LL)) {
+                                       storage_adaptor_debug("Get file info");
+                                       plugin_message_array_h file_info_message = NULL;
+                                       param_ret = plugin_message_get_param_array(result_message, 1, &file_info_message);
+                                       if ((0 == param_ret) && (NULL != file_info_message)) {
+                                               int i, l = (int) len;
+                                               *file_info_list = (storage_adaptor_file_info_h *) calloc(l, sizeof(storage_adaptor_file_info_h));
+                                               if (NULL != *file_info_list) {
+                                                       for (i = 0; i < l; i++) {
+                                                               (*file_info_list)[i] = _get_file_info_from_message_array(file_info_message, (i+1));
+                                                       }
+                                                       if (NULL != file_info_list_len) {
+                                                               *file_info_list_len = l;
+                                                       }
+                                               }
+                                               plugin_message_array_destroy(file_info_message);
+                                       }
+                               }
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Get list failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       storage_adaptor_error_code_h error_code = storage_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+
+storage_error_code_t storage_plugin_send_upload_file_sync(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       const char *upload_file_local_path,
+                                                       const int publish,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_UPLOAD_FILE_SYNC);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               int param_index = 1;
+               plugin_message_set_param_string(message, param_index++, parent_folder_storage_path);
+               plugin_message_set_param_string(message, param_index++, file_name);
+               plugin_message_set_param_string(message, param_index++, upload_file_local_path);
+               plugin_message_set_param_number(message, param_index++, (pmnumber) publish);
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Upload sync successed");
+
+                               if (NULL != file_info) {
+                                       storage_adaptor_debug("Get file info");
+                                       int param_idx = 1;
+                                       int param_ret;
+                                       plugin_message_array_h file_info_message = NULL;
+                                       param_ret = plugin_message_get_param_array(result_message, param_idx++, &file_info_message);
+                                       if ((0 == param_ret) && (NULL != file_info_message)) {
+                                               *file_info = _get_file_info_from_message_array(file_info_message, param_idx++);
+                                       }
+                                       plugin_message_array_destroy(file_info_message);
+                               }
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Upload sync failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       storage_adaptor_error_code_h error_code = storage_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+
+storage_error_code_t storage_plugin_send_download_file_sync(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       const char *download_file_local_path,
+                                                       void *request,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_DOWNLOAD_FILE_SYNC);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               int param_index = 1;
+               plugin_message_set_param_string(message, param_index++, parent_folder_storage_path);
+               plugin_message_set_param_string(message, param_index++, file_name);
+               plugin_message_set_param_string(message, param_index++, download_file_local_path);
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Download sync successed");
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Download sync failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       storage_adaptor_error_code_h error_code = storage_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+storage_error_code_t storage_plugin_send_delete_file(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_DELETE_FILE);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               int param_index = 1;
+               plugin_message_set_param_string(message, param_index++, parent_folder_storage_path);
+               plugin_message_set_param_string(message, param_index++, file_name);
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Delete file successed");
+
+                               if (NULL != file_info) {
+                                       storage_adaptor_debug("Get file info");
+                                       int param_idx = 1;
+                                       int param_ret;
+                                       plugin_message_array_h file_info_message = NULL;
+                                       param_ret = plugin_message_get_param_array(result_message, param_idx++, &file_info_message);
+                                       if ((0 == param_ret) && (NULL != file_info_message)) {
+                                               *file_info = _get_file_info_from_message_array(file_info_message, param_idx++);
+                                       }
+                                       plugin_message_array_destroy(file_info_message);
+                               }
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Delete file failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       storage_adaptor_error_code_h error_code = storage_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+storage_error_code_t storage_plugin_send_move_directory(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *folder_name,
+                                                       const char *dest_parent_folder_storage_path,
+                                                       const char *new_folder_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_MOVE_DIRECTORY);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               int param_index = 1;
+               plugin_message_set_param_string(message, param_index++, parent_folder_storage_path);
+               plugin_message_set_param_string(message, param_index++, folder_name);
+               plugin_message_set_param_string(message, param_index++, dest_parent_folder_storage_path);
+               plugin_message_set_param_string(message, param_index++, new_folder_name);
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Move directory successed");
+
+                               if (NULL != file_info) {
+                                       storage_adaptor_debug("Get file info");
+                                       int param_idx = 1;
+                                       int param_ret;
+                                       plugin_message_array_h file_info_message = NULL;
+                                       param_ret = plugin_message_get_param_array(result_message, param_idx++, &file_info_message);
+                                       if ((0 == param_ret) && (NULL != file_info_message)) {
+                                               *file_info = _get_file_info_from_message_array(file_info_message, param_idx++);
+                                       }
+                                       plugin_message_array_destroy(file_info_message);
+                               }
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Move directory failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       storage_adaptor_error_code_h error_code = storage_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+storage_error_code_t storage_plugin_send_move_file(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       const char *dest_parent_folder_storage_path,
+                                                       const char *new_file_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_MOVE_FILE);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               int param_index = 1;
+               plugin_message_set_param_string(message, param_index++, parent_folder_storage_path);
+               plugin_message_set_param_string(message, param_index++, file_name);
+               plugin_message_set_param_string(message, param_index++, dest_parent_folder_storage_path);
+               plugin_message_set_param_string(message, param_index++, new_file_name);
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Move file successed");
+
+                               if (NULL != file_info) {
+                                       storage_adaptor_debug("Get file info");
+                                       int param_idx = 1;
+                                       int param_ret;
+                                       plugin_message_array_h file_info_message = NULL;
+                                       param_ret = plugin_message_get_param_array(result_message, param_idx++, &file_info_message);
+                                       if ((0 == param_ret) && (NULL != file_info_message)) {
+                                               *file_info = _get_file_info_from_message_array(file_info_message, param_idx++);
+                                       }
+                                       plugin_message_array_destroy(file_info_message);
+                               }
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Move file failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       storage_adaptor_error_code_h error_code = storage_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+storage_error_code_t storage_plugin_send_set_transfer_state(storage_adaptor_plugin_context_h context,
+                                                       void *transfer_request_id,
+                                                       storage_adaptor_transfer_state_e state,
+                                                       void *request,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_SET_TRANSFER_STATE);
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               int param_index = 1;
+               plugin_message_set_param_number(message, param_index++, (pmnumber)(intptr_t)transfer_request_id);
+               plugin_message_set_param_number(message, param_index++, (pmnumber)state);
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Set transfer state successed");
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Set transfer state failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       storage_adaptor_error_code_h error_code = storage_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+storage_error_code_t storage_plugin_send_get_transfer_state(storage_adaptor_plugin_context_h context,
+                                                       void *transfer_request_id,
+                                                       void *request,
+                                                       storage_adaptor_transfer_state_e *state,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_GET_TRANSFER_STATE);
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               int param_index = 1;
+               plugin_message_set_param_number(message, param_index++, (pmnumber)(intptr_t)transfer_request_id);
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Get transfer state successed");
+                               pmnumber st;
+                               plugin_message_get_param_number(message, 1, &st);
+                               if (NULL != state) {
+                                       *state = (storage_adaptor_transfer_state_e)st;
+                               }
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Get transfer state failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       storage_adaptor_error_code_h error_code = storage_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+storage_error_code_t storage_plugin_send_get_root_folder_path(storage_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       char **root_folder_path,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_GET_ROOT_FOLDER_PATH);
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+/*             int param_index = 1; */
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if (0 == ret) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Get root folder path successed");
+                               char *path = NULL;
+                               plugin_message_get_param_string(message, 1, &path);
+                               if (NULL != root_folder_path) {
+                                       *root_folder_path = path;
+                               }
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Get root folder path failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       storage_adaptor_error_code_h error_code = storage_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+/* ///////////// for 2.4 public API */
+storage_error_code_t storage_plugin_send_start_upload_task(storage_adaptor_plugin_context_h context,
+                                                       int fd,
+                                                       const char *upload_dir,
+                                                       const char *file_path,
+                                                       bool need_progress,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *user_data)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_START_UPLOAD_TASK);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               int param_index = 1;
+               plugin_message_set_param_number(message, param_index++, (pmnumber)fd);
+               plugin_message_set_param_string(message, param_index++, upload_dir);
+               plugin_message_set_param_string(message, param_index++, file_path);
+               plugin_message_set_param_bool(message, param_index++, need_progress);
+
+               param_index = 1;
+               plugin_message_set_opt_param_number(message, param_index++, (pmnumber)(intptr_t)user_data);
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if ((0 == ret) && (NULL != result_message)) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Upload file async successed");
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Upload file async failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       storage_adaptor_error_code_h error_code = storage_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+storage_error_code_t storage_plugin_send_start_download_task(storage_adaptor_plugin_context_h context,
+                                                       const char *storage_dir,
+                                                       const char *file_path,
+                                                       int fd,
+                                                       bool need_progress,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *user_data)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_START_DOWNLOAD_TASK);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               int param_index = 1;
+               plugin_message_set_param_string(message, param_index++, storage_dir);
+               plugin_message_set_param_string(message, param_index++, file_path);
+               plugin_message_set_param_number(message, param_index++, (pmnumber)fd);
+               plugin_message_set_param_bool(message, param_index++, need_progress);
+
+               param_index = 1;
+               plugin_message_set_opt_param_number(message, param_index++, (pmnumber)(intptr_t)user_data);
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if ((0 == ret) && (NULL != result_message)) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Download file async successed");
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Download file async failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       storage_adaptor_error_code_h error_code = storage_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+storage_error_code_t storage_plugin_send_start_download_thumb_task(storage_adaptor_plugin_context_h context,
+                                                       const char *storage_dir,
+                                                       const char *file_path,
+                                                       int fd,
+                                                       int thumbnail_size,
+                                                       bool need_progress,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *user_data)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_START_DOWNLOAD_THUMB_TASK);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               int param_index = 1;
+               plugin_message_set_param_string(message, param_index++, storage_dir);
+               plugin_message_set_param_string(message, param_index++, file_path);
+               plugin_message_set_param_number(message, param_index++, (pmnumber)fd);
+               plugin_message_set_param_number(message, param_index++, (pmnumber)thumbnail_size);
+               plugin_message_set_param_bool(message, param_index++, need_progress);
+
+               param_index = 1;
+               plugin_message_set_opt_param_number(message, param_index++, (pmnumber)(intptr_t)user_data);
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if ((0 == ret) && (NULL != result_message)) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Download thumbnail async successed");
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Download thumbnail async failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       storage_adaptor_error_code_h error_code = storage_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+storage_error_code_t storage_plugin_send_cancel_upload_task(storage_adaptor_plugin_context_h context,
+                                                       int fd,
+                                                       storage_adaptor_error_code_h *error)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_CANCEL_UPLOAD_TASK);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               int param_index = 1;
+               plugin_message_set_param_number(message, param_index++, (pmnumber)fd);
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if ((0 == ret) && (NULL != result_message)) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Upload file async successed");
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Upload file async failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       storage_adaptor_error_code_h error_code = storage_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+storage_error_code_t storage_plugin_send_cancel_download_task(storage_adaptor_plugin_context_h context,
+                                                       int fd,
+                                                       storage_adaptor_error_code_h *error)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_CANCEL_DOWNLOAD_TASK);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               int param_index = 1;
+               plugin_message_set_param_number(message, param_index++, (pmnumber)fd);
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if ((0 == ret) && (NULL != result_message)) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Cancel upload file successed");
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Cancel upload file failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       storage_adaptor_error_code_h error_code = storage_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+storage_error_code_t storage_plugin_send_cancel_download_thumb_task(storage_adaptor_plugin_context_h context,
+                                                       int fd,
+                                                       storage_adaptor_error_code_h *error)
+{
+       storage_adaptor_plugin_h plugin = NULL;
+       plugin = context->plugin_handle;
+
+       int ret = 0;
+       plugin_message_h message = NULL;
+       ret = plugin_message_create(&message);
+
+       if (ret == 0) {
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+                               (pmnumber) context->context_id);
+               plugin_message_set_value_string(message, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+                               STORAGE_PLUGIN_INTERFACE_CANCEL_DOWNLOAD_THUMB_TASK);
+
+               plugin_message_set_value_number(message, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+                               (pmnumber) PLUGIN_MESSAGE_TYPE_FUNCTION);
+
+               int param_index = 1;
+               plugin_message_set_param_number(message, param_index++, (pmnumber)fd);
+
+               plugin_message_h result_message = NULL;
+               ret = storage_adaptor_send_message_to_plugin_sync(plugin, message, &result_message);
+
+               if ((0 == ret) && (NULL != result_message)) {
+                       pmnumber ret_code;
+                       plugin_message_get_value_number(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, &ret_code);
+
+                       ret = (int) ret_code;
+                       char *ret_msg = NULL;
+                       if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                               storage_adaptor_debug("Cancel download thumbnail successed");
+                       } else {
+                               plugin_message_get_value_string(result_message, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, &ret_msg);
+                               storage_adaptor_debug("Cancel download thumbnail failed (%d)(%s)", ret, ret_msg);
+                               if (NULL != error) {
+                                       storage_adaptor_error_code_h error_code = storage_adaptor_create_error_code(ret, ret_msg);
+                                       *error = error_code;
+                               }
+                               free(ret_msg);
+                               ret_msg = NULL;
+                       }
+                       plugin_message_destroy(result_message);
+               }
+       } else {
+               ret = STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL;
+       }
+       plugin_message_destroy(message);
+
+       return ret;
+}
+
+void storage_plugin_receive_download_state_changed_cb(int file_descriptor,
+                                               storage_adaptor_transfer_state_e state,
+                                               storage_adaptor_error_code_h error,
+                                               void *user_data)
+{
+       int ret = 0;
+       plugin_message_h m_callback = NULL;
+
+       if ((0 != plugin_message_create(&m_callback)) || (NULL == m_callback)) {
+               LOGE("[%s/%d] Callback message create failed", __FUNCTION__, __LINE__);
+               return;
+       }
+
+       const char *func_name = STORAGE_PLUGIN_CALLBACK_DOWNLOAD_FILE_ASYNC_CB;
+
+       plugin_message_set_value_string(m_callback, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME, func_name);
+       plugin_message_set_value_number(m_callback, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE, PLUGIN_MESSAGE_TYPE_CALLBACK);
+
+       if (NULL == error) {
+               plugin_message_set_value_number(m_callback, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)STORAGE_ADAPTOR_ERROR_NONE);
+       } else {
+               LOGD("[%s/%d] Callback's error value (%lld, %s)", __FUNCTION__, __LINE__, (long long int)error->code, error->msg);
+               plugin_message_set_value_number(m_callback, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, (pmnumber)error->code);
+               plugin_message_set_value_string(m_callback, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, error->msg);
+       }
+
+       int param_idx = 1;
+       plugin_message_set_param_number(m_callback, param_idx++, (pmnumber)file_descriptor);
+       plugin_message_set_param_number(m_callback, param_idx++, (pmnumber)state);
+
+       char *result = NULL;
+       int rcv_len;
+
+       ret = plugin_message_serialize(m_callback, &result);
+
+       if ((0 == ret) && (NULL != result)) {
+               LOGD("[%s/%d] Send callback data message to adaptor", __FUNCTION__, __LINE__);
+               int res_len = strlen(result);
+               rcv_len = write(g_child_plugin->wd, &res_len, sizeof(int));
+               rcv_len = write(g_child_plugin->wd, result, sizeof(char) * res_len);
+               if (rcv_len <= 0) {
+                       LOGE("[%s/%d] pipe socket writing error", __FUNCTION__, __LINE__);
+               }
+       } else {
+               LOGE("[%s/%d] Callback data message serialization failed", __FUNCTION__, __LINE__);
+       }
+
+       plugin_message_destroy(m_callback);
+}
+
+void storage_plugin_receive_upload_state_changed_cb(int file_descriptor,
+                                               storage_adaptor_transfer_state_e state,
+                                               storage_adaptor_file_info_h file_info,
+                                               storage_adaptor_error_code_h error,
+                                               void *user_data)
+{
+       int ret = 0;
+       plugin_message_h m_callback = NULL;
+
+       if ((0 != plugin_message_create(&m_callback)) || (NULL == m_callback)) {
+               LOGE("[%s/%d] Callback message create failed", __FUNCTION__, __LINE__);
+               return;
+       }
+
+       const char *func_name = STORAGE_PLUGIN_CALLBACK_UPLOAD_FILE_ASYNC_CB;
+
+       plugin_message_set_value_string(m_callback, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME, func_name);
+       plugin_message_set_value_number(m_callback, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE, PLUGIN_MESSAGE_TYPE_CALLBACK);
+
+       if (NULL == error) {
+               plugin_message_set_value_number(m_callback, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)STORAGE_ADAPTOR_ERROR_NONE);
+       } else {
+               LOGD("[%s/%d] Callback's error value (%lld, %s)", __FUNCTION__, __LINE__, (long long int)error->code, error->msg);
+               plugin_message_set_value_number(m_callback, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, (pmnumber)error->code);
+               plugin_message_set_value_string(m_callback, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, error->msg);
+       }
+
+       int param_idx = 1;
+       plugin_message_set_param_number(m_callback, param_idx++, (pmnumber)file_descriptor);
+       plugin_message_set_param_number(m_callback, param_idx++, (pmnumber)state);
+
+       if (NULL != file_info) {
+               LOGD("Insert file info to pipe message");
+               int param_ret;
+               plugin_message_array_h file_info_message = NULL;
+               char message_array_type[20] = {0, };
+               snprintf(message_array_type, 19, "%c%c%c%c%c%c%c%c%c", PLUGIN_DATA_TYPE_STRING,
+                                                       PLUGIN_DATA_TYPE_STRING,
+                                                       PLUGIN_DATA_TYPE_STRING,
+                                                       PLUGIN_DATA_TYPE_NUM,
+                                                       PLUGIN_DATA_TYPE_NUM,
+                                                       PLUGIN_DATA_TYPE_NUM,
+                                                       PLUGIN_DATA_TYPE_NUM,
+                                                       PLUGIN_DATA_TYPE_NUM,
+                                                       PLUGIN_DATA_TYPE_STRING);
+               param_ret = plugin_message_array_create(message_array_type, &file_info_message);
+               if (0 == param_ret) {
+                       _message_array_set_file_info(file_info_message, 1, file_info);
+                       param_ret = plugin_message_set_param_array(m_callback, param_idx++, file_info_message);
+                       plugin_message_array_destroy(file_info_message);
+               }
+       }
+
+       char *result = NULL;
+
+       ret = plugin_message_serialize(m_callback, &result);
+
+       if ((0 == ret) && (NULL != result)) {
+               LOGD("[%s/%d] Send callback data message to adaptor", __FUNCTION__, __LINE__);
+               int res_len = strlen(result);
+               int rcv_len = write(g_child_plugin->wd, &res_len, sizeof(int));
+               rcv_len = write(g_child_plugin->wd, result, sizeof(char) * res_len);
+               if (rcv_len <= 0) {
+                       LOGE("[%s/%d] pipe socket writing error", __FUNCTION__, __LINE__);
+               }
+       } else {
+               LOGE("[%s/%d] Callback data message serialization failed", __FUNCTION__, __LINE__);
+       }
+
+       plugin_message_destroy(m_callback);
+
+}
+
+void storage_plugin_receive_file_progress_cb(int file_descriptor,
+                                               unsigned long long progress_size_byte,
+                                               unsigned long long total_size_byte,
+                                               storage_adaptor_error_code_h error,
+                                               void *user_data)
+{
+       int ret = 0;
+       plugin_message_h m_callback = NULL;
+
+       if ((0 != plugin_message_create(&m_callback)) || (NULL == m_callback)) {
+               LOGE("[%s/%d] Callback message create failed", __FUNCTION__, __LINE__);
+               return;
+       }
+
+       const char *func_name = STORAGE_PLUGIN_CALLBACK_PROGRESS_CB;
+
+       plugin_message_set_value_string(m_callback, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME, func_name);
+       plugin_message_set_value_number(m_callback, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE, PLUGIN_MESSAGE_TYPE_CALLBACK);
+
+       if (NULL == error) {
+               plugin_message_set_value_number(m_callback, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)STORAGE_ADAPTOR_ERROR_NONE);
+       } else {
+               LOGD("[%s/%d] Callback's error value (%lld, %s)", __FUNCTION__, __LINE__, (long long int)error->code, error->msg);
+               plugin_message_set_value_number(m_callback, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, (pmnumber)error->code);
+               plugin_message_set_value_string(m_callback, PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE, error->msg);
+       }
+
+       int param_idx = 1;
+       plugin_message_set_param_number(m_callback, param_idx++, (pmnumber)file_descriptor);
+       plugin_message_set_param_number(m_callback, param_idx++, (pmnumber)progress_size_byte);
+       plugin_message_set_param_number(m_callback, param_idx++, (pmnumber)total_size_byte);
+
+       char *result = NULL;
+
+       ret = plugin_message_serialize(m_callback, &result);
+
+       if ((0 == ret) && (NULL != result)) {
+               LOGD("[%s/%d] Send callback data message to adaptor", __FUNCTION__, __LINE__);
+               int res_len = strlen(result);
+               int rcv_len = write(g_child_plugin->wd, &res_len, sizeof(int));
+               rcv_len = write(g_child_plugin->wd, result, sizeof(char) * res_len);
+               if (rcv_len <= 0) {
+                       LOGE("[%s/%d] pipe socket writing error", __FUNCTION__, __LINE__);
+               }
+       } else {
+               LOGE("[%s/%d] Callback data message serialization failed", __FUNCTION__, __LINE__);
+       }
+
+       plugin_message_destroy(m_callback);
+
+}
+
+
+/* For forked plugin */
+void *_storage_plugin_request_collector(void *data)
+{
+       storage_adaptor_plugin_h plugin = (storage_adaptor_plugin_h) data;
+
+       int rcv_len, buf_size;
+       char msg_buf[PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE] = {0, };
+
+       while (1) {
+               /* pre-read buf size */
+               rcv_len = read(plugin->rd, &buf_size, sizeof(int));
+
+               if (rcv_len <= 0) {
+                       LOGD("shutdown by adaptor disconnected");
+                       return NULL;
+               }
+
+               /* allocates and read buf data */
+               memset(msg_buf, 0, PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE);
+               buf_size %= (PLUGIN_MESSAGE_PROTOCOL_MAX_BUF_SIZE - 1);
+               rcv_len = read(plugin->rd, msg_buf, buf_size);
+               LOGD("read message [%s][len: %d]", msg_buf, rcv_len);
+
+               if (rcv_len <= 0) {
+                       LOGD("shutdown by adaptor disconnected");
+                       return NULL;
+               }
+
+               char *result = NULL;
+               __storage_plugin_progress_command(plugin, msg_buf, &result);
+
+               if (NULL != result) {
+                       int res_len = strlen(result);
+                       rcv_len = write(plugin->wd, &res_len, sizeof(int));
+                       rcv_len = write(plugin->wd, result, sizeof(char) * res_len);
+               }
+               /* transfer data to adaptor */
+       }
+       return data;
+}
+
+storage_adaptor_plugin_context_h __storage_plugin_get_context_by_context_id(storage_adaptor_plugin_h plugin, int context_id)
+{
+       if (NULL == plugin) {
+               return NULL;
+       }
+
+       /* For forked plugin */
+       storage_adaptor_plugin_context_h ctx = NULL;
+       int i, len;
+       len = g_list_length(plugin->contexts);
+
+       for (i = 0; i < len; i++) {
+               ctx = (storage_adaptor_plugin_context_h) g_list_nth_data(plugin->contexts, i);
+
+               if (context_id == ctx->context_id) {
+                       return ctx;
+               }
+       }
+       return NULL;
+}
+
+void __storage_plugin_progress_command(storage_adaptor_plugin_h plugin, char *order, char **result)
+{
+       int ret = 0;
+       plugin_message_h m_order = NULL;
+       plugin_message_h m_result = NULL;
+
+       if ((NULL == order) || (plugin_message_deserialize(order, &m_order))) {
+               LOGE("[%s/%d] Message parse error", __FUNCTION__, __LINE__);
+               return;
+       } else if (plugin_message_create(&m_result)) {
+               plugin_message_destroy(m_order);
+               m_order = NULL;
+
+               LOGE("[%s/%d] Message parse error", __FUNCTION__, __LINE__);
+               return;
+       }
+
+       char *func_name = NULL;
+       int context_id = 0;
+
+       pmnumber ctx, req, type;
+
+       plugin_message_get_value_number(m_order, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID, &ctx);
+       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID, ctx);
+       plugin_message_get_value_number(m_order, PLUGIN_MESSAGE_ELEMENT_REQUEST_ID, &req);
+       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_REQUEST_ID, req);
+       plugin_message_get_value_string(m_order, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME, &func_name);
+       plugin_message_set_value_string(m_result, PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME, func_name);
+       plugin_message_get_value_number(m_order, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE, &type);
+       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE, type);
+       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)STORAGE_ADAPTOR_ERROR_NONE);
+       context_id = (int) ctx;
+       storage_adaptor_plugin_context_h context = __storage_plugin_get_context_by_context_id(plugin, context_id);
+
+       storage_adaptor_error_code_h error_code = NULL;
+       storage_adaptor_file_info_h file_info = NULL;
+
+       if (0 == strncmp(STORAGE_PLUGIN_INTERFACE_CREATE_CONTEXT,
+                       func_name, strlen(STORAGE_PLUGIN_INTERFACE_CREATE_CONTEXT))) {
+               LOGD(">>>>>> %s func start", func_name);
+               char *app_id = NULL;
+               char *app_secret = NULL;
+               char *access_token = NULL;
+               char *cid = NULL;
+               char *uid = NULL;
+               char *service_name = NULL;
+
+               int param_idx = 1;
+               plugin_message_get_param_string(m_order, param_idx++, &app_id);
+               plugin_message_get_param_string(m_order, param_idx++, &app_secret);
+               plugin_message_get_param_string(m_order, param_idx++, &access_token);
+               plugin_message_get_param_string(m_order, param_idx++, &cid);
+               plugin_message_get_param_string(m_order, param_idx++, &uid);
+
+               LOGD("Call library function");
+               context = storage_adaptor_create_plugin_context(plugin,
+                               app_id, app_secret, access_token, cid, uid, "");
+
+               if (NULL == context) {
+                       LOGE("[%s<%s>/%d] Could not create context", __FUNCTION__, func_name, __LINE__);
+/*                     error_code = storage_adaptor_create_error_code((int64_t)STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL, */
+/*                                     "Could not create context"); */
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       "Could not create context");
+               } else {
+                       LOGD("[%s<%s>/%d] Created context successfuly", __FUNCTION__, func_name, __LINE__);
+                       context->context_id = context_id;
+
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)STORAGE_ADAPTOR_ERROR_NONE);
+               }
+
+
+               free(app_id);
+               free(app_secret);
+               free(access_token);
+               free(uid);
+               free(service_name);
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(STORAGE_PLUGIN_INTERFACE_DESTROY_CONTEXT,
+                       func_name, strlen(STORAGE_PLUGIN_INTERFACE_DESTROY_CONTEXT))) {
+               LOGD(">>>>>> %s func start", func_name);
+               if (NULL == context) {
+                       LOGE("[%s<%s>/%d] Could not found context", __FUNCTION__, func_name, __LINE__);
+               } else {
+                       LOGD("[%s<%s>/%d] function success", __FUNCTION__, func_name, __LINE__);
+                       storage_adaptor_destroy_plugin_context(plugin, context);
+
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)STORAGE_ADAPTOR_ERROR_NONE);
+               }
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(STORAGE_PLUGIN_INTERFACE_MAKE_DIRECTORY,
+                       func_name, strlen(STORAGE_PLUGIN_INTERFACE_MAKE_DIRECTORY))) {
+               LOGD(">>>>>> %s func start", func_name);
+               char *parent_path = NULL;
+               char *folder_path = NULL;
+
+               int param_idx = 1;
+               plugin_message_get_param_string(m_order, param_idx++, &parent_path);
+               plugin_message_get_param_string(m_order, param_idx++, &folder_path);
+
+               LOGD("Call library function");
+               ret = plugin->handle->make_directory(context, parent_path, folder_path,
+                               NULL, &file_info, &error_code, NULL);
+
+               if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                       LOGD("API success");
+                       int param_idx = 1;
+
+                       if (NULL != file_info) {
+                               LOGD("Insert file info to pipe message");
+                               int param_ret;
+                               plugin_message_array_h file_info_message = NULL;
+                               char message_array_type[20] = {0, };
+                               snprintf(message_array_type, 19, "%c%c%c%c%c%c%c%c%c", PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_STRING);
+                               param_ret = plugin_message_array_create(message_array_type, &file_info_message);
+                               if (0 == param_ret) {
+                                       _message_array_set_file_info(file_info_message, 1, file_info);
+                                       param_ret = plugin_message_set_param_array(m_result, param_idx++, file_info_message);
+                                       plugin_message_array_destroy(file_info_message);
+                               }
+                       }
+                       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               } else if (NULL != error_code) {
+                       LOGD("API failed, error_code[%lld / %s]", (long long int)error_code->code, error_code->msg);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)error_code->code);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       error_code->msg ? error_code->msg : "");
+                       free(error_code->msg);
+                       free(error_code);
+               } else {
+                       LOGD("API failed ret_code[%d]", ret);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               }
+
+               free(parent_path);
+               free(folder_path);
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(STORAGE_PLUGIN_INTERFACE_REMOVE_DIRECTORY,
+                       func_name, strlen(STORAGE_PLUGIN_INTERFACE_REMOVE_DIRECTORY))) {
+               LOGD(">>>>>> %s func start", func_name);
+               char *parent_path = NULL;
+               char *folder_path = NULL;
+
+               int param_idx = 1;
+               plugin_message_get_param_string(m_order, param_idx++, &parent_path);
+               plugin_message_get_param_string(m_order, param_idx++, &folder_path);
+
+               LOGD("Call library function");
+               ret = plugin->handle->remove_directory(context, parent_path, folder_path,
+                               NULL, &file_info, &error_code, NULL);
+
+               if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                       LOGD("API success");
+                       int param_idx = 1;
+
+                       if (NULL != file_info) {
+                               LOGD("Insert file info to pipe message");
+                               int param_ret;
+                               plugin_message_array_h file_info_message = NULL;
+                               char message_array_type[20] = {0, };
+                               snprintf(message_array_type, 19, "%c%c%c%c%c%c%c%c%c", PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_STRING);
+                               param_ret = plugin_message_array_create(message_array_type, &file_info_message);
+                               if (0 == param_ret) {
+                                       _message_array_set_file_info(file_info_message, 1, file_info);
+                                       param_ret = plugin_message_set_param_array(m_result, param_idx++, file_info_message);
+                                       plugin_message_array_destroy(file_info_message);
+                               }
+                       }
+                       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               } else if (NULL != error_code) {
+                       LOGD("API failed, error_code[%lld / %s]", (long long int)error_code->code, error_code->msg);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)error_code->code);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       error_code->msg ? error_code->msg : "");
+                       free(error_code->msg);
+                       free(error_code);
+               } else {
+                       LOGD("API failed ret_code[%d]", ret);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               }
+
+               free(parent_path);
+               free(folder_path);
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(STORAGE_PLUGIN_INTERFACE_GET_LIST,
+                       func_name, strlen(STORAGE_PLUGIN_INTERFACE_GET_LIST))) {
+               LOGD(">>>>>> %s func start", func_name);
+               char *parent_path = NULL;
+               char *folder_path = NULL;
+
+               int param_idx = 1;
+               plugin_message_get_param_string(m_order, param_idx++, &parent_path);
+               plugin_message_get_param_string(m_order, param_idx++, &folder_path);
+
+               storage_adaptor_file_info_h *file_list = NULL;
+               int file_list_len = 0;
+               LOGD("Call library function");
+               ret = plugin->handle->list(context, parent_path, folder_path,
+                               NULL, &file_list, &file_list_len, &error_code, NULL);
+
+               if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                       int param_idx = 1;
+
+                       if ((NULL != file_list) && (0 < file_list_len)) {
+                               LOGD("Insert file list to pipe message (length : %d)", file_list_len);
+                               int param_ret, i;
+                               plugin_message_array_h file_info_message = NULL;
+                               char message_array_type[20] = {0, };
+                               snprintf(message_array_type, 19, "%c%c%c%c%c%c%c%c%c", PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_STRING);
+                               param_ret = plugin_message_array_create(message_array_type, &file_info_message);
+                               if (0 == param_ret) {
+                                       for (i = 0; i < file_list_len; i++) {
+                                               _message_array_set_file_info(file_info_message, (i + 1), file_list[i]);
+                                               storage_adaptor_destroy_file_info(&(file_list[i]));
+                                       }
+                                       free(file_list);
+                                       file_list = NULL;
+                                       param_ret = plugin_message_set_param_array(m_result, param_idx++, file_info_message);
+                                       param_ret = plugin_message_set_param_number(m_result, param_idx++, (pmnumber)file_list_len);
+                                       plugin_message_array_destroy(file_info_message);
+                               }
+                       }
+                       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               } else if (NULL != error_code) {
+                       LOGD("API failed, error_code[%lld / %s]", (long long int)error_code->code, error_code->msg);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)error_code->code);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       error_code->msg ? error_code->msg : "");
+                       free(error_code->msg);
+                       free(error_code);
+               } else {
+                       LOGD("API failed ret_code[%d]", ret);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               }
+
+               free(parent_path);
+               free(folder_path);
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(STORAGE_PLUGIN_INTERFACE_UPLOAD_FILE_SYNC,
+                       func_name, strlen(STORAGE_PLUGIN_INTERFACE_UPLOAD_FILE_SYNC))) {
+               LOGD(">>>>>> %s func start", func_name);
+               char *parent_path = NULL;
+               char *folder_path = NULL;
+               char *local_path = NULL;
+               pmnumber publish;
+
+               int param_idx = 1;
+               plugin_message_get_param_string(m_order, param_idx++, &parent_path);
+               plugin_message_get_param_string(m_order, param_idx++, &folder_path);
+               plugin_message_get_param_string(m_order, param_idx++, &local_path);
+               plugin_message_get_param_number(m_order, param_idx++, &publish);
+
+               LOGD("Call library function");
+               ret = plugin->handle->upload_file_sync(context, parent_path, folder_path, local_path, (int)publish,
+                               NULL, &file_info, &error_code, NULL);
+
+               if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                       LOGD("API success");
+                       int param_idx = 1;
+
+                       if (NULL != file_info) {
+                               LOGD("Insert file info to pipe message");
+                               int param_ret;
+                               plugin_message_array_h file_info_message = NULL;
+                               char message_array_type[20] = {0, };
+                               snprintf(message_array_type, 19, "%c%c%c%c%c%c%c%c%c", PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_STRING);
+                               param_ret = plugin_message_array_create(message_array_type, &file_info_message);
+                               if (0 == param_ret) {
+                                       _message_array_set_file_info(file_info_message, 1, file_info);
+                                       param_ret = plugin_message_set_param_array(m_result, param_idx++, file_info_message);
+                                       plugin_message_array_destroy(file_info_message);
+                               }
+                       }
+                       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               } else if (NULL != error_code) {
+                       LOGD("API failed, error_code[%lld / %s]", (long long int)error_code->code, error_code->msg);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)error_code->code);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       error_code->msg ? error_code->msg : "");
+                       free(error_code->msg);
+                       free(error_code);
+               } else {
+                       LOGD("API failed ret_code[%d]", ret);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               }
+
+               free(parent_path);
+               free(folder_path);
+               free(local_path);
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(STORAGE_PLUGIN_INTERFACE_DOWNLOAD_FILE_SYNC,
+                       func_name, strlen(STORAGE_PLUGIN_INTERFACE_DOWNLOAD_FILE_SYNC))) {
+               LOGD(">>>>>> %s func start", func_name);
+               char *parent_path = NULL;
+               char *folder_path = NULL;
+               char *local_path = NULL;
+
+               int param_idx = 1;
+               plugin_message_get_param_string(m_order, param_idx++, &parent_path);
+               plugin_message_get_param_string(m_order, param_idx++, &folder_path);
+               plugin_message_get_param_string(m_order, param_idx++, &local_path);
+
+               LOGD("Call library function");
+               ret = plugin->handle->download_file_sync(context, parent_path, folder_path, local_path,
+                               NULL, &error_code, NULL);
+
+               if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                       LOGD("API success");
+                       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               } else if (NULL != error_code) {
+                       LOGD("API failed, error_code[%lld / %s]", (long long int)error_code->code, error_code->msg);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)error_code->code);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       error_code->msg ? error_code->msg : "");
+                       free(error_code->msg);
+                       free(error_code);
+               } else {
+                       LOGD("API failed ret_code[%d]", ret);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               }
+
+               free(parent_path);
+               free(folder_path);
+               free(local_path);
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(STORAGE_PLUGIN_INTERFACE_DELETE_FILE,
+                       func_name, strlen(STORAGE_PLUGIN_INTERFACE_DELETE_FILE))) {
+               LOGD(">>>>>> %s func start", func_name);
+               char *parent_path = NULL;
+               char *folder_path = NULL;
+
+               int param_idx = 1;
+               plugin_message_get_param_string(m_order, param_idx++, &parent_path);
+               plugin_message_get_param_string(m_order, param_idx++, &folder_path);
+
+               LOGD("Call library function");
+               ret = plugin->handle->delete_file(context, parent_path, folder_path,
+                               NULL, &file_info, &error_code, NULL);
+
+               if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                       LOGD("API success");
+                       int param_idx = 1;
+
+                       if (NULL != file_info) {
+                               LOGD("Insert file info to pipe message");
+                               int param_ret;
+                               plugin_message_array_h file_info_message = NULL;
+                               char message_array_type[20] = {0, };
+                               snprintf(message_array_type, 19, "%c%c%c%c%c%c%c%c%c", PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_STRING);
+                               param_ret = plugin_message_array_create(message_array_type, &file_info_message);
+                               if (0 == param_ret) {
+                                       _message_array_set_file_info(file_info_message, 1, file_info);
+                                       param_ret = plugin_message_set_param_array(m_result, param_idx++, file_info_message);
+                                       plugin_message_array_destroy(file_info_message);
+                               }
+                       }
+                       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               } else if (NULL != error_code) {
+                       LOGD("API failed, error_code[%lld / %s]", (long long int)error_code->code, error_code->msg);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)error_code->code);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       error_code->msg ? error_code->msg : "");
+                       free(error_code->msg);
+                       free(error_code);
+               } else {
+                       LOGD("API failed ret_code[%d]", ret);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               }
+
+               free(parent_path);
+               free(folder_path);
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(STORAGE_PLUGIN_INTERFACE_MOVE_DIRECTORY,
+                       func_name, strlen(STORAGE_PLUGIN_INTERFACE_MOVE_DIRECTORY))) {
+               LOGD(">>>>>> %s func start", func_name);
+               char *parent_path = NULL;
+               char *folder_path = NULL;
+               char *dst_parent_path = NULL;
+               char *dst_folder_path = NULL;
+
+               int param_idx = 1;
+               plugin_message_get_param_string(m_order, param_idx++, &parent_path);
+               plugin_message_get_param_string(m_order, param_idx++, &folder_path);
+               plugin_message_get_param_string(m_order, param_idx++, &dst_parent_path);
+               plugin_message_get_param_string(m_order, param_idx++, &dst_folder_path);
+
+               LOGD("Call library function");
+               ret = plugin->handle->move_directory(context, parent_path, folder_path, dst_parent_path, dst_folder_path,
+                               NULL, &file_info, &error_code, NULL);
+
+               if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                       LOGD("API success");
+                       int param_idx = 1;
+
+                       if (NULL != file_info) {
+                               LOGD("Insert file info to pipe message");
+                               int param_ret;
+                               plugin_message_array_h file_info_message = NULL;
+                               char message_array_type[20] = {0, };
+                               snprintf(message_array_type, 19, "%c%c%c%c%c%c%c%c%c", PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_STRING);
+                               param_ret = plugin_message_array_create(message_array_type, &file_info_message);
+                               if (0 == param_ret) {
+                                       _message_array_set_file_info(file_info_message, 1, file_info);
+                                       param_ret = plugin_message_set_param_array(m_result, param_idx++, file_info_message);
+                                       plugin_message_array_destroy(file_info_message);
+                               }
+                       }
+                       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               } else if (NULL != error_code) {
+                       LOGD("API failed, error_code[%lld / %s]", (long long int)error_code->code, error_code->msg);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)error_code->code);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       error_code->msg ? error_code->msg : "");
+                       free(error_code->msg);
+                       free(error_code);
+               } else {
+                       LOGD("API failed ret_code[%d]", ret);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               }
+
+               free(parent_path);
+               free(folder_path);
+               free(dst_parent_path);
+               free(dst_folder_path);
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(STORAGE_PLUGIN_INTERFACE_MOVE_FILE,
+                       func_name, strlen(STORAGE_PLUGIN_INTERFACE_MOVE_FILE))) {
+               LOGD(">>>>>> %s func start", func_name);
+               char *parent_path = NULL;
+               char *file_path = NULL;
+               char *dst_parent_path = NULL;
+               char *dst_file_path = NULL;
+
+               int param_idx = 1;
+               plugin_message_get_param_string(m_order, param_idx++, &parent_path);
+               plugin_message_get_param_string(m_order, param_idx++, &file_path);
+               plugin_message_get_param_string(m_order, param_idx++, &dst_parent_path);
+               plugin_message_get_param_string(m_order, param_idx++, &dst_file_path);
+
+               LOGD("Call library function");
+               ret = plugin->handle->move_file(context, parent_path, file_path, dst_parent_path, dst_file_path,
+                               NULL, &file_info, &error_code, NULL);
+
+               if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                       LOGD("API success");
+                       int param_idx = 1;
+
+                       if (NULL != file_info) {
+                               LOGD("Insert file info to pipe message");
+                               int param_ret;
+                               plugin_message_array_h file_info_message = NULL;
+                               char message_array_type[20] = {0, };
+                               snprintf(message_array_type, 19, "%c%c%c%c%c%c%c%c%c", PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_STRING,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_NUM,
+                                                                       PLUGIN_DATA_TYPE_STRING);
+                               param_ret = plugin_message_array_create(message_array_type, &file_info_message);
+                               if (0 == param_ret) {
+                                       _message_array_set_file_info(file_info_message, 1, file_info);
+                                       param_ret = plugin_message_set_param_array(m_result, param_idx++, file_info_message);
+                                       plugin_message_array_destroy(file_info_message);
+                               }
+                       }
+                       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               } else if (NULL != error_code) {
+                       LOGD("API failed, error_code[%lld / %s]", (long long int)error_code->code, error_code->msg);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)error_code->code);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       error_code->msg ? error_code->msg : "");
+                       free(error_code->msg);
+                       free(error_code);
+               } else {
+                       LOGD("API failed ret_code[%d]", ret);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               }
+
+               free(parent_path);
+               free(file_path);
+               free(dst_parent_path);
+               free(dst_file_path);
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(STORAGE_PLUGIN_INTERFACE_START_UPLOAD_TASK,
+                       func_name, strlen(STORAGE_PLUGIN_INTERFACE_START_UPLOAD_TASK))) {
+               LOGD(">>>>>> %s func start", func_name);
+               pmnumber fd, user_data;
+               char *parent_path = NULL;
+               char *file_name = NULL;
+               bool need_progress = false;
+
+               int param_idx = 1;
+               plugin_message_get_param_number(m_order, param_idx++, &fd);
+               plugin_message_get_param_string(m_order, param_idx++, &parent_path);
+               plugin_message_get_param_string(m_order, param_idx++, &file_name);
+               plugin_message_get_param_bool(m_order, param_idx++, &need_progress);
+
+               param_idx = 1;
+               plugin_message_get_param_number(m_order, param_idx++, &user_data);
+
+               LOGD("Call library function");
+               ret = plugin->handle->start_upload_task(context, (int)fd, parent_path, file_name, need_progress,
+                               &error_code, (void *)(intptr_t)user_data);
+
+               if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                       LOGD("API success");
+
+                       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               } else if (NULL != error_code) {
+                       LOGD("API failed, error_code[%lld / %s]", (long long int)error_code->code, error_code->msg);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)error_code->code);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       error_code->msg ? error_code->msg : "");
+                       free(error_code->msg);
+                       free(error_code);
+               } else {
+                       LOGD("API failed ret_code[%d]", ret);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               }
+
+               free(parent_path);
+               free(file_name);
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(STORAGE_PLUGIN_INTERFACE_START_DOWNLOAD_TASK,
+                       func_name, strlen(STORAGE_PLUGIN_INTERFACE_START_DOWNLOAD_TASK))) {
+               LOGD(">>>>>> %s func start", func_name);
+               pmnumber fd, user_data;
+               char *parent_path = NULL;
+               char *file_name = NULL;
+               bool need_progress = false;
+
+               int param_idx = 1;
+               plugin_message_get_param_string(m_order, param_idx++, &parent_path);
+               plugin_message_get_param_string(m_order, param_idx++, &file_name);
+               plugin_message_get_param_number(m_order, param_idx++, &fd);
+               plugin_message_get_param_bool(m_order, param_idx++, &need_progress);
+
+               param_idx = 1;
+               plugin_message_get_param_number(m_order, param_idx++, &user_data);
+
+               LOGD("Call library function");
+               ret = plugin->handle->start_download_task(context, parent_path, file_name, (int)fd, need_progress,
+                               &error_code, (void *)(intptr_t)user_data);
+
+               if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                       LOGD("API success");
+
+                       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               } else if (NULL != error_code) {
+                       LOGD("API failed, error_code[%lld / %s]", (long long int)error_code->code, error_code->msg);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)error_code->code);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       error_code->msg ? error_code->msg : "");
+                       free(error_code->msg);
+                       free(error_code);
+               } else {
+                       LOGD("API failed ret_code[%d]", ret);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               }
+
+               free(parent_path);
+               free(file_name);
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(STORAGE_PLUGIN_INTERFACE_START_DOWNLOAD_THUMB_TASK,
+                       func_name, strlen(STORAGE_PLUGIN_INTERFACE_START_DOWNLOAD_THUMB_TASK))) {
+               LOGD(">>>>>> %s func start", func_name);
+               pmnumber fd, thumb_size, user_data;
+               char *parent_path = NULL;
+               char *file_name = NULL;
+               bool need_progress = false;
+
+               int param_idx = 1;
+               plugin_message_get_param_string(m_order, param_idx++, &parent_path);
+               plugin_message_get_param_string(m_order, param_idx++, &file_name);
+               plugin_message_get_param_number(m_order, param_idx++, &fd);
+               plugin_message_get_param_number(m_order, param_idx++, &thumb_size);
+               plugin_message_get_param_bool(m_order, param_idx++, &need_progress);
+
+               param_idx = 1;
+               plugin_message_get_param_number(m_order, param_idx++, &user_data);
+
+               LOGD("Call library function");
+               ret = plugin->handle->start_download_thumb_task(context, parent_path, file_name, (int)fd, (int)thumb_size, need_progress,
+                               &error_code, (void *)(intptr_t)user_data);
+
+               if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                       LOGD("API success");
+
+                       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               } else if (NULL != error_code) {
+                       LOGD("API failed, error_code[%lld / %s]", (long long int)error_code->code, error_code->msg);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)error_code->code);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       error_code->msg ? error_code->msg : "");
+                       free(error_code->msg);
+                       free(error_code);
+               } else {
+                       LOGD("API failed ret_code[%d]", ret);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               }
+
+               free(parent_path);
+               free(file_name);
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(STORAGE_PLUGIN_INTERFACE_CANCEL_UPLOAD_TASK,
+                       func_name, strlen(STORAGE_PLUGIN_INTERFACE_CANCEL_UPLOAD_TASK))) {
+               LOGD(">>>>>> %s func start", func_name);
+               pmnumber fd;
+
+               int param_idx = 1;
+               plugin_message_get_param_number(m_order, param_idx++, &fd);
+
+               LOGD("Call library function");
+               ret = plugin->handle->cancel_upload_task(context, (int)fd, &error_code);
+
+               if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                       LOGD("API success");
+
+                       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               } else if (NULL != error_code) {
+                       LOGD("API failed, error_code[%lld / %s]", (long long int)error_code->code, error_code->msg);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)error_code->code);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       error_code->msg ? error_code->msg : "");
+                       free(error_code->msg);
+                       free(error_code);
+               } else {
+                       LOGD("API failed ret_code[%d]", ret);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               }
+
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(STORAGE_PLUGIN_INTERFACE_CANCEL_DOWNLOAD_TASK,
+                       func_name, strlen(STORAGE_PLUGIN_INTERFACE_CANCEL_DOWNLOAD_TASK))) {
+               LOGD(">>>>>> %s func start", func_name);
+               pmnumber fd;
+
+               int param_idx = 1;
+               plugin_message_get_param_number(m_order, param_idx++, &fd);
+
+               LOGD("Call library function");
+               ret = plugin->handle->cancel_download_task(context, (int)fd, &error_code);
+
+               if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                       LOGD("API success");
+
+                       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               } else if (NULL != error_code) {
+                       LOGD("API failed, error_code[%lld / %s]", (long long int)error_code->code, error_code->msg);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)error_code->code);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       error_code->msg ? error_code->msg : "");
+                       free(error_code->msg);
+                       free(error_code);
+               } else {
+                       LOGD("API failed ret_code[%d]", ret);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               }
+
+               LOGD("<<<<<< %s func end", func_name);
+       } else if (0 == strncmp(STORAGE_PLUGIN_INTERFACE_CANCEL_DOWNLOAD_THUMB_TASK,
+                       func_name, strlen(STORAGE_PLUGIN_INTERFACE_CANCEL_DOWNLOAD_THUMB_TASK))) {
+               LOGD(">>>>>> %s func start", func_name);
+               pmnumber fd;
+
+               int param_idx = 1;
+               plugin_message_get_param_number(m_order, param_idx++, &fd);
+
+               LOGD("Call library function");
+               ret = plugin->handle->cancel_download_thumb_task(context, (int)fd, &error_code);
+
+               if (STORAGE_ADAPTOR_ERROR_NONE == ret) {
+                       LOGD("API success");
+
+                       plugin_message_set_value_number(m_result, PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               } else if (NULL != error_code) {
+                       LOGD("API failed, error_code[%lld / %s]", (long long int)error_code->code, error_code->msg);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                                       (pmnumber)error_code->code);
+                       plugin_message_set_value_string(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                                       error_code->msg ? error_code->msg : "");
+                       free(error_code->msg);
+                       free(error_code);
+               } else {
+                       LOGD("API failed ret_code[%d]", ret);
+                       plugin_message_set_value_number(m_result,
+                                       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE, (pmnumber)ret);
+               }
+
+               LOGD("<<<<<< %s func end", func_name);
+       } else { /* TODO Next */
+               LOGD(">>>>>> %s func start", func_name);
+               plugin_message_set_value_number(m_result,
+                               PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+                               (pmnumber)STORAGE_ADAPTOR_ERROR_UNSUPPORTED);
+               plugin_message_set_value_string(m_result,
+                               PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+                               "Unsupported operation");
+               LOGD("<<<<<< %s func end", func_name);
+       }
+
+       storage_adaptor_destroy_file_info(&file_info);
+       free(func_name);
+
+       char *result_data = NULL;
+       plugin_message_serialize(m_result, &result_data);
+       plugin_message_destroy(m_result);
+       plugin_message_destroy(m_order);
+
+       *result = result_data;
+}
diff --git a/adaptor/storage-adaptor/storage-adaptor.h b/adaptor/storage-adaptor/storage-adaptor.h
new file mode 100644 (file)
index 0000000..1d79a1e
--- /dev/null
@@ -0,0 +1,2210 @@
+/*
+* Copyright (c) 2011 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 __STORAGE_ADAPTOR_H__
+#define __STORAGE_ADAPTOR_H__
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+#include <glib.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * Storage adaptor error code
+ */
+typedef enum storage_error_code_e
+{
+       STORAGE_ADAPTOR_ERROR_NONE                      = 0,
+       STORAGE_ADAPTOR_ERROR_LAUNCH                    = 1,    /**< 1 ~ 99: internal error*/
+       STORAGE_ADAPTOR_ERROR_INIT                      = 2,
+       STORAGE_ADAPTOR_ERROR_DEINIT                    = 3,
+       STORAGE_ADAPTOR_ERROR_CREATE                    = 4,
+       STORAGE_ADAPTOR_ERROR_DESTROY                   = 5,
+       STORAGE_ADAPTOR_ERROR_START                     = 6,
+       STORAGE_ADAPTOR_ERROR_STOP                      = 7,
+       STORAGE_ADAPTOR_ERROR_CONNECT                   = 8,
+       STORAGE_ADAPTOR_ERROR_DISCONNECT                = 9,
+       STORAGE_ADAPTOR_ERROR_NOT_FOUND                 = 10,
+       STORAGE_ADAPTOR_ERROR_CORRUPTED                 = 11,
+       STORAGE_ADAPTOR_ERROR_UNSUPPORTED               = 12,
+       STORAGE_ADAPTOR_ERROR_INVALID_HANDLE            = 13,
+       STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT          = 14,
+       STORAGE_ADAPTOR_ERROR_INVALID_ARGUMENT_TYPE     = 15,
+       STORAGE_ADAPTOR_ERROR_NOT_AUTHORIZED            = 16,
+       STORAGE_ADAPTOR_ERROR_ADAPTOR_INTERNAL          = 17,
+       STORAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL           = 18,
+       STORAGE_ADAPTOR_ERROR_SERVER_INTERNAL           = 19,
+       STORAGE_ADAPTOR_ERROR_DBUS                      = 20,
+       STORAGE_ADAPTOR_ERROR_CALLBACK_TIME_OUT         = 21,
+       STORAGE_ADAPTOR_ERROR_MAX
+} storage_error_code_t;
+
+/**
+ * Storage adaptor error code
+ */
+typedef enum _storage_plugin_internal_error_code_e
+{
+       STORAGE_PLUGIN_ERROR_HTTP_BAD_REQUEST           = 400,
+       STORAGE_PLUGIN_ERROR_HTTP_UNAUTHORIZED          = 401,
+       STORAGE_PLUGIN_ERROR_HTTP_FORBIDDEN             = 403,
+       STORAGE_PLUGIN_ERROR_HTTP_NOT_FOUND             = 404,
+       STORAGE_PLUGIN_ERROR_HTTP_METHOD_NOT_ALLOWED    = 405,
+       STORAGE_PLUGIN_ERROR_HTTP_BAD_GATEWAY           = 502,
+       STORAGE_PLUGIN_ERROR_HTTP_SERVICE_UNAVAILBLE    = 503,
+       STORAGE_PLUGIN_ERROR_HTTP_INSUFFICIENT_STORAGE  = 507,
+       STORAGE_PLUGIN_ERROR_HTTP_ETC                   = 598,
+       STORAGE_PLUGIN_ERROR_HTTP_UNKNOWN               = 599,
+
+       STORAGE_PLUGIN_ERROR_CURL_COULDNT_CONNECT       = 601,
+       STORAGE_PLUGIN_ERROR_CURL_TIMEOUT               = 602,
+       STORAGE_PLUGIN_ERROR_CURL_ETC                   = 698,
+       STORAGE_PLUGIN_ERROR_CURL_UNKNOWN               = 699,
+
+       STORAGE_PLUGIN_ERROR_FILE_OPEN_FAILED           = 701,
+       STORAGE_PLUGIN_ERROR_FILE_NOT_EXIST             = 702,
+       STORAGE_PLUGIN_ERROR_FILE_TRANSFER_CANCELED     = 703,
+       STORAGE_PLUGIN_ERROR_FILE_AREADY_EXIST          = 704, // EEXIST
+       STORAGE_PLUGIN_ERROR_FILE_ACCESS_DENIED         = 705, // EACCES
+       STORAGE_PLUGIN_ERROR_FILE_ETC                   = 798,
+       STORAGE_PLUGIN_ERROR_FILE_UNKNOWN               = 799,
+
+       STORAGE_PLUGIN_ERROR_MEMORY_ALLOCATION_FAILED   = 801,
+       STORAGE_PLUGIN_ERROR_MEMORY_ETC                 = 898,
+       STORAGE_PLUGIN_ERROR_MEMORY_UNKNOWN             = 899,
+
+       STORAGE_PLUGIN_ERROR_THREAD_CREATE_FAILED       = 901,
+       STORAGE_PLUGIN_ERROR_THREAD_STOPPED             = 902,
+       STORAGE_PLUGIN_ERROR_THREAD_ETC                 = 908,
+       STORAGE_PLUGIN_ERROR_THREAD_UNNOWN              = 909,
+       STORAGE_PLUGIN_ERROR_ETC                        = 998,
+       STORAGE_PLUGIN_ERROR_UNKNOWN                    = 999,
+} storage_plugin_internal_error_code_e;
+
+/**
+ * Storage adaptor status code
+ */
+typedef enum _storage_adaptor_transfer_state_e
+{
+       STORAGE_ADAPTOR_TRANSFER_STATE_IN_PROGRESS      = 1,
+       STORAGE_ADAPTOR_TRANSFER_STATE_FINISHED         = 2,
+       STORAGE_ADAPTOR_TRANSFER_STATE_CANCELED         = 3,    // canceled by request
+       STORAGE_ADAPTOR_TRANSFER_STATE_FAILED           = 4,    // canceled by system
+
+       STORAGE_ADAPTOR_TRANSFER_STATE_RESUME,  // not use this version yet (Next feature)
+       STORAGE_ADAPTOR_TRANSFER_STATE_PAUSED,  // not use this version yet (Next feature)
+
+       // Private feature
+       STORAGE_ADAPTOR_TRANSFER_STATUS_PROGRESS        = 1,
+       STORAGE_ADAPTOR_TRANSFER_STATUS_RESUME          = 1,
+       STORAGE_ADAPTOR_TRANSFER_STATUS_PAUSE           = 2,
+       STORAGE_ADAPTOR_TRANSFER_STATUS_CANCEL          = 3,    // canceled by request
+       STORAGE_ADAPTOR_TRANSFER_STATUS_STOPPED         = 4,    // canceled by system
+       STORAGE_ADAPTOR_TRANSFER_STATUS_FINISHED        = 5
+} storage_adaptor_transfer_state_e;
+
+typedef storage_adaptor_transfer_state_e storage_adaptor_transfer_status_e;
+
+typedef enum
+{
+       STORAGE_ADAPTOR_FILE_ACCESS_READ        = O_RDONLY,
+       STORAGE_ADAPTOR_FILE_ACCESS_WRITE       = O_WRONLY|O_CREAT|O_EXCL,
+} storage_adaptor_file_access_mode_e;
+
+/**
+ * Storage adaptor content type
+ */
+typedef enum _storage_adaptor_content_type_e
+{
+       STORAGE_ADAPTOR_CONTENT_TYPE_DEFAULT            = -1,   // initalize value
+
+       STORAGE_ADAPTOR_CONTENT_TYPE_IMGAE              = 160,
+       STORAGE_ADAPTOR_CONTENT_TYPE_VIDEO              = 161,
+       STORAGE_ADAPTOR_CONTENT_TYPE_SOUND              = 162,
+       STORAGE_ADAPTOR_CONTENT_TYPE_MUSIC              = 163,
+       STORAGE_ADAPTOR_CONTENT_TYPE_OTHER              = 164,
+       STORAGE_ADAPTOR_CONTENT_TYPE_DOCUMENT           = 165,
+       STORAGE_ADAPTOR_CONTENT_TYPE_THUMBNAIL          = 166,
+
+       STORAGE_ADAPTOR_CONTENT_TYPE_CHUNK_MASK         = 320,
+       STORAGE_ADAPTOR_CONTENT_TYPE_IMGAE_CHUNK        = 480,
+       STORAGE_ADAPTOR_CONTENT_TYPE_VIDEO_CHUNK        = 481,
+       STORAGE_ADAPTOR_CONTENT_TYPE_SOUND_CHUNK        = 482,
+       STORAGE_ADAPTOR_CONTENT_TYPE_MUSIC_CHUNK        = 483,
+       STORAGE_ADAPTOR_CONTENT_TYPE_OTHER_CHUNK        = 484,
+       STORAGE_ADAPTOR_CONTENT_TYPE_DOCUMENT_CHUNK     = 485,
+       STORAGE_ADAPTOR_CONTENT_TYPE_THUMBNAIL_CHUNK    = 486,
+
+       STORAGE_ADAPTOR_CONTENT_TYPE_FOLDER             = 1024,
+       STORAGE_ADAPTOR_CONTENT_TYPE_METADATA           = 2048,
+} storage_adaptor_content_type_e;
+
+
+/**
+ * Storage adaptor plugin handle
+ */
+typedef struct storage_adaptor_plugin_s *storage_adaptor_plugin_h;
+
+/**
+ * Storage adaptor
+ */
+typedef struct storage_adaptor_s *storage_adaptor_h;
+
+/**
+ * Storage adaptor plugin context structure
+ */
+typedef struct storage_adaptor_plugin_context_s
+{
+       // Context variables
+       int context_id;
+       storage_adaptor_plugin_h plugin_handle;
+
+       // User define (input by service-adaptor)
+       char *app_id;
+       char *app_secret;
+       char *access_token;
+       char *cid;
+       char *uid;
+       char *service_name;
+
+       // Plugin define (input by plugin)
+       char *plugin_uri;       // mandatory (package id)
+       void *plugin_data;      // optional
+} storage_adaptor_plugin_context_t;
+typedef struct storage_adaptor_plugin_context_s *storage_adaptor_plugin_context_h;
+
+/**
+ * Structure for error code from server
+ */
+typedef struct storage_adaptor_error_code_s
+{
+       int64_t code;
+       char    *msg;
+} storage_adaptor_error_code_t;
+typedef struct storage_adaptor_error_code_s *storage_adaptor_error_code_h;
+
+typedef struct _storage_adaptor_media_meta_s
+{
+       char *mime_type;
+       char *title;
+       char *album;
+       char *artist;
+       char *genere;
+       char *recorded_date;
+       int width;
+       int height;
+       int duration;
+       char *copyright;
+       char *track_num;
+       char *description;
+       char *composer;
+       char *year;
+       int bitrate;
+       int samplerate;
+       int channel;
+       char *extra_media_meta;
+} storage_adaptor_media_meta_s;
+
+typedef struct _storage_adaptor_cloud_meta_s
+{
+       char *service_name;
+       unsigned long long usage_byte;
+       unsigned long long quota_byte;
+       char *extra_cloud_meta;
+} storage_adaptor_cloud_meta_s;
+
+// private only!!
+/**
+ * Structure Storage File Share token Infomation
+ */
+typedef struct storage_adaptor_file_share_token_s
+{
+       char *public_token;
+       char *auth_code;
+} storage_adaptor_file_share_token_t;
+typedef struct storage_adaptor_file_share_token_s *storage_adaptor_file_share_token_h;
+
+/**
+ * Structure Storage File Infomation
+ */
+typedef struct storage_adaptor_file_info_s
+{
+       // Common
+       char    *plugin_uri;            /**< specifies plugin name generated file_info */
+       char    *object_id;             /**< specifies file object id be used in storage */
+       char    *storage_path;          /**< specifies file path in storage */
+       unsigned long long file_size;   /**< specifies file size (recomend byte)*/
+       int     file_info_index;        /**< specifies file info index (wide use; e.g : chunk upload, multi download)*/
+
+       // private only!!
+       int     revision;
+       unsigned long long timestamp;
+       char    *type;
+       int     deleted;
+       unsigned long long expired_time;
+       unsigned int download_count;
+       unsigned int max_download_count;
+       char    *tag;
+       storage_adaptor_file_share_token_h file_share_token;
+
+
+       // public defined
+       unsigned long long created_time;        /**< specifies timestamp */
+       unsigned long long modified_time;       /**< specifies timestamp */
+       storage_adaptor_content_type_e content_type;
+
+       storage_adaptor_media_meta_s *media_meta;
+       storage_adaptor_cloud_meta_s *cloud_meta;
+       char    *extra_file_info;               /**< specifies content name in metadata */
+} storage_adaptor_file_info_t;
+typedef struct storage_adaptor_file_info_s *storage_adaptor_file_info_h;
+
+/**
+ * Storage adaptor plugin listener
+ */
+typedef struct storage_adaptor_plugin_listener_s *storage_adaptor_plugin_listener_h;
+
+/**
+ * Storage adaptor plugin handle
+ */
+typedef struct storage_adaptor_plugin_handle_s
+{
+       // Mandatory functions to handle plugin in adaptor
+       storage_error_code_t (*create_context)(storage_adaptor_plugin_context_h *context,
+                                                       const char *app_id,
+                                                       const char *app_secret,
+                                                       const char *access_token,
+                                                       const char *cid,
+                                                       const char *uid);
+       storage_error_code_t (*destroy_context)(storage_adaptor_plugin_context_h context);
+       storage_error_code_t (*destroy_handle)(struct storage_adaptor_plugin_handle_s *handle);
+       storage_error_code_t (*set_listener)(storage_adaptor_plugin_listener_h listener);
+       storage_error_code_t (*unset_listener)(void);
+       // Mandatory end
+
+       // Optional
+
+       storage_error_code_t (*open_file) (storage_adaptor_plugin_context_h context,            // Do Not define from plugin (TBD)
+                                                       const char *file_path,
+                                                       storage_adaptor_file_access_mode_e mode,
+                                                       int *file_descriptor,
+                                                       storage_adaptor_error_code_h *error);
+
+       storage_error_code_t (*close_file) (storage_adaptor_plugin_context_h context,           // Do Not define from plugin (TBD)
+                                                       int file_descriptor,
+                                                       storage_adaptor_error_code_h *error);
+
+       storage_error_code_t (*start_upload_task)(storage_adaptor_plugin_context_h context,
+                                                       int src_file_descriptor,                // read only opened
+                                                       const char *upload_dir_path,
+                                                       const char *file_name,
+                                                       bool need_progress,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *user_data);
+
+       storage_error_code_t (*start_download_task)(storage_adaptor_plugin_context_h context,
+                                                       const char *storage_dir_path,
+                                                       const char *file_name,
+                                                       int dst_file_descriptor,                // write only opened
+                                                       bool need_progress,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *user_data);
+
+       storage_error_code_t (*start_download_thumb_task)(storage_adaptor_plugin_context_h context,
+                                                       const char *storage_dir_path,
+                                                       const char *file_name,
+                                                       int dst_file_descriptor,                // write only opened
+                                                       int thumbnail_size,                     // level (defined plugin SPEC)
+                                                       bool need_progress,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *user_data);
+
+       storage_error_code_t (*cancel_upload_task)(storage_adaptor_plugin_context_h context,
+                                                       int file_descriptor,
+                                                       storage_adaptor_error_code_h *error);
+
+       storage_error_code_t (*cancel_download_task)(storage_adaptor_plugin_context_h context,
+                                                       int file_descriptor,
+                                                       storage_adaptor_error_code_h *error);
+
+       storage_error_code_t (*cancel_download_thumb_task)(storage_adaptor_plugin_context_h context,
+                                                       int file_descriptor,
+                                                       storage_adaptor_error_code_h *error);
+
+       // common (yet)
+       storage_error_code_t (*set_server_info)(storage_adaptor_plugin_context_h context,
+                                                       GHashTable *server_info,
+                                                       void *request,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+       // Optional end
+       // common
+       storage_error_code_t (*get_root_folder_path)(storage_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       char **root_folder_path,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       // common
+       storage_error_code_t (*list)(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *folder_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h **file_info_list,
+                                                       int *file_info_list_len,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       // common
+       storage_error_code_t (*make_directory)(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *folder_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       // common
+       storage_error_code_t (*upload_file_sync)(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       const char *upload_file_local_path,
+                                                       const int publish,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       // common
+       storage_error_code_t (*download_file_sync)(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       const char *download_file_local_path,
+                                                       void *request,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       // common
+       storage_error_code_t (*download_thumbnail)(storage_adaptor_plugin_context_h context,
+                                                       const char *folder_path,
+                                                       const char *file_name,
+                                                       const char *download_path,
+                                                       int thumbnail_size,
+                                                       void *request,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       // common
+       storage_error_code_t (*delete_file)(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       // common
+       storage_error_code_t (*remove_directory)(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *folder_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       // common
+       storage_error_code_t (*move_file)(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       const char *dest_parent_folder_storage_path,
+                                                       const char *new_file_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       // common
+       storage_error_code_t (*move_directory)(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *folder_name,
+                                                       const char *dest_parent_folder_storage_path,
+                                                       const char *new_folder_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       // common
+       storage_error_code_t (*set_transfer_state)(storage_adaptor_plugin_context_h context,
+                                                       void *transfer_request_id,
+                                                       storage_adaptor_transfer_state_e state,
+                                                       void *request,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       // common
+       storage_error_code_t (*get_transfer_state)(storage_adaptor_plugin_context_h context,
+                                                       void *transfer_request_id,
+                                                       void *request,
+                                                       storage_adaptor_transfer_state_e *state,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+
+       storage_error_code_t (*upload_file_async)(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       const char *upload_file_local_path,
+                                                       const int publish,
+                                                       void *request,
+                                                       void *transfer_request_id);
+
+       storage_error_code_t (*download_file_async)(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       const char *download_file_local_path,
+                                                       void *request,
+                                                       void *transfer_request_id);
+
+       storage_error_code_t (*download_file_sync_by_public_token)(storage_adaptor_plugin_context_h context,
+                                                       const char *public_token,
+                                                       const char *auth_code,
+                                                       const char *download_file_local_path,
+                                                       void *request,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*download_file_async_by_public_token)(storage_adaptor_plugin_context_h context,
+                                                       const char *public_token,
+                                                       const char *auth_code,
+                                                       const char *download_file_local_path,
+                                                       void *request,
+                                                       void *transfer_request_id);
+
+       storage_error_code_t (*get_transfer_progress)(storage_adaptor_plugin_context_h context,
+                                                       void *transfer_request_id,
+                                                       void *request,
+                                                       unsigned long long *progress_size_byte,
+                                                       unsigned long long *total_size_byte,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*set_meta)(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       const void *meta_data,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*get_meta)(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       void **meta_data,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*start_mupload)(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       const char *upload_file_local_path,
+                                                       const unsigned long long chunk_size_byte,
+                                                       void *request,
+                                                       char **mupload_key,
+                                                       int *chunk_count,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*upload_mupload)(storage_adaptor_plugin_context_h context,
+                                                       const char *mupload_key,
+                                                       const int chunk_number,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*end_mupload)(storage_adaptor_plugin_context_h context,
+                                                       const char *mupload_key,
+                                                       const int publish,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*list_mupload)(storage_adaptor_plugin_context_h context,
+                                                       const char *mupload_key,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h **file_info_list,
+                                                       int *file_info_list_len,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*cancel_mupload)(storage_adaptor_plugin_context_h context,
+                                                       const char *mupload_key,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*start_transaction)(storage_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       char **tx_key,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*upload_file_transaction)(storage_adaptor_plugin_context_h context,
+                                                       const char *tx_key,
+                                                       const int tx_seq,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       const char *upload_file_local_path,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*set_dir_transaction)(storage_adaptor_plugin_context_h context,
+                                                       const char *tx_key,
+                                                       const int tx_seq,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *folder_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*delete_file_transaction)(storage_adaptor_plugin_context_h context,
+                                                       const char *tx_key,
+                                                       const int tx_seq,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*delete_dir_transaction)(storage_adaptor_plugin_context_h context,
+                                                       const char *tx_key,
+                                                       const int tx_seq,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *folder_name,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*end_transaction)(storage_adaptor_plugin_context_h context,
+                                                       const char *tx_key,
+                                                       const int tx_count,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h **file_info_list,
+                                                       int *file_info_list_len,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*list_transaction)(storage_adaptor_plugin_context_h context,
+                                                       const char *tx_key,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h **file_info_list,
+                                                       int *file_info_list_len,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*cancel_transaction)(storage_adaptor_plugin_context_h context,
+                                                       const char *tx_key,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h **file_info_list,
+                                                       int *file_info_list_len,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*multi_file_upload)(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char **upload_file_local_path_list,
+                                                       const int upload_list_len,
+                                                       void *request,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*multi_file_download)(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name_list,
+                                                       const int file_name_list_len,
+                                                       const char *download_folder_local_path,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h **file_info_list,
+                                                       int *file_info_list_len,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*get_timestamp)(storage_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       unsigned long long *timestamp,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*get_file_info_by_public_token)(storage_adaptor_plugin_context_h context,
+                                                       const char *public_token,
+                                                       const char *auth_code,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h *file_info,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*auth_public_authcode_by_public_token)(storage_adaptor_plugin_context_h context,
+                                                       const char *public_token,
+                                                       const char *auth_code,
+                                                       void *request,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*redirect_url_by_public_token)(storage_adaptor_plugin_context_h context,
+                                                       const char *public_token,
+                                                       void *request,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*create_resuming_upload_url)(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char *file_name,
+                                                       const unsigned long long x_upload_content_length,
+                                                       void *request,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*create_resuming_chunk_upload_url)(storage_adaptor_plugin_context_h context,
+                                                       const char *mupload_key,
+                                                       const int chunk_number,
+                                                       const unsigned long long x_upload_content_length,
+                                                       void *request,
+                                                       char **rupload_key,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*resuming_upload)(storage_adaptor_plugin_context_h context,
+                                                       const char *rupload_key,
+                                                       const char *content_range,
+                                                       const unsigned long long content_length,
+                                                       void *request,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*delete_multi_file_in_folder)(storage_adaptor_plugin_context_h context,
+                                                       const char *parent_folder_storage_path,
+                                                       const char **file_name_list,
+                                                       const int file_name_list_len,
+                                                       void *request,
+                                                       storage_adaptor_file_info_h **file_info_list,
+                                                       int *file_info_list_len,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*get_policy)(storage_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       char ***allowed_extension,
+                                                       int *allowed_extension_len,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       storage_error_code_t (*get_quota)(storage_adaptor_plugin_context_h context,
+                                                       void *request,
+                                                       unsigned long long *total_usage,
+                                                       unsigned long long *total_quota,
+                                                       storage_adaptor_error_code_h *error,
+                                                       void *response);
+
+       // Optional end
+
+       // Mandatory
+       char *plugin_uri;       // get from config file
+       // Mandatory end
+
+} storage_adaptor_plugin_handle_t;
+typedef struct storage_adaptor_plugin_handle_s *storage_adaptor_plugin_handle_h;
+
+/**
+ * Callback function variable for service adaptor
+ */
+
+// private feature
+typedef void (*storage_adaptor_service_download_file_async_reply_cb)(void *transfer_request_id,
+                                               char *download_file_local_path,
+                                               storage_adaptor_error_code_h error,
+                                               void *response);
+
+typedef void (*storage_adaptor_service_upload_file_async_reply_cb)(void *transfer_request_id,
+                                               storage_adaptor_file_info_h file_info,
+                                               storage_adaptor_error_code_h error,
+                                               void *response);
+
+typedef void (*storage_adaptor_service_file_transfer_progress_reply_cb)(void *transfer_request_id,
+                                               unsigned long long progress_size_byte,
+                                               unsigned long long total_size_byte,
+                                               storage_adaptor_error_code_h error,
+                                               void *response);
+
+// public feature
+typedef void (*storage_adaptor_service_download_state_changed_reply_cb)(long long int file_descriptor,
+                                               storage_adaptor_transfer_state_e state,
+                                               storage_adaptor_error_code_h error,
+                                               void *user_data);
+
+typedef void (*storage_adaptor_service_upload_state_changed_reply_cb)(long long int file_descriptor,
+                                               storage_adaptor_transfer_state_e state,
+                                               storage_adaptor_file_info_h file_info,
+                                               storage_adaptor_error_code_h error,
+                                               void *user_data);
+
+typedef void (*storage_adaptor_service_task_progress_reply_cb)(long long int file_descriptor,
+                                               unsigned long long progress_size_byte,
+                                               unsigned long long total_size_byte);
+
+
+
+/**
+ * Storage adaptor listener for service adaptor
+ * Listener is used by service adaptor
+ */
+typedef struct storage_adaptor_listener_s
+{
+// private feature
+       void (*download_file_async_reply)(void *transfer_request_id,
+                                                       char *download_file_local_path,
+                                                       storage_adaptor_error_code_h error,
+                                                       void *response);
+
+       void (*upload_file_async_reply)(void *transfer_request_id,
+                                                       storage_adaptor_file_info_h file_info,
+                                                       storage_adaptor_error_code_h error,
+                                                       void *response);
+
+       void (*file_transfer_progress_reply)(void *transfer_request_id,
+                                                       unsigned long long progress_size_byte,
+                                                       unsigned long long total_size_byte,
+                                                       storage_adaptor_error_code_h error,
+                                                       void *response);
+
+// public feature
+       void (*download_state_changed_reply)(long long int file_descriptor,
+                                               storage_adaptor_transfer_state_e state,
+                                               storage_adaptor_error_code_h error,
+                                               void *user_data);
+
+       void (*upload_state_changed_reply)(long long int file_descriptor,
+                                               storage_adaptor_transfer_state_e state,
+                                               storage_adaptor_file_info_h file_info,
+                                               storage_adaptor_error_code_h error,
+                                               void *user_data);
+
+       void (*task_progress_reply)(long long int file_descriptor,
+                                               unsigned long long progress_size_byte,
+                                               unsigned long long total_size_byte);
+
+} storage_adaptor_listener_t;
+typedef struct storage_adaptor_listener_s *storage_adaptor_listener_h;
+
+/**
+ * Callback function variables for plugins
+ * These callbacks are expected to be support by plugins
+ */
+// private feature
+typedef void (*storage_adaptor_plugin_download_file_async_reply_cb)(void *transfer_request_id,
+                                               char *download_file_local_path,
+                                               storage_adaptor_error_code_h error,
+                                               void *response);
+
+typedef void (*storage_adaptor_plugin_upload_file_async_reply_cb)(void *transfer_request_id,
+                                               storage_adaptor_file_info_h file_info,
+                                               storage_adaptor_error_code_h error,
+                                               void *response);
+
+typedef void (*storage_adaptor_plugin_file_transfer_progress_reply_cb)(void *transfer_request_id,
+                                               unsigned long long progress_size_byte,
+                                               unsigned long long total_size_byte,
+                                               storage_adaptor_error_code_h error,
+                                               void *response);
+
+// public feature
+typedef void (*storage_adaptor_plugin_download_state_changed_reply_cb)(int file_descriptor,
+                                               storage_adaptor_transfer_state_e state,
+                                               storage_adaptor_error_code_h error,
+                                               void *user_data);
+
+typedef void (*storage_adaptor_plugin_upload_state_changed_reply_cb)(int file_descriptor,
+                                               storage_adaptor_transfer_state_e state,
+                                               storage_adaptor_file_info_h file_info,
+                                               storage_adaptor_error_code_h error,
+                                               void *user_data);
+
+typedef void (*storage_adaptor_plugin_task_progress_reply_cb)(int file_descriptor,
+                                               unsigned long long progress_size_byte,
+                                               unsigned long long total_size_byte,
+                                               storage_adaptor_error_code_h error,
+                                               void *user_data);
+
+/**
+ * Storage adaptor listener for plugins
+ * Listener is used by plugins
+ */
+typedef struct storage_adaptor_plugin_listener_s
+{
+// private feature
+       storage_adaptor_plugin_download_file_async_reply_cb     storage_adaptor_download_file_async_reply;
+       storage_adaptor_plugin_upload_file_async_reply_cb       storage_adaptor_upload_file_async_reply;
+       storage_adaptor_plugin_file_transfer_progress_reply_cb  storage_adaptor_file_transfer_progress_reply;
+
+// public feature
+       storage_adaptor_plugin_download_state_changed_reply_cb  storage_adaptor_download_state_changed_reply;
+       storage_adaptor_plugin_upload_state_changed_reply_cb    storage_adaptor_upload_state_changed_reply;
+       storage_adaptor_plugin_task_progress_reply_cb   storage_adaptor_task_progress_reply;
+} storage_adaptor_plugin_listener_t;
+
+/**
+ * Loads plugin from selected path
+ */
+int storage_adaptor_load_plugin(storage_adaptor_h,
+                                               const char *plugin_path);
+
+// For 3rd party plugin packages
+int storage_adaptor_load_plugin_from_package(storage_adaptor_h adaptor,
+                                               const char *package_id,
+                                               const char *plugin_path);
+
+/**
+ * Unloads selected plugin
+ */
+int storage_adaptor_unload_plugin(storage_adaptor_h,
+                                               storage_adaptor_plugin_h);
+
+/**
+ * Gets plugin name
+ */
+void storage_adaptor_get_plugin_uri(storage_adaptor_plugin_h plugin,
+                                               char **plugin_uri);
+
+/**
+ * Refresh access token
+ */
+EXPORT_API
+storage_error_code_t storage_adaptor_refresh_access_token(storage_adaptor_plugin_context_h context,
+                                               const char *new_access_token);
+
+/**
+ * Refresh access token
+ */
+EXPORT_API
+storage_error_code_t storage_adaptor_refresh_uid(storage_adaptor_plugin_context_h context,
+                                               const char *new_uid);
+
+/**
+ * Create error code
+ */
+EXPORT_API
+storage_adaptor_error_code_h storage_adaptor_create_error_code(const int64_t code,
+                                               const char *msg);
+
+/**
+ * Destroy error code
+ */
+EXPORT_API
+void storage_adaptor_destroy_error_code(storage_adaptor_error_code_h *error_code);
+
+/**
+ * Creates storage adaptor
+ */
+EXPORT_API
+storage_adaptor_h storage_adaptor_create(const char *plugins_dir);
+
+/**
+ * Destroys storage adaptor
+ * Destroys storage adaptor. If storage adaptor was started it is stopped first.
+ */
+EXPORT_API
+void storage_adaptor_destroy(storage_adaptor_h adaptor);
+
+/**
+ * Starts storage adaptor
+ * Starts storage adaptor and loads plugins that were found in plugins search dir
+ * specified in storage_adaptor_create
+ */
+EXPORT_API
+int storage_adaptor_start(storage_adaptor_h adaptor);
+
+/**
+ * Stops storage adaptor.
+ */
+EXPORT_API
+int storage_adaptor_stop(storage_adaptor_h adaptor);
+
+/**
+ * Registers plugin state listener
+ */
+EXPORT_API
+int storage_adaptor_register_listener(storage_adaptor_h,
+                                               storage_adaptor_listener_h);
+
+/**
+ * Unregisters plugin state listener
+ */
+EXPORT_API
+int storage_adaptor_unregister_listener(storage_adaptor_h,
+                                               storage_adaptor_listener_h);
+
+/**
+ * Creates plugin context.
+ */
+EXPORT_API
+storage_adaptor_plugin_context_h storage_adaptor_create_plugin_context(storage_adaptor_plugin_h plugin,
+                                               const char *app_id,
+                                               const char *app_secret,
+                                               const char *access_token,
+                                               const char *cid,
+                                               const char *uid,
+                                               const char *service_name);
+
+/**
+ * Destroys plugin context.
+ */
+EXPORT_API
+void storage_adaptor_destroy_plugin_context(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h);
+
+/**
+ * Gets plugin with specified unique name
+ */
+EXPORT_API
+storage_adaptor_plugin_h storage_adaptor_get_plugin_by_name(storage_adaptor_h adaptor,
+                                               const char *plugin_uri);
+
+/**
+ * Gets plugins
+ */
+EXPORT_API
+GList *storage_adaptor_get_plugins(storage_adaptor_h adaptor);
+
+////////////////////////////////////////////////////////////
+// Adaptor Util Functions
+////////////////////////////////////////////////////////////
+EXPORT_API
+storage_adaptor_file_info_h storage_adaptor_create_file_info(void);
+
+EXPORT_API
+int storage_adaptor_destroy_file_info(storage_adaptor_file_info_h *file_info);
+
+
+////////////////////////////////////////////////////////////
+// Adaptor Plugin call Functions
+////////////////////////////////////////////////////////////
+
+
+EXPORT_API
+storage_error_code_t storage_adaptor_open_file(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *file_path,
+                                               storage_adaptor_file_access_mode_e mode,
+                                               long long int *file_uid,
+                                               storage_adaptor_error_code_h *error);
+
+EXPORT_API
+storage_error_code_t storage_adaptor_close_file(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               long long int file_uid,
+                                               storage_adaptor_error_code_h *error);
+
+EXPORT_API
+storage_error_code_t storage_adaptor_start_upload_task(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               long long int src_file_descriptor,              // read only opened
+                                               const char *upload_dir_path,
+                                               const char *file_name,
+                                               bool need_progress,
+                                               storage_adaptor_error_code_h *error,
+                                               void *user_data);
+
+EXPORT_API
+storage_error_code_t storage_adaptor_start_download_task(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *storage_dir_path,
+                                               const char *file_name,
+                                               long long int dst_file_descriptor,              // write only opened
+                                               bool need_progress,
+                                               storage_adaptor_error_code_h *error,
+                                               void *user_data);
+
+EXPORT_API
+storage_error_code_t storage_adaptor_start_download_thumb_task(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *storage_dir_path,
+                                               const char *file_name,
+                                               long long int dst_file_descriptor,              // write only opened
+                                               int thumbnail_size,                     // level (defined plugin SPEC)
+                                               bool need_progress,
+                                               storage_adaptor_error_code_h *error,
+                                               void *user_data);
+
+EXPORT_API
+storage_error_code_t storage_adaptor_cancel_upload_task(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               long long int file_uid,
+                                               storage_adaptor_error_code_h *error);
+
+EXPORT_API
+storage_error_code_t storage_adaptor_cancel_download_task(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               long long int file_uid,
+                                               storage_adaptor_error_code_h *error);
+
+EXPORT_API
+storage_error_code_t storage_adaptor_cancel_download_thumb_task(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               long long int file_uid,
+                                               storage_adaptor_error_code_h *error);
+
+/**
+* @brief Set server information for Storage Plugin
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   server_info                     specifies server information for Storage Plugin
+* @param[in]   request                         specifies optional parameter
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_set_server_info(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               GHashTable *server_info,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Makes a directory at cloud
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   parent_folder_storage_path      specifies path to locate the folder you want to create
+* @param[in]   folder_name                     specifies folder name to be created at cloud
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info                       specifies Storage Adaptor File Info handle
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_make_directory(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *folder_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Removes a directory at cloud
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   parent_folder_storage_path      specifies parent folder path of folder you want to delete
+* @param[in]   folder_name                     specifies folder name to be deleted from cloud
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info                       specifies Storage Adaptor File Info handle
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_remove_directory(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *folder_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Requests folder and file list in a folder
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   parent_folder_storage_path      specifies parent folder path of folder you want to get list
+* @param[in]   folder_name                     specifies folder name you want to get list
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info_list                  specifies Storage Adaptor File Info handle
+* @param[out]  file_info_list_len              specifies length of the file_info_list
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_list(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *folder_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h **file_info_list,
+                                               int *file_info_list_len,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Uploads a file to cloud (Sync)
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   parent_folder_storage_path      specifies folder path of file you want to upload
+* @param[in]   file_name                       specifies file name to be uploaded to cloud
+* @param[in]   upload_file_local_path          specifies local path of the file to be uploaded
+* @param[in]   publish                         specifies Allow to share file with no authentication
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info                       specifies Storage Adaptor File Info handle
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_upload_file_sync(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               const char *upload_file_local_path,
+                                               const int publish,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Uploads a file to cloud (Async)
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   parent_folder_storage_path      specifies folder path of file you want to upload
+* @param[in]   file_name                       specifies file name to be uploaded to cloud
+* @param[in]   upload_file_local_path          specifies local path of the file to be uploaded
+* @param[in]   publish                         specifies Allow to share file with no authentication
+* @param[in]   request                         specifies optional parameter
+* @param[out]  transfer_request_id             specifies
+* @param[out]  error                           specifies error code
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_upload_file_async(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               const char *upload_file_local_path,
+                                               const int publish,
+                                               void *request,
+                                               void *transfer_request_id,
+                                               storage_adaptor_error_code_h *error);
+
+/**
+* @brief Downloads a file to local (Sync)
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   parent_folder_storage_path      specifies folder path of file you want to download
+* @param[in]   file_name                       specifies file name to be downloaded to local
+* @param[in]   download_file_local_path        specifies local path to download
+* @param[in]   request                         specifies optional parameter
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_download_file_sync(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               const char *download_file_local_path,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Downloads a file to local (Async)
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   parent_folder_storage_path      specifies folder path of file you want to download
+* @param[in]   file_name                       specifies file name to be downloaded to local
+* @param[in]   download_file_local_path        specifies local path to download
+* @param[in]   request                         specifies optional parameter
+* @param[out]  transfer_request_id             specifies
+* @param[out]  error                           specifies error code
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_download_file_async(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               const char *download_file_local_path,
+                                               void *request,
+                                               void *transfer_request_id,
+                                               storage_adaptor_error_code_h *error);
+
+/**
+* @brief Downloads a thumbnail to local (Sync)
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   parent_folder_storage_path      specifies folder path of file you want to download
+* @param[in]   file_name                       specifies file name to be downloaded to local
+* @param[in]   download_file_local_path        specifies local path to download
+* @param[in]   thumbnail_size                  specifies thumbnail_size
+* @param[in]   request                         specifies optional parameter
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_download_thumbnail(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *folder_path,
+                                               const char *file_name,
+                                               const char *download_path,
+                                               int thumbnail_size,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Removes a file at cloud
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   parent_folder_storage_path      specifies folder path of file you want to delete
+* @param[in]   file_name                       specifies file name to be deleted from cloud
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info                       specifies Storage Adaptor File Info handle
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_delete_file(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Sets metadata of file at cloud
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   parent_folder_storage_path      specifies folder path of file you want to set meta data
+* @param[in]   file_name                       specifies file name to be updated meta data
+* @param[in]   meta_data                       specifies meta data (A pair of Key, Value)
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info                       specifies Storage Adaptor File Info handle
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_set_meta(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               const void *meta_data,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Gets metatdata of file at cloud
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   parent_folder_storage_path      specifies folder path of file you want to get meta data
+* @param[in]   file_name                       specifies file name
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info                       specifies Storage Adaptor File Info handle
+* @param[out]  meta_data                       specifies meta data (A pair of Key, Value)
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_get_meta(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               void **meta_data,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Set up Multi Channel Upload
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   parent_folder_storage_path      specifies folder path of file you want to upload
+* @param[in]   file_name                       specifies file name to be uploaded to cloud
+* @param[in]   upload_file_local_path          specifies local path of the file to be uploaded
+* @param[in]   chunk_size_byte                 specifies size of chunk
+* @param[in]   request                         specifies optional parameter
+* @param[out]  mupload_key                     specifies Multi Channel Upload key
+* @param[out]  chunk_count                     specifies total number of chunks
+* @param[out]  file_info                       specifies Storage Adaptor File Info handle
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_start_mupload(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               const char *upload_file_local_path,
+                                               const unsigned long long chunk_size_byte,
+                                               void *request,
+                                               char **mupload_key,
+                                               int *chunk_count,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Uploads a chunk to cloud
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   mupload_key                     specifies Multi Channel Upload key
+* @param[in]   chunk_number                    specifies number of chunk (Starting at 1)
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info                       specifies Storage Adaptor File Info handle
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_upload_mupload(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *mupload_key,
+                                               const int chunk_number,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Ends Multi channel Upload
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   mupload_key                     specifies Multi Channel Upload key
+* @param[in]   publish                         specifies Allow to share file with no authentication
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info                       specifies Storage Adaptor File Info handle
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_end_mupload(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *mupload_key,
+                                               const int publish,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Requests list of chunks uploaded
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   mupload_key                     specifies Multi Channel Upload key
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info_list                  specifies Storage Adaptor File Info handle
+* @param[out]  file_info_list_len              specifies length of the file_info_list
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_list_mupload(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *mupload_key,
+                                               void *request,
+                                               storage_adaptor_file_info_h **file_info_list,
+                                               int *file_info_list_len,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Cancels all operations
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   mupload_key                     specifies Multi Channel Upload key
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info                       specifies Storage Adaptor File Info handle
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_cancel_mupload(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *mupload_key,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Starts Transaction
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   request                         specifies optional parameter
+* @param[out]  tx_key                          specifies Transaction key
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_start_transaction(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               void *request,
+                                               char **tx_key,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Uploads a file
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   tx_key                          specifies Transaction key
+* @param[in]   tx_seq                          specifies Transaction sequesnce (Starting at 1)
+* @param[in]   parent_folder_storage_path      specifies folder path of file you want to upload
+* @param[in]   file_name                       specifies file name to be uploaded to cloud
+* @param[in]    upload_file_local_path          specifies local path of the file to be uploaded
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info                       specifies Storage Adaptor File Info handle
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_upload_file_transaction(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *tx_key,
+                                               const int tx_seq,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               const char *upload_file_local_path,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Updates a folder
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   tx_key                          specifies Transaction key
+* @param[in]   tx_seq                          specifies Transaction sequesnce (Starting at 1)
+* @param[in]   parent_folder_storage_path      specifies folder path of folder you want to update
+* @param[in]   folder_name                     specifies folder name to be updated
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info                       specifies Storage Adaptor File Info handle
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_set_dir_transaction(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *tx_key,
+                                               const int tx_seq,
+                                               const char *parent_folder_storage_path,
+                                               const char *folder_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Removes a file
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   tx_key                          specifies Transaction key
+* @param[in]   tx_seq                          specifies Transaction sequesnce (Starting at 1)
+* @param[in]   parent_folder_storage_path      specifies folder path of file you want to delete
+* @param[in]   file_name                       specifies file name to be deleted from cloud
+* @param[in]   request                         specifies optional parameter
+* @param[in]    upload_file_local_path          specifies local path of the file to be uploaded
+* @param[out]  file_info                       specifies Storage Adaptor File Info handle
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_delete_file_transaction(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *tx_key,
+                                               const int tx_seq,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Removes a folder
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   tx_key                          specifies Transaction key
+* @param[in]   tx_seq                          specifies Transaction sequesnce (Starting at 1)
+* @param[in]   parent_folder_storage_path      specifies folder path of folder you want to delete
+* @param[in]   folder_name                     specifies folder name to be deleted
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info                       specifies Storage Adaptor File Info handle
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_delete_dir_transaction(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *tx_key,
+                                               const int tx_seq,
+                                               const char *parent_folder_storage_path,
+                                               const char *folder_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Ends Transaction
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   tx_key                          specifies Transaction key
+* @param[in]   tx_count                        specifies Transaction order count
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info_list                  specifies Storage Adaptor File Info handle
+* @param[out]  file_info_list_len              specifies length of the file_info_list
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_end_transaction(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *tx_key,
+                                               const int tx_count,
+                                               void *request,
+                                               storage_adaptor_file_info_h **file_info_list,
+                                               int *file_info_list_len,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Requests Transaction list
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   tx_key                          specifies Transaction key
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info_list                  specifies Storage Adaptor File Info handle
+* @param[out]  file_info_list_len              specifies length of the file_info_list
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_list_transaction(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *tx_key,
+                                               void *request,
+                                               storage_adaptor_file_info_h **file_info_list,
+                                               int *file_info_list_len,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Cancels all transactions
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   tx_key                          specifies Transaction key
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info_list                  specifies Storage Adaptor File Info handle
+* @param[out]  file_info_list_len              specifies length of the file_info_list
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_cancel_transaction(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *tx_key,
+                                               void *request,
+                                               storage_adaptor_file_info_h **file_info_list,
+                                               int *file_info_list_len,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Uploads multiple files to cloud
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   parent_folder_storage_path      specifies folder path of files you want to upload
+* @param[in]   upload_file_local_path_list     specifies local path list of the files to be uploaded
+* @param[in]   upload_list_len                 specifies total number of files to be uploaded
+* @param[in]   request                         specifies optional parameter
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_multi_file_upload(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char **upload_file_local_path_list,
+                                               const int upload_list_len,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Downloads multiple files in a folder
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   parent_folder_storage_path      specifies folder path of files you want to download
+* @param[in]   file_name_list                  specifies file name list to be downloaded
+* @param[in]   file_name_list_len              specifies total number of files to be downloaded
+* @param[in]   download_folder_local_path      specifies local folder path to download files
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info_list                  specifies Storage Adaptor File Info handle
+* @param[out]  file_info_list_len              specifies length of the file_info_list
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_multi_file_download(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name_list,
+                                               const int file_name_list_len,
+                                               const char *download_folder_local_path,
+                                               void *request,
+                                               storage_adaptor_file_info_h **file_info_list,
+                                               int *file_info_list_len,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Requests current server timestamp
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   request                         specifies optional parameter
+* @param[out]  timestamp                       specifies server timestamp
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_get_timestamp(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               void *request,
+                                               unsigned long long *timestamp,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Requests a file info by public token
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   public_token                    specifies token for Download, Get API
+                                               (when terminal upload file and add publish=true parameter, ors return public_token)
+* @param[in]   auth_code                       specifies Authentication code for public APIs
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info                       specifies Storage Adaptor File Info handle
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_get_file_info_by_public_token(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *public_token,
+                                               const char *auth_code,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Downloads a file by public token (Sync)
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   public_token                    specifies token for Download, Get API
+                                               (when terminal upload file and add publish=true parameter, ors return public_token)
+* @param[in]   auth_code                       specifies Authentication code for public APIs
+* @param[in]   download_file_local_path        specifies local path to download
+* @param[in]   request                         specifies optional parameter
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_download_file_sync_by_public_token(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *public_token,
+                                               const char *auth_code,
+                                               const char *download_file_local_path,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Downloads a file by public token (Async)
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   public_token                    specifies token for Download, Get API
+                                               (when terminal upload file and add publish=true parameter, ors return public_token)
+* @param[in]   auth_code                       specifies Authentication code for public APIs
+* @param[in]   download_file_local_path        specifies local path to download
+* @param[in]   request                         specifies optional parameter
+* @param[out]  transfer_request_id             specifies
+* @param[out]  error                           specifies error code
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_download_file_async_by_public_token(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *public_token,
+                                               const char *auth_code,
+                                               const char *download_file_local_path,
+                                               void *request,
+                                               void *transfer_request_id,
+                                               storage_adaptor_error_code_h *error);
+
+/**
+* @brief Authenticates public auth code
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   public_token                    specifies token for Download, Get API
+                                               (when terminal upload file and add publish=true parameter, ors return public_token)
+* @param[in]   auth_code                       specifies Authentication code for public APIs
+* @param[in]   request                         specifies optional parameter
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_auth_public_authcode_by_public_token(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *public_token,
+                                               const char *auth_code,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Removes multiple files in a folder
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   parent_folder_storage_path      specifies folder path of files you want to delete
+* @param[in]   file_name_list                  specifies file name list to be deleted
+* @param[in]   file_name_list_len              specifies total number of files to be deleted
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info_list                  specifies Storage Adaptor File Info handle
+* @param[out]  file_info_list_len              specifies length of the file_info_list
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_delete_multi_file_in_folder(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char **file_name_list,
+                                               const int file_name_list_len,
+                                               void *request,
+                                               storage_adaptor_file_info_h **file_info_list,
+                                               int *file_info_list_len,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Requests policy for upload
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   request                         specifies optional parameter
+* @param[out]  allowed_extension               specifies
+* @param[out]  allowed_extension_len           specifies length of allowed_extension
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_get_policy(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               void *request,
+                                               char ***allowed_extension,
+                                               int *allowed_extension_len,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Requests quota of user
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   request                         specifies optional parameter
+* @param[out]  total_usage                     specifies total usage of user
+* @param[out]  total_quota                     specifies total quota of user
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_get_quota(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               void *request,
+                                               unsigned long long *total_usage,
+                                               unsigned long long *total_quota,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Requests Redirect URL mapped with public token (Not yet supported)
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   public_token                    specifies token for Download, Get API
+                                               (when terminal upload file and add publish=true parameter, ors return public_token)
+* @param[in]   request                         specifies optional parameter
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_redirect_url_by_public_token(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *public_token,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Creates Upload URL (Not yet supported)
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   parent_folder_storage_path      specifies folder path of files you want to upload
+* @param[in]   file_name                       specifies file name to be uploaded
+* @param[in]   x_upload_content_length         specifies length of content
+* @param[in]   request                         specifies optional parameter
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_create_resuming_upload_url(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               const unsigned long long x_upload_content_length,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Creates chunk Upload URL (Not yet supported)
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   mupload_key                     specifies Multi Channel Upload key
+* @param[in]   chunk_number                    specifies number of chunk (Starting at 1)
+* @param[in]   x_upload_content_length         specifies length of content
+* @param[in]   request                         specifies optional parameter
+* @param[out]  rupload_key                     specifies Resuming Upload key
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_create_resuming_chunk_upload_url(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *mupload_key,
+                                               const int chunk_number,
+                                               const unsigned long long x_upload_content_length,
+                                               void *request,
+                                               char **rupload_key,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Resumes Upload (Not yet supported)
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   rupload_key                     specifies Resuming Upload key
+* @param[in]   content_range                   specifies range of content
+* @param[in]   content_length                  specifies length of content
+* @param[in]   request                         specifies optional parameter
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_resuming_upload(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *rupload_key,
+                                               const char *content_range,
+                                               const unsigned long long content_length,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Move a folder into destination folder
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   parent_folder_storage_path      specifies parent folder path of folder you want to move
+* @param[in]   folder_name                     specifies folder name to be moved
+* @param[in]   dest_parent_folder_storage_path specifies new parent folder path
+* @param[in]   new_folder_name                 specifies new folder name
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info                       specifies Storage Adaptor File Info handle
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_move_directory(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *folder_name,
+                                               const char *dest_parent_folder_storage_path,
+                                               const char *new_folder_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Move a file into destination folder
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   parent_folder_storage_path      specifies folder path of file you want to move
+* @param[in]   file_name                       specifies file name to be moved
+* @param[in]   dest_parent_folder_storage_path specifies new folder path
+* @param[in]   new_file_name                   specifies new file name
+* @param[in]   request                         specifies optional parameter
+* @param[out]  file_info                       specifies Storage Adaptor File Info handle
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_move_file(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               const char *parent_folder_storage_path,
+                                               const char *file_name,
+                                               const char *dest_parent_folder_storage_path,
+                                               const char *new_file_name,
+                                               void *request,
+                                               storage_adaptor_file_info_h *file_info,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Get progress of file transfer request
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    transfer_request_id             specifies unique id for file transfer request
+* @param[in]    request                         specifies optional parameter
+* @param[out]   progress_size                   specifies current progress size
+* @param[out]   total_size                      specifies total size to transfer
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_get_transfer_progress(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               void *transfer_request_id,
+                                               void *request,
+                                               unsigned long long *progress_size_byte,
+                                               unsigned long long *total_size_byte,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Get state of file transfer request
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    transfer_request_id             specifies unique id for file transfer request
+* @param[in]    request                         specifies optional parameter
+* @param[out]   state                          specifies current state of transfer request
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_get_transfer_state(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               void *transfer_request_id,
+                                               void *request,
+                                               storage_adaptor_transfer_state_e *state,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Set state of file transfer request
+*
+* @param[in]    plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]    context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]    transfer_request_id             specifies unique id for file transfer request
+* @param[in]    state                          specifies state to set
+* @param[in]    request                         specifies optional parameter
+* @param[out]   error                           specifies error code
+* @param[out]   response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_set_transfer_state(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               void *transfer_request_id,
+                                               storage_adaptor_transfer_state_e state,
+                                               void *request,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+/**
+* @brief Requests root folder path
+*
+* @param[in]   plugin                          specifies Storage Adaptor Plugin handle
+* @param[in]   context                         specifies Storage Adaptor Plugin Context handle
+* @param[in]   request                         specifies optional parameter
+* @param[out]  root_folder_path        specifies root folder path
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in storage_error_code_t - STORAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+storage_error_code_t storage_adaptor_get_root_folder_path(storage_adaptor_plugin_h plugin,
+                                               storage_adaptor_plugin_context_h context,
+                                               void *request,
+                                               char **root_folder_path,
+                                               storage_adaptor_error_code_h *error,
+                                               void *response);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STORAGE_ADAPTOR_H__ */
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
new file mode 100644 (file)
index 0000000..40d588a
--- /dev/null
@@ -0,0 +1,49 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(sal-common)
+
+SET(CMAKE_SKIP_BUILD_RPATH TRUE)
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+        SET(CMAKE_BUILD_TYPE "Debug")
+ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+
+MESSAGE("")
+MESSAGE(">>> current directory: ${CMAKE_CURRENT_SOURCE_DIR}")
+MESSAGE(">>> Build type: ${CMAKE_BUILD_TYPE}")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${VISIBILITY} -fvisibility=hidden")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,--gc-sections")
+
+ADD_DEFINITIONS("-DSERVICE_ADAPTOR_DEBUGGING")
+
+##########################################################
+# Define common base
+##########################################################
+
+SET(PLUGIN-CONFIG-LIB "plugin-config")
+SET(PLUGIN-CONFIG-SRCS
+        ${CMAKE_SOURCE_DIR}/common/plugin_config/plugin_message.c
+)
+
+INCLUDE_DIRECTORIES(
+        ${CMAKE_SOURCE_DIR}/common/plugin_config
+)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(plugin_config_pkgs REQUIRED dlog glib-2.0 gio-2.0 gobject-2.0 json-glib-1.0)
+
+FOREACH(flag ${plugin_config_pkgs_CFLAGS})
+        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -std=gnu99")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+
+ADD_LIBRARY(${PLUGIN-CONFIG-LIB} SHARED ${PLUGIN-CONFIG-SRCS})
+TARGET_LINK_LIBRARIES(${PLUGIN-CONFIG-LIB} ${plugin_config_pkgs_LDFLAGS})
+SET_TARGET_PROPERTIES(${PLUGIN-CONFIG-LIB} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${PLUGIN-CONFIG-LIB} PROPERTIES VERSION ${VERSION})
+
+INSTALL(TARGETS ${PLUGIN-CONFIG-LIB} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
+
diff --git a/common/plugin_config/libservice_plugin_log.h b/common/plugin_config/libservice_plugin_log.h
new file mode 100644 (file)
index 0000000..809c32b
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+* Copyright (c) 2011 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 __LIB_SERVICE_PLUGIN_LOG_H__
+#define __LIB_SERVICE_PLUGIN_LOG_H__
+
+/**
+ *  HOW TO USE IT:
+ *  First you need to set platform logging on the device:
+ *
+ *    # dlogctrl set platformlog 1
+ *
+ *  After reboot you are able to see logs from this application, when you launch dlogutil with a proper filter e.g.:
+ *
+ *    # dlogutil HELLO_WORLD_TEMP:D
+ *
+ *  You may use different logging levels as: D (debug), I (info), W (warning), E (error) or F (fatal).
+ *  Higher level messages are included by default e.g. dlogutil CLOUDBOX:W prints warnings but also errors and fatal messages.
+ */
+
+#include <unistd.h>
+#include <linux/unistd.h>
+
+/* These defines must be located before #include <dlog.h> */
+#define TIZEN_ENGINEER_MODE
+// TODO: Investigate why this macro is defined somewhere else
+#ifndef TIZEN_DEBUG_ENABLE
+#define TIZEN_DEBUG_ENABLE
+#endif
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+/* Literal to filter logs from dlogutil */
+#define LOG_TAG "LIBSERVICE_PLUGIN"
+
+#include <dlog.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+       /**
+        *  Colors of font
+        */
+#define FONT_COLOR_RESET      "\033[0m"
+#define FONT_COLOR_BLACK      "\033[30m"             /* Black */
+#define FONT_COLOR_RED        "\033[31m"             /* Red */
+#define FONT_COLOR_GREEN      "\033[32m"             /* Green */
+#define FONT_COLOR_YELLOW     "\033[33m"             /* Yellow */
+#define FONT_COLOR_BLUE       "\033[34m"             /* Blue */
+#define FONT_COLOR_PURPLE     "\033[35m"             /* Purple */
+#define FONT_COLOR_CYAN       "\033[36m"             /* Cyan */
+#define FONT_COLOR_WHITE      "\033[37m"             /* White */
+#define FONT_COLOR_BOLDBLACK  "\033[1m\033[30m"      /* Bold Black */
+#define FONT_COLOR_BOLDRED    "\033[1m\033[31m"      /* Bold Red */
+#define FONT_COLOR_BOLDGREEN  "\033[1m\033[32m"      /* Bold Green */
+#define FONT_COLOR_BOLDYELLOW "\033[1m\033[33m"      /* Bold Yellow */
+#define FONT_COLOR_BOLDBLUE   "\033[1m\033[34m"      /* Bold Blue */
+#define FONT_COLOR_BOLDPURPLE "\033[1m\033[35m"      /* Bold Purple */
+#define FONT_COLOR_BOLDCYAN   "\033[1m\033[36m"      /* Bold Cyan */
+#define FONT_COLOR_BOLDWHITE  "\033[1m\033[37m"      /* Bold White */
+
+       /**
+        *  Gets thread ID
+        */
+#define LSP_LOG_gettid() syscall(__NR_gettid)
+
+/**
+ *  @brief Macro for returning value if expression is satisfied
+ *  @param[in]  expr Expression to be checked
+ *  @param[out] val  Value to be returned when expression is true
+ */
+#define LSP_LOG_retv_if(expr, val) do { \
+            if(expr) { \
+                LOGE(FONT_COLOR_PURPLE"[%d]"FONT_COLOR_RESET, LSP_LOG_gettid());    \
+                return (val); \
+            } \
+        } while (0)
+
+/**
+ * @brief Prints debug messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define LSP_LOG_debug(fmt, arg...) do { \
+            LOGD(FONT_COLOR_GREEN"[%d]"fmt""FONT_COLOR_RESET, LSP_LOG_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints info messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define LSP_LOG_info(fmt, arg...) do { \
+            LOGI(FONT_COLOR_BLUE"[%d]"fmt""FONT_COLOR_RESET, LSP_LOG_gettid() ,##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints warning messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define LSP_LOG_warning(fmt, arg...) do { \
+            LOGW(FONT_COLOR_YELLOW"[%d]"fmt""FONT_COLOR_RESET,LSP_LOG_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints error messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define LSP_LOG_error(fmt, arg...) do { \
+            LOGE(FONT_COLOR_RED"[%d]"fmt""FONT_COLOR_RESET,LSP_LOG_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints fatal messages
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define LSP_LOG_fatal(fmt, arg...) do { \
+            LOGF(FONT_COLOR_BOLDRED"[%d]"fmt""FONT_COLOR_RESET,LSP_LOG_gettid(), ##arg);     \
+        } while (0)
+
+/**
+ * @brief Prints debug message on entry to particular function
+ * @param[in]  fmt  Format of data to be displayed
+ * @param[in]  args Arguments to be displayed
+ */
+#define LSP_LOG_debug_func(fmt, arg...) do { \
+            LOGD(FONT_COLOR_CYAN"[%d]"fmt""FONT_COLOR_RESET, LSP_LOG_gettid(), ##arg);     \
+        } while (0)
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __LIB_SERVICE_PLUGIN_LOG_H__ */
diff --git a/common/plugin_config/plugin_message.c b/common/plugin_config/plugin_message.c
new file mode 100644 (file)
index 0000000..b543d97
--- /dev/null
@@ -0,0 +1,1257 @@
+/*
+* Copyright (c) 2011 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.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <glib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <glib-unix.h>
+#include <glib-object.h>
+
+#include "libservice_plugin_log.h"
+#include <plugin_message.h>
+#include <json-glib/json-glib.h>
+
+/*     For debug */
+/*#define CONSOLE_MODE */
+
+#ifdef CONSOLE_MODE
+#define PRINT_LOG printf
+#else
+#define PRINT_LOG LSP_LOG_debug
+#endif
+
+#define FUNC_START() do {PRINT_LOG("\033[1m\033[32m""Start >>%s>>\n""\033[0m", __FUNCTION__); } while (0)
+#define FUNC_END() do {PRINT_LOG("\033[1m\033[36m""End <<%s<<\n""\033[0m", __FUNCTION__); } while (0)
+
+
+#define PLUGIN_MESSAGE_ELEMENT_KEY_CONTEXT_ID          "ctx_id"
+#define PLUGIN_MESSAGE_ELEMENT_KEY_FUNCTION_NAME       "func_id"
+#define PLUGIN_MESSAGE_ELEMENT_KEY_PARAMETER_MANDATORY "man_param"
+#define PLUGIN_MESSAGE_ELEMENT_KEY_PARAMETER_OPTIONAL  "opt_param"
+#define PLUGIN_MESSAGE_ELEMENT_KEY_REQUEST_ID          "req_id"
+#define PLUGIN_MESSAGE_ELEMENT_KEY_MESSAGE_TYPE                "msg_id"
+#define PLUGIN_MESSAGE_ELEMENT_KEY_RESULT_CODE         "rcode"
+#define PLUGIN_MESSAGE_ELEMENT_KEY_RESULT_MESSAGE      "rmsg"
+
+
+#define SUCCESS 0
+#define FAIL -1
+
+#define PLUGIN_PARAMETER_BUF_SIZE_MAX 10
+
+#define JSON_EMPTY_NODE_FILL_NULL(node)                do {if (0 == json_node_get_value_type((node))) { \
+                                                       json_node_free((node)); \
+                                                       (node) = NULL; \
+                                                       (node) = json_node_new(JSON_NODE_NULL); } } while (0)
+
+
+struct _plugin_message_s {
+       JsonNode *context;
+       JsonNode *function;
+       JsonNode *parameter_mandatory;
+       JsonNode *parameter_optional;
+       JsonNode *request_id;
+       JsonNode *message_type;
+       JsonNode *rcode;
+       JsonNode *rmsg;
+};
+
+struct _plugin_message_array_s {
+       JsonArray *element;
+       plugin_data_type *types;
+};
+
+int plugin_message_create(plugin_message_h *message)
+{
+       FUNC_START();
+       if (NULL != message) {
+               plugin_message_h _msg = (plugin_message_h) calloc(1, sizeof(struct _plugin_message_s));
+               if (NULL != _msg) {
+                       _msg->context                   = json_node_new(JSON_NODE_VALUE);
+                       _msg->function                  = json_node_new(JSON_NODE_VALUE);
+                       _msg->parameter_mandatory       = json_node_new(JSON_NODE_OBJECT);
+                       _msg->parameter_optional        = json_node_new(JSON_NODE_OBJECT);
+                       _msg->request_id                = json_node_new(JSON_NODE_VALUE);
+                       _msg->message_type              = json_node_new(JSON_NODE_VALUE);
+                       _msg->rcode                     = json_node_new(JSON_NODE_VALUE);
+                       _msg->rmsg                      = json_node_new(JSON_NODE_VALUE);
+
+                       json_node_set_object(_msg->parameter_mandatory, json_object_new());
+                       json_node_set_object(_msg->parameter_optional, json_object_new());
+
+                       *message = _msg;
+
+                       FUNC_END();
+                       return SUCCESS;
+               }
+               FUNC_END();
+       }
+       return FAIL;
+}
+
+void plugin_message_destroy(plugin_message_h message)
+{
+       FUNC_START();
+       if (NULL != message) {
+               json_node_free(message->context);
+               json_node_free(message->function);
+               json_node_free(message->parameter_mandatory);
+               json_node_free(message->parameter_optional);
+               json_node_free(message->request_id);
+               json_node_free(message->message_type);
+               json_node_free(message->rcode);
+               json_node_free(message->rmsg);
+
+               free(message);
+       }
+       FUNC_END();
+}
+
+/*
+int plugin_message_set_value_int(plugin_message_h message, plugin_message_element_e field, int value)
+{
+       if (NULL == message)
+       {
+               return FAIL;
+       }
+
+       switch (field)
+       {
+       case PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID:
+               json_node_set_int(message->context, (gint64)value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME:
+               json_node_set_int(message->function, (gint64)value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_REQUEST_ID:
+               json_node_set_int(message->request_id, (gint64)value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE:
+               json_node_set_int(message->message_type, (gint64)value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_RESULT_CODE:
+               json_node_set_int(message->rcode, (gint64)value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE:
+               json_node_set_int(message->rmsg, (gint64)value);
+               break;
+       default:
+               return FAIL;
+       }
+
+       return SUCCESS;
+}
+
+int plugin_message_get_value_int(plugin_message_h message, plugin_message_element_e field, int *value)
+{
+       if ((NULL == message) || (NULL == value))
+       {
+               return FAIL;
+       }
+
+       switch (field)
+       {
+       case PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID:
+               *value = (int)json_node_get_int(message->context);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME:
+               *value = (int)json_node_get_int(message->function);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_REQUEST_ID:
+               *value = (int)json_node_get_int(message->request_id);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE:
+               *value = (int)json_node_get_int(message->message_type);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_RESULT_CODE:
+               *value = (int)json_node_get_int(message->rcode);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE:
+               *value = (int)json_node_get_int(message->rmsg);
+               break;
+       default:
+               return FAIL;
+       }
+
+       return SUCCESS;
+}
+*/
+
+int plugin_message_set_value_number(plugin_message_h message, plugin_message_element_e field, pmnumber value)
+{
+       FUNC_START();
+       if (NULL == message) {
+               return FAIL;
+       }
+
+       switch (field) {
+       case PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID:
+               json_node_set_int(message->context, (gint64)value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME:
+               json_node_set_int(message->function, (gint64)value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_REQUEST_ID:
+               json_node_set_int(message->request_id, (gint64)value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE:
+               json_node_set_int(message->message_type, (gint64)value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_RESULT_CODE:
+               json_node_set_int(message->rcode, (gint64)value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE:
+               json_node_set_int(message->rmsg, (gint64)value);
+               break;
+       default:
+               return FAIL;
+       }
+
+       FUNC_END();
+       return SUCCESS;
+}
+
+int plugin_message_get_value_number(plugin_message_h message, plugin_message_element_e field, pmnumber *value)
+{
+       FUNC_START();
+       if ((NULL == message) || (NULL == value)) {
+               return FAIL;
+       }
+
+       switch (field) {
+       case PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID:
+               *value = (long long int)json_node_get_int(message->context);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME:
+               *value = (long long int)json_node_get_int(message->function);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_REQUEST_ID:
+               *value = (long long int)json_node_get_int(message->request_id);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE:
+               *value = (long long int)json_node_get_int(message->message_type);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_RESULT_CODE:
+               *value = (long long int)json_node_get_int(message->rcode);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE:
+               *value = (long long int)json_node_get_int(message->rmsg);
+               break;
+       default:
+               return FAIL;
+       }
+
+       FUNC_END();
+       return SUCCESS;
+}
+
+int plugin_message_set_value_string(plugin_message_h message, plugin_message_element_e field, const char *value)
+{
+       FUNC_START();
+       if (NULL == message) {
+               return FAIL;
+       }
+
+       switch (field) {
+       case PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID:
+               json_node_set_string(message->context, value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME:
+               json_node_set_string(message->function, value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_REQUEST_ID:
+               json_node_set_string(message->request_id, value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE:
+               json_node_set_string(message->message_type, value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_RESULT_CODE:
+               json_node_set_string(message->rcode, value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE:
+               json_node_set_string(message->rmsg, value);
+               break;
+       default:
+               return FAIL;
+       }
+
+       FUNC_END();
+       return SUCCESS;
+}
+
+int plugin_message_get_value_string(plugin_message_h message, plugin_message_element_e field, char **value)
+{
+       FUNC_START();
+       if ((NULL == message) || (NULL == value)) {
+               return FAIL;
+       }
+
+       switch (field) {
+       case PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID:
+               *value = (char *)json_node_dup_string(message->context);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME:
+               *value = (char *)json_node_dup_string(message->function);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_REQUEST_ID:
+               *value = (char *)json_node_dup_string(message->request_id);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE:
+               *value = (char *)json_node_dup_string(message->message_type);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_RESULT_CODE:
+               *value = (char *)json_node_dup_string(message->rcode);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE:
+               *value = (char *)json_node_dup_string(message->rmsg);
+               break;
+       default:
+               return FAIL;
+       }
+
+       FUNC_END();
+       return SUCCESS;
+}
+
+int plugin_message_set_value_bool(plugin_message_h message, plugin_message_element_e field, bool value)
+{
+       FUNC_START();
+       if (NULL == message) {
+               return FAIL;
+       }
+
+       switch (field) {
+       case PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID:
+               json_node_set_boolean(message->context, value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME:
+               json_node_set_boolean(message->function, value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_REQUEST_ID:
+               json_node_set_boolean(message->request_id, value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE:
+               json_node_set_boolean(message->message_type, value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_RESULT_CODE:
+               json_node_set_boolean(message->rcode, value);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE:
+               json_node_set_boolean(message->rmsg, value);
+               break;
+       default:
+               return FAIL;
+       }
+
+       FUNC_END();
+       return SUCCESS;
+}
+
+int plugin_message_get_value_bool(plugin_message_h message, plugin_message_element_e field, bool *value)
+{
+       FUNC_START();
+       if ((NULL == message) || (NULL == value)) {
+               return FAIL;
+       }
+
+       switch (field) {
+       case PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID:
+               *value = (bool)json_node_get_boolean(message->context);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME:
+               *value = (bool)json_node_get_boolean(message->function);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_REQUEST_ID:
+               *value = (bool)json_node_get_boolean(message->request_id);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE:
+               *value = (bool)json_node_get_boolean(message->message_type);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_RESULT_CODE:
+               *value = (bool)json_node_get_boolean(message->rcode);
+               break;
+       case PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE:
+               *value = (bool)json_node_get_boolean(message->rmsg);
+               break;
+       default:
+               return FAIL;
+       }
+
+       FUNC_END();
+       return SUCCESS;
+}
+
+/*
+int _plugin_message_set_parameter_value_int(JsonNode *node, int param_index, int value)
+{
+       char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+       if (0 > param_index)
+       {
+               return FAIL;
+       }
+       snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+       JsonObject *params;
+       params = json_node_get_object(node);
+
+       // release memory of legacy node
+
+//     JsonNode *legacy_node = json_object_get_member(params, index);
+//     if (NULL != legacy_node)
+//     {
+//             json_node_free(legacy_node);
+//     }
+
+       JsonNode *new_node = json_node_new(JSON_NODE_VALUE);
+       json_node_set_int(new_node, (gint64)value);
+       json_object_set_member(params, index, new_node);
+
+       return SUCCESS;
+}
+
+int _plugin_message_get_parameter_value_int(JsonNode *node, int param_index, int *value)
+{
+       char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+       if (0 > param_index)
+       {
+               return FAIL;
+       }
+       snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+       JsonObject *params;
+       params = json_node_get_object(node);
+
+       JsonNode *legacy_node = json_object_get_member(params, index);
+       if (NULL != legacy_node)
+       {
+               *value = (int)json_node_get_int(legacy_node);
+       }
+       else
+       {
+               return FAIL;
+       }
+
+       return SUCCESS;
+}
+*/
+
+int _plugin_message_set_parameter_value_number(JsonNode *node, int param_index, pmnumber value)
+{
+       FUNC_START();
+       char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+       if (0 > param_index) {
+               return FAIL;
+       }
+       snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+       JsonObject *params;
+       params = json_node_get_object(node);
+
+       /* release memory of legacy node */
+/*
+       JsonNode *legacy_node = json_object_get_member(params, index);
+       if (NULL != legacy_node)
+       {
+               json_node_free(legacy_node);
+       }
+*/
+       JsonNode *new_node = json_node_new(JSON_NODE_VALUE);
+       json_node_set_int(new_node, (gint64)value);
+       json_object_set_member(params, index, new_node);
+
+       FUNC_END();
+       return SUCCESS;
+}
+
+int _plugin_message_get_parameter_value_number(JsonNode *node, int param_index, pmnumber *value)
+{
+       FUNC_START();
+       char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+       if (0 > param_index) {
+               return FAIL;
+       }
+       snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+       JsonObject *params;
+       params = json_node_get_object(node);
+
+       JsonNode *legacy_node = json_object_get_member(params, index);
+       if (NULL != legacy_node) {
+               *value = (long long int)json_node_get_int(legacy_node);
+       } else {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return SUCCESS;
+}
+
+int _plugin_message_set_parameter_value_string(JsonNode *node, int param_index, const char *value)
+{
+       FUNC_START();
+       char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+       if (0 > param_index) {
+               return FAIL;
+       }
+       snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+       JsonObject *params;
+       params = json_node_get_object(node);
+
+       /* release memory of legacy node */
+/*
+       JsonNode *legacy_node = json_object_get_member(params, index);
+       if (NULL != legacy_node)
+       {
+               json_node_free(legacy_node);
+       }
+*/
+       JsonNode *new_node = json_node_new(JSON_NODE_VALUE);
+       json_node_set_string(new_node, value);
+       json_object_set_member(params, index, new_node);
+
+       FUNC_END();
+       return SUCCESS;
+}
+
+int _plugin_message_get_parameter_value_string(JsonNode *node, int param_index, char **value)
+{
+       FUNC_START();
+       char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+       if (0 > param_index) {
+               return FAIL;
+       }
+       snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+       JsonObject *params;
+       params = json_node_get_object(node);
+
+       JsonNode *legacy_node = json_object_get_member(params, index);
+       if (NULL != legacy_node) {
+               *value = (char *)json_node_dup_string(legacy_node);
+       } else {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return SUCCESS;
+}
+int _plugin_message_set_parameter_value_bool(JsonNode *node, int param_index, bool value)
+{
+       FUNC_START();
+       char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+       if (0 > param_index) {
+               return FAIL;
+       }
+       snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+       JsonObject *params;
+       params = json_node_get_object(node);
+
+       /* release memory of legacy node */
+/*
+       JsonNode *legacy_node = json_object_get_member(params, index);
+       if (NULL != legacy_node)
+       {
+               json_node_free(legacy_node);
+       }
+*/
+       JsonNode *new_node = json_node_new(JSON_NODE_VALUE);
+       json_node_set_boolean(new_node, value);
+       json_object_set_member(params, index, new_node);
+
+       FUNC_END();
+       return SUCCESS;
+}
+
+int _plugin_message_get_parameter_value_bool(JsonNode *node, int param_index, bool *value)
+{
+       FUNC_START();
+       char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+       if (0 > param_index) {
+               return FAIL;
+       }
+       snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+       JsonObject *params;
+       params = json_node_get_object(node);
+
+       JsonNode *legacy_node = json_object_get_member(params, index);
+       if (NULL != legacy_node) {
+               *value = (bool)json_node_get_boolean(legacy_node);
+       } else {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return SUCCESS;
+}
+
+int _plugin_message_set_parameter_value_array(JsonNode *node, int param_index, plugin_message_array_h value)
+{
+       FUNC_START();
+       char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+       if (0 > param_index) {
+               return FAIL;
+       }
+       snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+       JsonObject *params;
+       params = json_node_get_object(node);
+
+       /* release memory of legacy node */
+/*
+       JsonNode *legacy_node = json_object_get_member(params, index);
+       if (NULL != legacy_node)
+       {
+               json_node_free(legacy_node);
+       }
+*/
+       JsonNode *new_node = json_node_new(JSON_NODE_ARRAY);
+       json_node_set_array(new_node, value->element);
+       json_object_set_member(params, index, new_node);
+
+       FUNC_END();
+       return SUCCESS;
+}
+
+int _plugin_message_get_parameter_value_array(JsonNode *node, int param_index, plugin_message_array_h *value)
+{
+       FUNC_START();
+       char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+       if (0 > param_index) {
+               return FAIL;
+       }
+       snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", param_index);
+
+       JsonObject *params;
+       params = json_node_get_object(node);
+
+
+       JsonNode *legacy_node = json_object_get_member(params, index);
+       if ((NULL != legacy_node) && (JSON_NODE_ARRAY == json_node_get_node_type(legacy_node))) {
+               JsonArray *j_array = NULL;
+               PRINT_LOG("duplacate json array\n");
+               j_array = json_node_dup_array(legacy_node);
+
+               if (NULL != j_array) {
+                       plugin_message_array_h _array = (plugin_message_array_h) calloc(1, sizeof(struct _plugin_message_array_s));
+                       if (NULL == _array) {
+                               PRINT_LOG("Memory allocation failed\n");
+                               return FAIL;
+                       }
+
+                       _array->element = j_array;
+
+                       PRINT_LOG("get object from json array\n");
+                       JsonObject *job = json_array_get_object_element(j_array, 0);
+
+                       int len = (int) json_object_get_size(job);
+
+                       PRINT_LOG("json object length : %d\n", len);
+                       _array->types = (plugin_data_type *) calloc((len + 1), sizeof(plugin_data_type));
+                       if (NULL == _array->types) {
+                               PRINT_LOG("Memory allocation failed\n");
+                               free(_array);
+                               return FAIL;
+                       }
+
+                       int i;
+                       JsonNode *iter_node;
+                       char idx[PLUGIN_PARAMETER_BUF_SIZE_MAX];
+
+                       for (i = 0; i < len; i++) {
+                               snprintf(idx, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", i+1);
+
+                               iter_node = json_object_get_member(job, idx);
+                               if (JSON_NODE_VALUE == json_node_get_node_type(iter_node)) {
+                                       GType value_type = json_node_get_value_type(iter_node);
+                                       if (G_TYPE_INT64 == value_type) {
+                                               PRINT_LOG("node type (long == int)\n");
+                                               _array->types[i] = PLUGIN_DATA_TYPE_NUM;
+                                       } else if (G_TYPE_BOOLEAN == value_type) {
+                                               PRINT_LOG("node type (bool)\n");
+                                               _array->types[i] = PLUGIN_DATA_TYPE_BOOL;
+                                       } else if (G_TYPE_STRING == value_type) {
+                                               PRINT_LOG("node type (string)\n");
+                                               _array->types[i] = PLUGIN_DATA_TYPE_STRING;
+                                       } else {
+                                               PRINT_LOG("node type (unknown)\n");
+                                               _array->types[i] = PLUGIN_DATA_TYPE_UNKNOWN;
+                                       }
+                               } else {
+                                       PRINT_LOG("node type (no value node)\n");
+                                       _array->types[i] = PLUGIN_DATA_TYPE_UNKNOWN;
+                               }
+                       }
+
+                       *value = _array;
+
+                       FUNC_END();
+                       return SUCCESS;
+               }
+       }
+
+       FUNC_END();
+       return FAIL;
+}
+/*
+int plugin_message_set_param_int(plugin_message_h message, int param_index, int value)
+{
+       if (NULL == message)
+       {
+               return FAIL;
+       }
+
+       return _plugin_message_set_parameter_value_int(message->parameter_mandatory, param_index, value);
+}
+
+int plugin_message_get_param_int(plugin_message_h message, int param_index, int *value)
+{
+       if ((NULL == message) || (NULL == value))
+       {
+               return FAIL;
+       }
+
+       return _plugin_message_get_parameter_value_int(message->parameter_mandatory, param_index, value);
+}
+*/
+
+int plugin_message_set_param_number(plugin_message_h message, int param_index, pmnumber value)
+{
+       FUNC_START();
+       if (NULL == message) {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return _plugin_message_set_parameter_value_number(message->parameter_mandatory, param_index, value);
+}
+
+int plugin_message_get_param_number(plugin_message_h message, int param_index, pmnumber *value)
+{
+       FUNC_START();
+       if ((NULL == message) || (NULL == value)) {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return _plugin_message_get_parameter_value_number(message->parameter_mandatory, param_index, value);
+}
+
+int plugin_message_set_param_string(plugin_message_h message, int param_index, const char *value)
+{
+       FUNC_START();
+       if ((NULL == message) || (NULL == value)) {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return _plugin_message_set_parameter_value_string(message->parameter_mandatory, param_index, value);
+}
+
+int plugin_message_get_param_string(plugin_message_h message, int param_index, char **value)
+{
+       FUNC_START();
+       if ((NULL == message) || (NULL == value)) {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return _plugin_message_get_parameter_value_string(message->parameter_mandatory, param_index, value);
+}
+
+int plugin_message_set_param_bool(plugin_message_h message, int param_index, bool value)
+{
+       FUNC_START();
+       if (NULL == message) {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return _plugin_message_set_parameter_value_bool(message->parameter_mandatory, param_index, value);
+}
+
+int plugin_message_get_param_bool(plugin_message_h message, int param_index, bool *value)
+{
+       FUNC_START();
+       if ((NULL == message) || (NULL == value)) {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return _plugin_message_get_parameter_value_bool(message->parameter_mandatory, param_index, value);
+}
+
+int plugin_message_set_param_array(plugin_message_h message, int param_index, plugin_message_array_h value)
+{
+       FUNC_START();
+       if ((NULL == message) || (NULL == value)) {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return _plugin_message_set_parameter_value_array(message->parameter_mandatory, param_index, value);
+}
+
+int plugin_message_get_param_array(plugin_message_h message, int param_index, plugin_message_array_h *value)
+{
+       FUNC_START();
+       if ((NULL == message) || (NULL == value)) {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return _plugin_message_get_parameter_value_array(message->parameter_mandatory, param_index, value);
+}
+
+/*
+int plugin_message_set_opt_param_int(plugin_message_h message, int param_index, int value)
+{
+       FUNC_START();
+       if (NULL == message)
+       {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return _plugin_message_set_parameter_value_int(message->parameter_optional, param_index, value);
+}
+
+int plugin_message_get_opt_param_int(plugin_message_h message, int param_index, int *value)
+{
+       FUNC_START();
+       if ((NULL == message) || (NULL == value))
+       {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return _plugin_message_get_parameter_value_int(message->parameter_optional, param_index, value);
+}
+*/
+
+int plugin_message_set_opt_param_number(plugin_message_h message, int param_index, pmnumber value)
+{
+       FUNC_START();
+       if (NULL == message) {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return _plugin_message_set_parameter_value_number(message->parameter_optional, param_index, value);
+}
+
+int plugin_message_get_opt_param_number(plugin_message_h message, int param_index, pmnumber *value)
+{
+       FUNC_START();
+       if ((NULL == message) || (NULL == value)) {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return _plugin_message_get_parameter_value_number(message->parameter_optional, param_index, value);
+}
+
+int plugin_message_set_opt_param_string(plugin_message_h message, int param_index, const char *value)
+{
+       FUNC_START();
+       if ((NULL == message) || (NULL == value)) {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return _plugin_message_set_parameter_value_string(message->parameter_optional, param_index, value);
+}
+
+int plugin_message_get_opt_param_string(plugin_message_h message, int param_index, char **value)
+{
+       FUNC_START();
+       if ((NULL == message) || (NULL == value)) {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return _plugin_message_get_parameter_value_string(message->parameter_optional, param_index, value);
+}
+
+int plugin_message_set_opt_param_bool(plugin_message_h message, int param_index, bool value)
+{
+       FUNC_START();
+       if (NULL == message) {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return _plugin_message_set_parameter_value_bool(message->parameter_optional, param_index, value);
+}
+
+int plugin_message_get_opt_param_bool(plugin_message_h message, int param_index, bool *value)
+{
+       FUNC_START();
+       if ((NULL == message) || (NULL == value)) {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return _plugin_message_get_parameter_value_bool(message->parameter_optional, param_index, value);
+}
+
+int plugin_message_set_opt_param_array(plugin_message_h message, int param_index, plugin_message_array_h value)
+{
+       FUNC_START();
+       if ((NULL == message) || (NULL == value)) {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return _plugin_message_set_parameter_value_array(message->parameter_optional, param_index, value);
+}
+
+int plugin_message_get_opt_param_array(plugin_message_h message, int param_index, plugin_message_array_h *value)
+{
+       FUNC_START();
+       if ((NULL == message) || (NULL == value)) {
+               return FAIL;
+       }
+
+       FUNC_END();
+       return _plugin_message_get_parameter_value_array(message->parameter_optional, param_index, value);
+}
+
+char *_json_serialize_by_jnode(JsonNode *total_node)
+{
+       FUNC_START();
+       JsonGenerator *gen = json_generator_new();
+       json_generator_set_root(gen, total_node);
+
+       char *t_data = NULL;
+       gsize len = 0;
+       t_data = json_generator_to_data(gen, &len);
+
+       g_object_unref(gen);
+
+       FUNC_END();
+       return t_data;
+/*     return t; */
+}
+
+JsonNode *_json_deserialize_by_data(const char *data)
+{
+       FUNC_START();
+       JsonParser *parser = json_parser_new();
+       json_parser_load_from_data(parser, data, strlen(data), NULL);
+
+       PRINT_LOG("next\n");
+
+       JsonNode *node = json_parser_get_root(parser);
+
+       JsonNodeType nt = json_node_get_node_type(node);
+       if (nt == JSON_NODE_OBJECT)
+               PRINT_LOG("object type\n");
+       if (nt == JSON_NODE_ARRAY)
+               PRINT_LOG("array type\n");
+       if (nt == JSON_NODE_VALUE)
+               PRINT_LOG("value type\n");
+       if (nt == JSON_NODE_NULL)
+               PRINT_LOG("null type\n");
+
+       FUNC_END();
+       return node;
+}
+
+int plugin_message_serialize(plugin_message_h message, char **data)
+{
+       FUNC_START();
+       if ((NULL == message) || (NULL == data)) {
+               return FAIL;
+       }
+
+       JsonObject *obj = json_object_new();
+
+       JsonNode *context_id = json_node_copy(message->context);
+       JsonNode *function_name = json_node_copy(message->function);
+       JsonNode *parameter_mandatory = json_node_copy(message->parameter_mandatory);
+       JsonNode *parameter_optional = json_node_copy(message->parameter_optional);
+       JsonNode *request_id = json_node_copy(message->request_id);
+       JsonNode *message_type = json_node_copy(message->message_type);
+       JsonNode *rcode = json_node_copy(message->rcode);
+       JsonNode *rmsg = json_node_copy(message->rmsg);
+
+       JSON_EMPTY_NODE_FILL_NULL(context_id);
+       JSON_EMPTY_NODE_FILL_NULL(function_name);
+       JSON_EMPTY_NODE_FILL_NULL(parameter_mandatory);
+       JSON_EMPTY_NODE_FILL_NULL(parameter_optional);
+       JSON_EMPTY_NODE_FILL_NULL(request_id);
+       JSON_EMPTY_NODE_FILL_NULL(message_type);
+       JSON_EMPTY_NODE_FILL_NULL(rcode);
+       JSON_EMPTY_NODE_FILL_NULL(rmsg);
+
+       json_object_set_member(obj, PLUGIN_MESSAGE_ELEMENT_KEY_CONTEXT_ID, context_id);
+       json_object_set_member(obj, PLUGIN_MESSAGE_ELEMENT_KEY_FUNCTION_NAME, function_name);
+       json_object_set_member(obj, PLUGIN_MESSAGE_ELEMENT_KEY_PARAMETER_MANDATORY, parameter_mandatory);
+       json_object_set_member(obj, PLUGIN_MESSAGE_ELEMENT_KEY_PARAMETER_OPTIONAL, parameter_optional);
+       json_object_set_member(obj, PLUGIN_MESSAGE_ELEMENT_KEY_REQUEST_ID, request_id);
+       json_object_set_member(obj, PLUGIN_MESSAGE_ELEMENT_KEY_MESSAGE_TYPE, message_type);
+       json_object_set_member(obj, PLUGIN_MESSAGE_ELEMENT_KEY_RESULT_CODE, rcode);
+       json_object_set_member(obj, PLUGIN_MESSAGE_ELEMENT_KEY_RESULT_MESSAGE, rmsg);
+
+       JsonNode *node = json_node_new(JSON_NODE_OBJECT);
+       json_node_take_object(node, obj);
+
+       char *_data = NULL;
+       _data = _json_serialize_by_jnode(node);
+/*
+       json_node_free(node);
+       json_object_unref(obj);
+
+       json_node_free(context_id);
+       json_node_free(function_name);
+       json_node_free(parameter_mandatory);
+       json_node_free(parameter_optional);
+       json_node_free(request_id);
+       json_node_free(message_type);
+       json_node_free(rcode);
+       json_node_free(rmsg);
+*/
+       *data = _data;
+       FUNC_END();
+       return SUCCESS;
+}
+
+int plugin_message_deserialize(const char *data, plugin_message_h *message)
+{
+       FUNC_START();
+       if ((NULL == message) || (NULL == data)) {
+               return FAIL;
+       }
+
+       plugin_message_h _msg = (plugin_message_h) calloc(1, sizeof(struct _plugin_message_s));
+       if (NULL == _msg) {
+               return FAIL;
+       }
+
+       JsonNode *root_node = _json_deserialize_by_data(data);
+
+       JsonObject *root_object = json_node_get_object(root_node);
+
+       _msg->context                   = json_object_dup_member(root_object, PLUGIN_MESSAGE_ELEMENT_KEY_CONTEXT_ID);
+       _msg->function                  = json_object_dup_member(root_object, PLUGIN_MESSAGE_ELEMENT_KEY_FUNCTION_NAME);
+       _msg->parameter_mandatory       = json_object_dup_member(root_object, PLUGIN_MESSAGE_ELEMENT_KEY_PARAMETER_MANDATORY);
+       _msg->parameter_optional        = json_object_dup_member(root_object, PLUGIN_MESSAGE_ELEMENT_KEY_PARAMETER_OPTIONAL);
+       _msg->request_id                = json_object_dup_member(root_object, PLUGIN_MESSAGE_ELEMENT_KEY_REQUEST_ID);
+       _msg->message_type              = json_object_dup_member(root_object, PLUGIN_MESSAGE_ELEMENT_KEY_MESSAGE_TYPE);
+       _msg->rcode                     = json_object_dup_member(root_object, PLUGIN_MESSAGE_ELEMENT_KEY_RESULT_CODE);
+       _msg->rmsg                      = json_object_dup_member(root_object, PLUGIN_MESSAGE_ELEMENT_KEY_RESULT_MESSAGE);
+
+       *message = _msg;
+
+       json_node_free(root_node);
+
+       return SUCCESS;
+}
+
+int plugin_message_array_create(const plugin_data_type *type_string, plugin_message_array_h *array)
+{
+       FUNC_START();
+       if ((NULL == type_string) || (NULL == array)) {
+               return FAIL;
+       }
+       int i = 0, len = strlen(type_string);
+       for (i = 0; i < len; i++) {
+               switch (type_string[i]) {
+               case PLUGIN_DATA_TYPE_NUM:
+               case PLUGIN_DATA_TYPE_BOOL:
+               case PLUGIN_DATA_TYPE_STRING:
+                       break;
+               default:
+                       return FAIL;
+               }
+       }
+
+       plugin_message_array_h _array = (plugin_message_array_h) calloc(1, sizeof(struct _plugin_message_array_s));
+       plugin_data_type *_types = (plugin_data_type *) calloc(strlen(type_string)+1, sizeof(plugin_data_type));
+
+       if ((NULL == _array) || (NULL == _types)) {
+               free(_array);
+               free(_types);
+               return FAIL;
+       }
+
+       _array->element = json_array_new();
+
+       _array->types = _types;
+       strncpy(_array->types, type_string, strlen(type_string));
+
+       *array = _array;
+
+       FUNC_END();
+       return SUCCESS;
+}
+
+void plugin_message_array_destroy(plugin_message_array_h array)
+{
+       FUNC_START();
+       if (NULL != array) {
+               json_array_unref(array->element);
+               free(array->types);
+               free(array);
+       }
+       FUNC_END();
+}
+
+int plugin_message_array_add_element(plugin_message_array_h array, ...)
+{
+       FUNC_START();
+       if (NULL == array) {
+               return FAIL;
+       }
+
+       plugin_data_type *types = array->types;
+
+       int count = strlen(types);
+       int i = 0;
+       char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+
+       JsonObject *obj = json_object_new();
+       JsonNode *new_node;
+
+       PRINT_LOG("[%d]count : %d\n", __LINE__, count);
+
+       va_list vl;
+       va_start(vl, array);
+
+       for (i = 0; i < count; i++) {
+               memset(index, 0, PLUGIN_PARAMETER_BUF_SIZE_MAX);
+               snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", i+1);
+               PRINT_LOG("[%d]index : %s, type : %c\n", __LINE__, index, types[i]);
+
+               switch (types[i]) {
+/*
+               case PLUGIN_DATA_TYPE_INT:
+                       new_node = json_node_new(JSON_NODE_VALUE);
+                       json_node_set_int(new_node, (gint64)va_arg(vl, int));
+                       json_object_set_member(obj, index, new_node);
+                       PRINT_LOG("[%d]index : %s\n", __LINE__, index);
+                       break;
+*/
+               case PLUGIN_DATA_TYPE_NUM:
+                       new_node = json_node_new(JSON_NODE_VALUE);
+                       json_node_set_int(new_node, (gint64)va_arg(vl, long long int));
+                       json_object_set_member(obj, index, new_node);
+                       PRINT_LOG("[%d]index : %s\n", __LINE__, index);
+                       break;
+               case PLUGIN_DATA_TYPE_BOOL:
+                       new_node = json_node_new(JSON_NODE_VALUE);
+                       json_node_set_boolean(new_node, va_arg(vl, int) ? true : false);
+                       json_object_set_member(obj, index, new_node);
+                       PRINT_LOG("[%d]index : %s\n", __LINE__, index);
+                       break;
+               case PLUGIN_DATA_TYPE_STRING:
+                       new_node = json_node_new(JSON_NODE_VALUE);
+                       json_node_set_string(new_node, va_arg(vl, char *));
+                       json_object_set_member(obj, index, new_node);
+                       PRINT_LOG("[%d]index : %s\n", __LINE__, index);
+                       break;
+               default:
+                       new_node = json_node_new(JSON_NODE_NULL);
+                       json_object_set_member(obj, index, new_node);
+                       PRINT_LOG("[%d]index : %s <unknown dada, function fail>\n", __LINE__, index);
+                       va_end(vl);
+                       return FAIL;
+               }
+       }
+       va_end(vl);
+
+       PRINT_LOG("array length : %u\n", json_object_get_size(obj));
+       json_array_add_object_element(array->element, obj);
+
+       FUNC_END();
+       return SUCCESS;
+}
+
+int plugin_message_array_get_element(plugin_message_array_h array, int idx, ...)
+{
+       FUNC_START();
+       if ((NULL == array) || (1 > idx)) {
+               return FAIL;
+       }
+
+       if (json_array_get_length(array->element) < idx) {
+               return FAIL;
+       }
+
+       JsonObject *obj = json_array_get_object_element(array->element, idx-1);
+
+       if (NULL == obj) {
+               return FAIL;
+       }
+
+       plugin_data_type *types = array->types;
+
+       int count = strlen(types);
+       int i = 0;
+       char index[PLUGIN_PARAMETER_BUF_SIZE_MAX+1] = {0, };
+
+       JsonNode *new_node;
+
+       PRINT_LOG("[%d]count : %d\n", __LINE__, count);
+
+       va_list vl;
+       va_start(vl, idx);
+
+       for (i = 0; i < count; i++) {
+               memset(index, 0, PLUGIN_PARAMETER_BUF_SIZE_MAX);
+               snprintf(index, PLUGIN_PARAMETER_BUF_SIZE_MAX, "%d", i+1);
+               PRINT_LOG("[%d]index : %s, type : %c\n", __LINE__, index, types[i]);
+               new_node = json_object_get_member(obj, index);
+
+               switch (types[i]) {
+/*
+               case PLUGIN_DATA_TYPE_INT:
+                       *(va_arg(vl, int *)) = (int) json_node_get_int(new_node);
+                       PRINT_LOG("[%d]index : %s\n", __LINE__, index);
+                       break;
+*/
+               case PLUGIN_DATA_TYPE_NUM:
+                       *(va_arg(vl, long long int *)) = (long long int) json_node_get_int(new_node);
+                       PRINT_LOG("[%d]index : %s\n", __LINE__, index);
+                       break;
+               case PLUGIN_DATA_TYPE_BOOL:
+                       *(va_arg(vl, bool *)) = (bool) json_node_get_boolean(new_node);
+                       PRINT_LOG("[%d]index : %s\n", __LINE__, index);
+                       break;
+               case PLUGIN_DATA_TYPE_STRING:
+                       *(va_arg(vl, char **)) = (char *) json_node_dup_string(new_node);
+                       PRINT_LOG("[%d]index : %s\n", __LINE__, index);
+                       break;
+               default:
+                       PRINT_LOG("[%d]index : %s\n", __LINE__, index);
+                       break;
+               }
+       }
+       va_end(vl);
+
+       FUNC_END();
+       return SUCCESS;
+}
+
diff --git a/common/plugin_config/plugin_message.h b/common/plugin_config/plugin_message.h
new file mode 100644 (file)
index 0000000..90cc1ea
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+* Copyright (c) 2011 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 __TIZEN_SOCIAL_LIBSERVICE_PLUGIN_MESSAGE_H__
+#define __TIZEN_SOCIAL_LIBSERVICE_PLUGIN_MESSAGE_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef enum
+{
+       PLUGIN_MESSAGE_TYPE_FUNCTION = 1,
+       PLUGIN_MESSAGE_TYPE_CALLBACK = 2,
+} plugin_message_type_e;
+
+/*
+#define PLUGIN_DATA_TYPE_INT           'i'
+#define        PLUGIN_DATA_TYPE_LONG           'l'
+*/
+
+// INT/LONG -> NUM (64bit)
+#define PLUGIN_DATA_TYPE_NUM           'n'
+#define        PLUGIN_DATA_TYPE_STRING         's'
+#define        PLUGIN_DATA_TYPE_BOOL           'b'
+#define        PLUGIN_DATA_TYPE_ARRAY          'a'
+#define        PLUGIN_DATA_TYPE_UNKNOWN        'u'
+
+typedef char plugin_data_type;
+
+
+/*
+typedef enum
+{
+       PM_TYPE_FALSE = 0,
+       PM_TYPE_TRUE = 1,
+} pmbool_type_e;
+*/
+
+typedef long long int pmnumber;
+typedef char *pmstring;
+typedef bool pmbool;
+
+typedef enum
+{
+       PLUGIN_MESSAGE_ELEMENT_CONTEXT_ID,
+       PLUGIN_MESSAGE_ELEMENT_FUNCTION_NAME,
+       PLUGIN_MESSAGE_ELEMENT_PARAMETER_MANDATORY,
+       PLUGIN_MESSAGE_ELEMENT_PARAMETER_OPTIONAL,
+       PLUGIN_MESSAGE_ELEMENT_REQUEST_ID,
+       PLUGIN_MESSAGE_ELEMENT_MESSAGE_TYPE,
+       PLUGIN_MESSAGE_ELEMENT_RESULT_CODE,
+       PLUGIN_MESSAGE_ELEMENT_RESULT_MESSAGE,
+} plugin_message_element_e;
+
+typedef struct _plugin_message_s *plugin_message_h;
+
+typedef struct _plugin_message_array_s *plugin_message_array_h;
+
+
+int plugin_message_create(plugin_message_h *message);
+
+void plugin_message_destroy(plugin_message_h message);
+
+int plugin_message_set_value_number(plugin_message_h message, plugin_message_element_e field, pmnumber value);
+
+int plugin_message_get_value_number(plugin_message_h message, plugin_message_element_e field, pmnumber *value);
+
+int plugin_message_set_value_string(plugin_message_h message, plugin_message_element_e field, const char *value);
+
+int plugin_message_get_value_string(plugin_message_h message, plugin_message_element_e field, char **value);
+
+int plugin_message_set_value_bool(plugin_message_h message, plugin_message_element_e field, bool value);
+
+int plugin_message_get_value_bool(plugin_message_h message, plugin_message_element_e field, bool *value);
+
+
+int plugin_message_set_param_number(plugin_message_h message, int param_index, pmnumber value);
+
+int plugin_message_get_param_number(plugin_message_h message, int param_index, pmnumber *value);
+
+int plugin_message_set_param_string(plugin_message_h message, int param_index, const char *value);
+
+int plugin_message_get_param_string(plugin_message_h message, int param_index, char **value);
+
+int plugin_message_set_param_bool(plugin_message_h message, int param_index, bool value);
+
+int plugin_message_get_param_bool(plugin_message_h message, int param_index, bool *value);
+
+int plugin_message_set_param_array(plugin_message_h message, int param_index, plugin_message_array_h value);
+
+int plugin_message_get_param_array(plugin_message_h message, int param_index, plugin_message_array_h *value);
+
+
+int plugin_message_set_opt_param_number(plugin_message_h message, int param_index, pmnumber value);
+
+int plugin_message_get_opt_param_number(plugin_message_h message, int param_index, pmnumber *value);
+
+int plugin_message_set_opt_param_string(plugin_message_h message, int param_index, const char *value);
+
+int plugin_message_get_opt_param_string(plugin_message_h message, int param_index, char **value);
+
+int plugin_message_set_opt_param_bool(plugin_message_h message, int param_index, bool value);
+
+int plugin_message_get_opt_param_bool(plugin_message_h message, int param_index, bool *value);
+
+int plugin_message_set_opt_param_array(plugin_message_h message, int param_index, plugin_message_array_h value);
+
+int plugin_message_get_opt_param_array(plugin_message_h message, int param_index, plugin_message_array_h *value);
+
+
+int plugin_message_serialize(plugin_message_h message, char **data);
+
+int plugin_message_deserialize(const char *data, plugin_message_h *message);
+
+
+int plugin_message_array_create(const plugin_data_type *type_string, plugin_message_array_h *array);
+
+void plugin_message_array_destroy(plugin_message_array_h array);
+
+int plugin_message_array_add_element(plugin_message_array_h array, ...);
+
+int plugin_message_array_get_element(plugin_message_array_h array, int idx, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_SOCIAL_LIBSERVICE_PLUGIN_MESSAGE_H__ */
index d239048..b507155 100644 (file)
@@ -20,7 +20,8 @@ BuildRequires:  pkgconfig(capi-appfw-application)
 BuildRequires:  pkgconfig(capi-appfw-app-manager)
 BuildRequires:  pkgconfig(capi-appfw-package-manager)
 BuildRequires:  pkgconfig(capi-appfw-service-application)
-BuildRequires:  pkgconfig(libsmack)
+BuildRequires:  pkgconfig(json-glib-1.0)
+#BuildRequires:  pkgconfig(libsmack)
 #BuildRequires:  pkgconfig(service-discovery)
 #BuildRequires:  pkgconfig(service-federation)
 #BuildRequires:  service-discovery-devel
@@ -82,18 +83,20 @@ cp LICENSE.APLv2 %{buildroot}/usr/share/license/service-adaptor-devel
 %manifest service-adaptor.manifest
 %defattr(-,root,root,-)
 %{_libdir}/lib*.so.*
-%{_bindir}/service-adaptor-server
+#%{_bindir}/service-adaptor-server
 #%{_bindir}/sal-test
 %{_unitdir_user}/service-adaptor.service
 %{_unitdir_user}/default.target.wants/service-adaptor.service
 %{_datadir}/dbus-1/system-services/org.tizen.serviceadaptor.client.service
 %{_sysconfdir}/dbus-1/system.d/org.tizen.serviceadaptor.client.conf
 /usr/share/license/%{name}
+%{_includedir}/*.h
 
 %files -n service-adaptor-devel
 %defattr(-,root,root,-)
 %{_libdir}/lib*.so
 %{_libdir}/pkgconfig/service-adaptor.pc
-%{_includedir}/service-adaptor/*.h
-%{_includedir}/service-provider/*.h
+%{_includedir}/*.h
+#%{_includedir}/service-adaptor/*.h
+#%{_includedir}/service-provider/*.h
 /usr/share/license/%{name}-devel