From: Jiwon Kim Date: Fri, 26 Feb 2016 10:58:09 +0000 (+0900) Subject: Merge (manually) adaptors and plugin-config from tizen_2.4 repository X-Git-Tag: accepted/tizen/common/20160303.110440~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=94cbc69e80fdd7a083defcf9f2a85c1e833ee32d;p=platform%2Fcore%2Fconvergence%2Fservice-adaptor.git Merge (manually) adaptors and plugin-config from tizen_2.4 repository framework/convergence/service/adaptors/*-adaptor -> adaptor/*-adaptor framework/convergence/service/service-plugin-client -> common/plugin_config Change-Id: I8c92e2fd7588d99100d1d40bae0768b0cfb54854 Signed-off-by: Jiwon Kim --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a4e049..954ada3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 index 0000000..7b55e8b --- /dev/null +++ b/adaptor/CMakeLists.txt @@ -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 index 57d751e..0000000 --- a/adaptor/CMakeLists.txt.backup +++ /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 index 0000000..eef4d26 --- /dev/null +++ b/adaptor/auth-adaptor/auth-adaptor-log.h @@ -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 +#include + +/* These defines must be located before #include */ +#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 + +#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 index 0000000..a70ccaf --- /dev/null +++ b/adaptor/auth-adaptor/auth-adaptor.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#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 index 0000000..2db99f8 --- /dev/null +++ b/adaptor/auth-adaptor/auth-adaptor.h @@ -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 +#include + +/** + * @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 index 0000000..6a93541 --- /dev/null +++ b/adaptor/contact-adaptor/contact-adaptor-log.h @@ -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 +#include + +/* These defines must be located before #include */ +#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 + +#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 index 0000000..2cf858c --- /dev/null +++ b/adaptor/contact-adaptor/contact-adaptor.c @@ -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 +#include +#include +#include +#include +#include + +#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 index 0000000..8d23f9b --- /dev/null +++ b/adaptor/contact-adaptor/contact-adaptor.h @@ -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 +#include +#include + +/** +* @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 index 0000000..69f9e69 --- /dev/null +++ b/adaptor/message-adaptor/message-adaptor-log.h @@ -0,0 +1,192 @@ +/* +* 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_LOG_H__ +#define __MESSAGE_ADAPTOR_LOG_H__ + + +/* #define WORK_IN_LOCAL */ + +/** + * 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 MESSAGE_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 +#include + +/* These defines must be located before #include */ +#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 "MESSAGE_ADAPTOR" + + +#ifndef WORK_IN_LOCAL +#include +#else +#define LOGE(fmt, arg...) +#define LOGD(fmt, arg...) +#define LOGI(fmt, arg...) +#define LOGF(fmt, arg...) +#define LOGW(fmt, arg...) +#endif + + +#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 message_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 message_adaptor_retv_if(expr, val) do { \ + if(expr) { \ + LOGE(FONT_COLOR_PURPLE"[%d]"FONT_COLOR_RESET, message_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 message_adaptor_debug(fmt, arg...) do { \ + LOGD(FONT_COLOR_GREEN"[%d]"fmt""FONT_COLOR_RESET, message_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 message_adaptor_info(fmt, arg...) do { \ + LOGI(FONT_COLOR_BLUE"[%d]"fmt""FONT_COLOR_RESET, message_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 message_adaptor_warning(fmt, arg...) do { \ + LOGW(FONT_COLOR_YELLOW"[%d]"fmt""FONT_COLOR_RESET,message_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 message_adaptor_error(fmt, arg...) do { \ + LOGE(FONT_COLOR_RED"[%d]"fmt""FONT_COLOR_RESET,message_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 message_adaptor_fatal(fmt, arg...) do { \ + LOGF(FONT_COLOR_BOLDRED"[%d]"fmt""FONT_COLOR_RESET,message_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 message_adaptor_debug_func(fmt, arg...) do { \ + LOGD(FONT_COLOR_CYAN"[%d]"fmt""FONT_COLOR_RESET, message_adaptor_gettid(), ##arg); \ + } while (0) + +#define plugin_req_enter() do { \ + message_adaptor_info("[ENTER] plugin API call -)) -)) -)) -)) -)) -)) -)) -)) -)) -))"); \ + } while (0) + +#define plugin_req_exit(ret, plugin, error) do { \ + message_adaptor_info("[EXIT] plugin API called (%d) ((- ((- ((- ((- ((- ((- ((- ((- ((- ((-", (int)(ret)); \ + if ((error)) { \ + if ((*error)) { \ + message_adaptor_error("plugin issued error (%s) (%s)", (char *)((*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 { \ + message_adaptor_info("[EXIT] plugin API called ((- ((- ((- ((- ((- ((- ((- ((- ((- ((-"); \ + } while (0) + +#define plugin_req_id_print() do { \ + message_adaptor_info("[REQUEST_ID] Important Request ID <%lld>", (long long int)request_id); \ + } while (0) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __MESSAGE_ADAPTOR_LOG_H__ */ diff --git a/adaptor/message-adaptor/message-adaptor.c b/adaptor/message-adaptor/message-adaptor.c new file mode 100644 index 0000000..acf7738 --- /dev/null +++ b/adaptor/message-adaptor/message-adaptor.c @@ -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 +#include +#include +#include +#include +#include + + +#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 index 0000000..a5d64b7 --- /dev/null +++ b/adaptor/message-adaptor/message-adaptor.h @@ -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 +#include +#include +#include +#include + + +#ifndef EXPORT_API +#define EXPORT_API __attribute__((visibility("default"))) +#endif + +#include + +/** + * 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 index 0000000..2bd7148 --- /dev/null +++ b/adaptor/push-adaptor/push-adaptor-log.h @@ -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 +#include + +/* These defines must be located before #include */ +#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 + +#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 index 0000000..af58ea8 --- /dev/null +++ b/adaptor/push-adaptor/push-adaptor.c @@ -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 +#include +#include +#include +#include + +#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 index 0000000..6829ac6 --- /dev/null +++ b/adaptor/push-adaptor/push-adaptor.h @@ -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 +#include +#include + +/** +* @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 index 0000000..6133597 --- /dev/null +++ b/adaptor/shop-adaptor/shop-adaptor-log.h @@ -0,0 +1,188 @@ +/* +* 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 __SHOP_ADAPTOR_LOG_H__ +#define __SHOP_ADAPTOR_LOG_H__ + +//#define WORK_IN_LOCAL + +/** + * 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 SHOP_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 +#include + +/* These defines must be located before #include */ +#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 "SHOP_ADAPTOR" + + +#ifndef WORK_IN_LOCAL +#include +#else +#define LOGE(fmt, arg...) +#define LOGD(fmt, arg...) +#define LOGI(fmt, arg...) +#define LOGF(fmt, arg...) +#define LOGW(fmt, arg...) +#endif + + +#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 shop_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 shop_adaptor_retv_if(expr, val) do { \ + if(expr) { \ + LOGE(FONT_COLOR_PURPLE"[%d]"FONT_COLOR_RESET, shop_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 shop_adaptor_debug(fmt, arg...) do { \ + LOGD(FONT_COLOR_GREEN"[%d]"fmt""FONT_COLOR_RESET, shop_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 shop_adaptor_info(fmt, arg...) do { \ + LOGI(FONT_COLOR_BLUE"[%d]"fmt""FONT_COLOR_RESET, shop_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 shop_adaptor_warning(fmt, arg...) do { \ + LOGW(FONT_COLOR_YELLOW"[%d]"fmt""FONT_COLOR_RESET,shop_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 shop_adaptor_error(fmt, arg...) do { \ + LOGE(FONT_COLOR_RED"[%d]"fmt""FONT_COLOR_RESET,shop_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 shop_adaptor_fatal(fmt, arg...) do { \ + LOGF(FONT_COLOR_BOLDRED"[%d]"fmt""FONT_COLOR_RESET,shop_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 shop_adaptor_debug_func(fmt, arg...) do { \ + LOGD(FONT_COLOR_CYAN"[%d]"fmt""FONT_COLOR_RESET, shop_adaptor_gettid(), ##arg); \ + } while (0) + +#define plugin_req_enter() do { \ + shop_adaptor_info("[ENTER] plugin API call -)) -)) -)) -)) -)) -)) -)) -)) -)) -))"); \ + } while (0) + +#define plugin_req_exit(ret, plugin, error) do { \ + shop_adaptor_info("[EXIT] plugin API called (%d) ((- ((- ((- ((- ((- ((- ((- ((- ((- ((-", (int)(ret)); \ + if ((error)) { \ + if ((*error)) { \ + shop_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 { \ + shop_adaptor_info("[EXIT] plugin API called ((- ((- ((- ((- ((- ((- ((- ((- ((- ((-"); \ + } while (0) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __SHOP_ADAPTOR_LOG_H__ */ + diff --git a/adaptor/shop-adaptor/shop-adaptor.c b/adaptor/shop-adaptor/shop-adaptor.c new file mode 100644 index 0000000..b0af4dc --- /dev/null +++ b/adaptor/shop-adaptor/shop-adaptor.c @@ -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 +#include +#include +#include +#include +#include + +#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 index 0000000..2ae629b --- /dev/null +++ b/adaptor/shop-adaptor/shop-adaptor.h @@ -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 + * + *****************************************************************************/ +/** + * @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 +#include +/** + * @ 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 index 0000000..5593807 --- /dev/null +++ b/adaptor/storage-adaptor/storage-adaptor-log.h @@ -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 +#include + +/* These defines must be located before #include */ +#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 + +#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]" "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 index 0000000..c2f39ad --- /dev/null +++ b/adaptor/storage-adaptor/storage-adaptor.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 index 0000000..1d79a1e --- /dev/null +++ b/adaptor/storage-adaptor/storage-adaptor.h @@ -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 +#include +#include +#include +#include +#include + +#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 index 0000000..40d588a --- /dev/null +++ b/common/CMakeLists.txt @@ -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 index 0000000..809c32b --- /dev/null +++ b/common/plugin_config/libservice_plugin_log.h @@ -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 +#include + +/* These defines must be located before #include */ +#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 + +#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 index 0000000..b543d97 --- /dev/null +++ b/common/plugin_config/plugin_message.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libservice_plugin_log.h" +#include +#include + +/* 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 \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 index 0000000..90cc1ea --- /dev/null +++ b/common/plugin_config/plugin_message.h @@ -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 +#include + +#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__ */ diff --git a/packaging/service-adaptor.spec b/packaging/service-adaptor.spec index d239048..b507155 100644 --- a/packaging/service-adaptor.spec +++ b/packaging/service-adaptor.spec @@ -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