From ad97a93299465c51dbfe89cfb80659d732497938 Mon Sep 17 00:00:00 2001 From: "jk7744.park" Date: Mon, 26 Oct 2015 15:43:44 +0900 Subject: [PATCH] tizen 2.4 release --- CMakeLists.txt | 47 + LICENSE.Apache-2.0 | 202 ++++ NOTICE | 3 + README | 0 inc/message-adaptor-log.h | 202 ++++ inc/message-adaptor.h | 1842 +++++++++++++++++++++++++++++++++++ message-adaptor.manifest | 13 + message-adaptor.pc.in | 10 + packaging/message-adaptor.spec | 48 + src/message-adaptor.c | 2095 ++++++++++++++++++++++++++++++++++++++++ 10 files changed, 4462 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 LICENSE.Apache-2.0 create mode 100644 NOTICE create mode 100644 README create mode 100644 inc/message-adaptor-log.h create mode 100644 inc/message-adaptor.h create mode 100644 message-adaptor.manifest create mode 100644 message-adaptor.pc.in create mode 100644 packaging/message-adaptor.spec create mode 100644 src/message-adaptor.c diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..dfaacb4 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,47 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(message-adaptor C) + +set(BUILD_TYPE "DEBUG") + +# variable holds path to config files +set(CONFIG_FILES_PATH "" CACHE FILEPATH "Path to coniguration files") + +include_directories(${CMAKE_BINARY_DIR}) + +file(GLOB SRCS src/*.c) + +if(BUILD_TYPE STREQUAL "DEBUG") + message("DEBUG build!") + set(BUILD_TYPE_FLAGS "") +elseif(BUILD_TYPE STREQUAL "RELEASE") + message("RELEASE build!") + set(BUILD_TYPE_FLAGS "-DRELEASE") +else() + message(FATAL_ERROR "####\nBUILD_TYPE should be DEBUG or RELEASE! Have: ${BUILD_TYPE} . Aborting.\n####") +endif(BUILD_TYPE STREQUAL "DEBUG") + +set(PREFIX "/usr") +set(BINDIR "${PREFIX}/bin") +set(LIBDIR "${PREFIX}/lib") + +include_directories(${CMAKE_SOURCE_DIR}/inc) + +include(FindPkgConfig) +pkg_check_modules(pkgs REQUIRED glib-2.0 dlog) + +foreach(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +endforeach(flag) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror -std=gnu99 -D_GNU_SOURCE") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") +SET(CMAKE_C_FLAGS_RELEASE "-O2") + +ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS} ) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${client_pkgs_LDFLAGS} message-adaptor "-lm -ldl -lrt") +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIBDIR}) + +INSTALL(FILES ${CMAKE_SOURCE_DIR}/inc/message-adaptor.h DESTINATION /usr/include/message-adaptor/) + +CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/message-adaptor.pc.in ${CMAKE_SOURCE_DIR}/message-adaptor.pc @ONLY) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/message-adaptor.pc DESTINATION ${LIBDIR}/pkgconfig) diff --git a/LICENSE.Apache-2.0 b/LICENSE.Apache-2.0 new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE.Apache-2.0 @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..579ba56 --- /dev/null +++ b/NOTICE @@ -0,0 +1,3 @@ +Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Apache License, Version 2. +Please, see the LICENSE.Apache-2.0 file for Apache License terms and conditions. diff --git a/README b/README new file mode 100644 index 0000000..e69de29 diff --git a/inc/message-adaptor-log.h b/inc/message-adaptor-log.h new file mode 100644 index 0000000..e0a516b --- /dev/null +++ b/inc/message-adaptor-log.h @@ -0,0 +1,202 @@ +/* +* 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) + +/** + * @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_secure(fmt, arg...) do { \ + SECURE_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/inc/message-adaptor.h b/inc/message-adaptor.h new file mode 100644 index 0000000..a5d64b7 --- /dev/null +++ b/inc/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/message-adaptor.manifest b/message-adaptor.manifest new file mode 100644 index 0000000..9cc5e17 --- /dev/null +++ b/message-adaptor.manifest @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/message-adaptor.pc.in b/message-adaptor.pc.in new file mode 100644 index 0000000..17cfa3c --- /dev/null +++ b/message-adaptor.pc.in @@ -0,0 +1,10 @@ +prefix=@PREFIX@ +libdir=@PREFIX@/lib +includedir=@PREFIX@/include + +Name: message adaptor API +Description: message adaptor API +Requires: glib-2.0 +Version: 1.0 +Libs: -L${libdir} -lmessage-adaptor -pthread +Cflags: -I${includedir}/message-adaptor diff --git a/packaging/message-adaptor.spec b/packaging/message-adaptor.spec new file mode 100644 index 0000000..dc946a0 --- /dev/null +++ b/packaging/message-adaptor.spec @@ -0,0 +1,48 @@ +Name: message-adaptor +Summary: message Adaptor +Version: 1.0.0 +Release: 1 +Group: Social & Content +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(dlog) +BuildRequires: cmake + +%description +message Adaptor + +%package -n message-adaptor-devel +Summary: Headers for message adaptor +Group: Development/Libraries +Requires: message-adaptor = %{version}-%{release} + +%description -n message-adaptor-devel +This package contains the header and pc files. + +%prep +%setup -q + +%build +export PREFIX="/usr/apps/message-adaptor" +#export CFLAGS+=" -fPIC" +export LDFLAGS+=" -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed -Wl,--hash-style=both" + +cmake . -DCMAKE_INSTALL_PREFIX="$PREFIX" + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + +%files +%manifest message-adaptor.manifest +%defattr(-,root,root,-) +%{_libdir}/libmessage-adaptor.so + +%files -n message-adaptor-devel +%defattr(-,root,root,-) +%{_includedir}/message-adaptor/*.h +%{_libdir}/pkgconfig/message-adaptor.pc + diff --git a/src/message-adaptor.c b/src/message-adaptor.c new file mode 100644 index 0000000..f2ba724 --- /dev/null +++ b/src/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_secure("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; +} -- 2.7.4