tizen 2.4 release accepted/tizen_2.4_mobile accepted/tizen/2.4/mobile/20151029.033305 submit/tizen_2.4/20151028.064119 tizen_2.4_mobile_release
authorjk7744.park <jk7744.park@samsung.com>
Mon, 26 Oct 2015 06:43:44 +0000 (15:43 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Mon, 26 Oct 2015 06:43:44 +0000 (15:43 +0900)
CMakeLists.txt [new file with mode: 0644]
LICENSE.Apache-2.0 [new file with mode: 0644]
NOTICE [new file with mode: 0644]
README [new file with mode: 0644]
inc/message-adaptor-log.h [new file with mode: 0644]
inc/message-adaptor.h [new file with mode: 0644]
message-adaptor.manifest [new file with mode: 0644]
message-adaptor.pc.in [new file with mode: 0644]
packaging/message-adaptor.spec [new file with mode: 0644]
src/message-adaptor.c [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..dfaacb4
--- /dev/null
@@ -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 (file)
index 0000000..d645695
--- /dev/null
@@ -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 (file)
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 (file)
index 0000000..e69de29
diff --git a/inc/message-adaptor-log.h b/inc/message-adaptor-log.h
new file mode 100644 (file)
index 0000000..e0a516b
--- /dev/null
@@ -0,0 +1,202 @@
+/*\r
+* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved\r
+*\r
+* Licensed under the Apache License, Version 2.0 (the License);\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+* http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an AS IS BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+*/\r
+\r
+#ifndef __MESSAGE_ADAPTOR_LOG_H__\r
+#define __MESSAGE_ADAPTOR_LOG_H__\r
+\r
+\r
+/* #define WORK_IN_LOCAL */\r
+\r
+/**\r
+ *  HOW TO USE IT:\r
+ *  First you need to set platform logging on the device:\r
+ *\r
+ *    # dlogctrl set platformlog 1\r
+ *\r
+ *  After reboot you are able to see logs from this application, when you launch dlogutil with a proper filter e.g.:\r
+ *\r
+ *    # dlogutil MESSAGE_ADAPTOR:D\r
+ *\r
+ *  You may use different logging levels as: D (debug), I (info), W (warning), E (error) or F (fatal).\r
+ *  Higher level messages are included by default e.g. dlogutil CLOUDBOX:W prints warnings but also errors and fatal messages.\r
+ */\r
+\r
+#include <unistd.h>\r
+#include <linux/unistd.h>\r
+\r
+/* These defines must be located before #include <dlog.h> */\r
+#define TIZEN_ENGINEER_MODE\r
+// TODO: Investigate why this macro is defined somewhere else\r
+#ifndef TIZEN_DEBUG_ENABLE\r
+#define TIZEN_DEBUG_ENABLE\r
+#endif\r
+\r
+#ifdef LOG_TAG\r
+#undef LOG_TAG\r
+#endif\r
+/* Literal to filter logs from dlogutil */\r
+#define LOG_TAG "MESSAGE_ADAPTOR"\r
+\r
+\r
+#ifndef WORK_IN_LOCAL\r
+#include <dlog.h>\r
+#else\r
+#define LOGE(fmt, arg...)\r
+#define LOGD(fmt, arg...)\r
+#define LOGI(fmt, arg...)\r
+#define LOGF(fmt, arg...)\r
+#define LOGW(fmt, arg...)\r
+#endif\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif /* __cplusplus */\r
+\r
+       /**\r
+        *  Colors of font\r
+        */\r
+#define FONT_COLOR_RESET      "\033[0m"\r
+#define FONT_COLOR_BLACK      "\033[30m"             /* Black */\r
+#define FONT_COLOR_RED        "\033[31m"             /* Red */\r
+#define FONT_COLOR_GREEN      "\033[32m"             /* Green */\r
+#define FONT_COLOR_YELLOW     "\033[33m"             /* Yellow */\r
+#define FONT_COLOR_BLUE       "\033[34m"             /* Blue */\r
+#define FONT_COLOR_PURPLE     "\033[35m"             /* Purple */\r
+#define FONT_COLOR_CYAN       "\033[36m"             /* Cyan */\r
+#define FONT_COLOR_WHITE      "\033[37m"             /* White */\r
+#define FONT_COLOR_BOLDBLACK  "\033[1m\033[30m"      /* Bold Black */\r
+#define FONT_COLOR_BOLDRED    "\033[1m\033[31m"      /* Bold Red */\r
+#define FONT_COLOR_BOLDGREEN  "\033[1m\033[32m"      /* Bold Green */\r
+#define FONT_COLOR_BOLDYELLOW "\033[1m\033[33m"      /* Bold Yellow */\r
+#define FONT_COLOR_BOLDBLUE   "\033[1m\033[34m"      /* Bold Blue */\r
+#define FONT_COLOR_BOLDPURPLE "\033[1m\033[35m"      /* Bold Purple */\r
+#define FONT_COLOR_BOLDCYAN   "\033[1m\033[36m"      /* Bold Cyan */\r
+#define FONT_COLOR_BOLDWHITE  "\033[1m\033[37m"      /* Bold White */\r
+\r
+       /**\r
+        *  Gets thread ID\r
+        */\r
+#define message_adaptor_gettid() syscall(__NR_gettid)\r
+\r
+/**\r
+ *  @brief Macro for returning value if expression is satisfied\r
+ *  @param[in]  expr Expression to be checked\r
+ *  @param[out] val  Value to be returned when expression is true\r
+ */\r
+#define message_adaptor_retv_if(expr, val) do { \\r
+            if(expr) { \\r
+                LOGE(FONT_COLOR_PURPLE"[%d]"FONT_COLOR_RESET, message_adaptor_gettid());    \\r
+                return (val); \\r
+            } \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints debug messages\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define message_adaptor_debug(fmt, arg...) do { \\r
+            LOGD(FONT_COLOR_GREEN"[%d]"fmt""FONT_COLOR_RESET, message_adaptor_gettid(), ##arg);     \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints info messages\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define message_adaptor_info(fmt, arg...) do { \\r
+            LOGI(FONT_COLOR_BLUE"[%d]"fmt""FONT_COLOR_RESET, message_adaptor_gettid() ,##arg);     \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints warning messages\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define message_adaptor_warning(fmt, arg...) do { \\r
+            LOGW(FONT_COLOR_YELLOW"[%d]"fmt""FONT_COLOR_RESET,message_adaptor_gettid(), ##arg);     \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints error messages\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define message_adaptor_error(fmt, arg...) do { \\r
+            LOGE(FONT_COLOR_RED"[%d]"fmt""FONT_COLOR_RESET,message_adaptor_gettid(), ##arg);     \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints fatal messages\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define message_adaptor_fatal(fmt, arg...) do { \\r
+            LOGF(FONT_COLOR_BOLDRED"[%d]"fmt""FONT_COLOR_RESET,message_adaptor_gettid(), ##arg);     \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints debug message on entry to particular function\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define message_adaptor_debug_func(fmt, arg...) do { \\r
+            LOGD(FONT_COLOR_CYAN"[%d]"fmt""FONT_COLOR_RESET, message_adaptor_gettid(), ##arg);     \\r
+        } while (0)\r
+\r
+/**\r
+ * @brief Prints debug message on entry to particular function\r
+ * @param[in]  fmt  Format of data to be displayed\r
+ * @param[in]  args Arguments to be displayed\r
+ */\r
+#define message_adaptor_debug_secure(fmt, arg...) do { \\r
+            SECURE_LOGD(FONT_COLOR_CYAN"[%d]"fmt""FONT_COLOR_RESET, message_adaptor_gettid(), ##arg);     \\r
+        } while (0)\r
+\r
+\r
+#define plugin_req_enter()                     do { \\r
+               message_adaptor_info("[ENTER] plugin API call -)) -)) -)) -)) -)) -)) -)) -)) -)) -))"); \\r
+       } while (0)\r
+\r
+#define plugin_req_exit(ret, plugin, error)    do { \\r
+               message_adaptor_info("[EXIT] plugin API called (%d) ((- ((- ((- ((- ((- ((- ((- ((- ((- ((-", (int)(ret)); \\r
+               if ((error)) { \\r
+                       if ((*error)) { \\r
+                               message_adaptor_error("plugin issued error (%s) (%s)", (char *)((*error)->code), (char *)((*error)->msg)); \\r
+                               char *tem = g_strdup_printf("[PLUGIN_ERROR] URI(%s), MSG(%s)", (char *)((plugin)->handle->plugin_uri), (char *)((*error)->msg)); \\r
+                               if (tem) { \\r
+                                       free((*error)->msg); \\r
+                                       (*error)->msg = tem; \\r
+                               } \\r
+                       } \\r
+               } \\r
+       } while (0)\r
+\r
+#define plugin_req_exit_void()                 do { \\r
+               message_adaptor_info("[EXIT] plugin API called ((- ((- ((- ((- ((- ((- ((- ((- ((- ((-"); \\r
+       } while (0)\r
+\r
+#define plugin_req_id_print()                  do { \\r
+               message_adaptor_info("[REQUEST_ID] Important Request ID <%lld>", (long long int)request_id); \\r
+       } while (0)\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+\r
+#endif /* __MESSAGE_ADAPTOR_LOG_H__ */\r
diff --git a/inc/message-adaptor.h b/inc/message-adaptor.h
new file mode 100644 (file)
index 0000000..a5d64b7
--- /dev/null
@@ -0,0 +1,1842 @@
+/*
+* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __MESSAGE_ADAPTOR_H__
+#define __MESSAGE_ADAPTOR_H__
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <arpa/inet.h>
+#include <stdbool.h>
+#include <pthread.h>
+
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__((visibility("default")))
+#endif
+
+#include <glib.h>
+
+/**
+ * Message adaptor error code
+ */
+typedef enum message_error_code_e
+{
+       MESSAGE_ADAPTOR_ERROR_NONE                     =  0,
+       MESSAGE_ADAPTOR_ERROR_LAUNCH                    = 1,    /**< 1 ~ 99: internal error*/
+       MESSAGE_ADAPTOR_ERROR_INIT                      = 2,
+       MESSAGE_ADAPTOR_ERROR_DEINIT                    = 3,
+       MESSAGE_ADAPTOR_ERROR_CREATE                    = 4,
+       MESSAGE_ADAPTOR_ERROR_DESTROY                   = 5,
+       MESSAGE_ADAPTOR_ERROR_START                     = 6,
+       MESSAGE_ADAPTOR_ERROR_STOP                      = 7,
+       MESSAGE_ADAPTOR_ERROR_CONNECT                   = 8,
+       MESSAGE_ADAPTOR_ERROR_DISCONNECT                = 9,
+       MESSAGE_ADAPTOR_ERROR_NOT_FOUND                 = 10,
+       MESSAGE_ADAPTOR_ERROR_CORRUPTED                 = 11,
+       MESSAGE_ADAPTOR_ERROR_UNSUPPORTED               = 12,
+       MESSAGE_ADAPTOR_ERROR_INVALID_HANDLE            = 13,
+       MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT          = 14,
+       MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT_TYPE     = 15,
+       MESSAGE_ADAPTOR_ERROR_NOT_AUTHORIZED            = 16,
+       MESSAGE_ADAPTOR_ERROR_ADAPTOR_INTERNAL          = 17,
+       MESSAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL           = 18,   // input error code and message issued from curl or http or message_plugin_internal_error_code_e(defined by developer manually)
+       MESSAGE_ADAPTOR_ERROR_SERVER_INTERNAL           = 19,   // input error code and message issued from server.
+       MESSAGE_ADAPTOR_ERROR_DBUS                      = 20,
+       MESSAGE_ADAPTOR_ERROR_TIME_OUT                  = 21,
+       MESSAGE_ADAPTOR_ERROR_MAX
+} message_error_code_t;
+
+/**
+ * @ brief Message plugin internal error code
+ * @ details When a plugin returns MESSAGE_ADAPTOR_ERROR_PLUGIN_INTERNAL, input this number to message_adaptor_error_code_s.code
+ */
+typedef enum _message_plugin_internal_error_code_e
+{
+       MESSAGE_PLUGIN_ERROR_HTTP_BAD_REQUEST           = 400,
+       MESSAGE_PLUGIN_ERROR_HTTP_UNAUTHORIZED          = 401,
+       MESSAGE_PLUGIN_ERROR_HTTP_FORBIDDEN             = 403,
+       MESSAGE_PLUGIN_ERROR_HTTP_NOT_FOUND             = 404,
+       MESSAGE_PLUGIN_ERROR_HTTP_METHOD_NOT_ALLOWED    = 405,
+       MESSAGE_PLUGIN_ERROR_HTTP_BAD_GATEWAY           = 502,
+       MESSAGE_PLUGIN_ERROR_HTTP_SERVICE_UNAVAILBLE    = 503,
+       MESSAGE_PLUGIN_ERROR_HTTP_INSUFFICIENT_STORAGE  = 507,
+       MESSAGE_PLUGIN_ERROR_HTTP_ETC                   = 598,
+       MESSAGE_PLUGIN_ERROR_HTTP_UNKNOWN               = 599,
+
+       MESSAGE_PLUGIN_ERROR_NETWORK_DEVICE_OFFLINE     = 601,
+       MESSAGE_PLUGIN_ERROR_NETWORK_DEVICE_CONFUSED    = 602,
+       MESSAGE_PLUGIN_ERROR_NETWORK_SOCKET_ISSUE       = 603,
+       MESSAGE_PLUGIN_ERROR_NETWORK_SERVER_NOT_RESPONSE= 604,
+       MESSAGE_PLUGIN_ERROR_NEWTORK_ETC                = 648,
+       MESSAGE_PLUGIN_ERROR_NEWTORK_UNKNOWN            = 649,
+
+       MESSAGE_PLUGIN_ERROR_AUTH_FAILED                = 701,
+       MESSAGE_PLUGIN_ERROR_AUTH_ETC                   = 718,
+       MESSAGE_PLUGIN_ERROR_AUTH_UNKNOWN               = 719,
+
+       MESSAGE_PLUGIN_ERROR_MEMORY_ALLOCATION_FAILED   = 801,
+       MESSAGE_PLUGIN_ERROR_MEMORY_ETC                 = 808,
+       MESSAGE_PLUGIN_ERROR_MEMORY_UNKNOWN             = 809,
+
+       MESSAGE_PLUGIN_ERROR_THREAD_CREATE_FAILED       = 821,
+       MESSAGE_PLUGIN_ERROR_THREAD_STOPPED             = 822,
+       MESSAGE_PLUGIN_ERROR_THREAD_ETC                 = 828,
+       MESSAGE_PLUGIN_ERROR_THREAD_UNNOWN              = 829,
+
+       MESSAGE_PLUGIN_ERROR_ETC                        = 998,
+       MESSAGE_PLUGIN_ERROR_UNKNOWN                    = 999,
+} message_plugin_internal_error_code_e;
+
+typedef enum _message_connection_policy_e
+{
+       MESSAGE_CONNECTION_POLICY_AUTO          = 0,
+       MESSAGE_CONNECTION_POLICY_CONNECT       = 1,
+       MESSAGE_CONNECTION_POLICY_DISCONNECT    = 2,
+} message_connection_policy_e;
+
+/**
+ * @ brief Message plugin's TCP connection state flag
+ */
+typedef enum message_connection_state_e
+{
+       MESSAGE_CONNECTION_STATE_INIT           = 0,    // init value (after create_context)
+       MESSAGE_CONNECTION_STATE_READY          = 1,    // thread running (after connect) before channel_auth
+       MESSAGE_CONNECTION_STATE_CONNECT        = 2,    // connection authenticated (after channel_auth_reply)
+       MESSAGE_CONNECTION_STATE_DISCONNECTED   = 3,    // connection was stopped explicitly (after disconnect)
+       MESSAGE_CONNECTION_STATE_INTERRUPTED    = 4,    // connection was stopped inadventently (by network/server/etc issue)
+       MESSAGE_CONNECTION_STATE_MAX            = 5,
+} message_connection_state_t;
+
+/**
+ * @ brief Message adaptor plugin handle
+ */
+typedef struct message_adaptor_plugin_s *message_adaptor_plugin_h;
+
+/**
+ * @ brief Message adaptor
+ */
+typedef struct message_adaptor_s *message_adaptor_h;
+
+/**
+ * @ brief Message adaptor error code
+ */
+typedef struct message_adaptor_error_code_s
+{
+       char *code;
+       char *msg;
+} message_adaptor_error_code_t;
+typedef struct message_adaptor_error_code_s *message_adaptor_error_code_h;
+
+/**
+ * @ brief Message adaptor violated user structure
+ */
+typedef struct message_adaptor_did_violation_users_s
+{
+       long long int usera;
+       long long int userb;
+} message_adaptor_did_violation_users_t;
+typedef struct message_adaptor_did_violation_users_s *message_adaptor_did_violation_users_h;
+
+/**
+ * @ brief Message adaptor wrong receiver structure
+ */
+typedef struct
+{
+       long long int *invalid_receivers;
+       unsigned int invalid_receivers_len;
+       long long int *interrupted_receivers;
+       unsigned int interrupted_receivers_len;
+       long long int *disabled_receivers;
+       unsigned int disabled_receivers_len;
+       long long int *existing_chatmember;
+       unsigned int existing_chatmembers_len;
+       struct message_adaptor_did_violation_users_s * did_violation_users;
+       unsigned int did_violation_users_len;
+       long long int *invitation_denieds;
+       unsigned int invitation_denieds_len;
+} message_adaptor_wrong_receiver_s;
+
+/**
+ * @ brief Message adaptor chat message structure
+ */
+typedef struct
+{
+       long long int msg_id;
+       int msg_type;
+       char *chatmsg;
+       int message_ttl;
+} message_adaptor_chat_msg_s;
+
+/**
+ * @ brief Message adaptor processed message structure
+ */
+typedef struct
+{
+       long long int msg_id;
+       long long int sent_time;
+} message_adaptor_processed_msg_s;
+
+/**
+ * @ brief Message adaptor deliveryAck structure
+ */
+typedef struct
+{
+       long long int userId;
+       long long int msgId;
+       long long int timestamp;
+} message_adaptor_delivery_ack_s;
+
+/**
+ * @ brief Message adaptor read_ack structure
+ */
+typedef struct
+{
+       long long int userId;
+       long long int msgId;
+       long long int timestamp;
+} message_adaptor_read_ack_s;
+
+/**
+ * @ brief Message adaptor ordered chat member structure
+ */
+typedef struct
+{
+       long long int userId;
+       long long int available;
+       char *name;
+} message_adaptor_ordered_chat_member_s;
+
+/**
+ * @ brief Message adaptor inbox entry structure
+ */
+typedef struct _message_inboxentry
+{
+       long long int msgId;
+       int msgType;
+       long long int sender;
+       long long int receiver;
+       long long int sentTime;
+       char *chatMsg;
+       long long int chatroomId;
+       int chatType;
+       int message_ttl;
+} message_inboxentry_t;
+
+typedef message_inboxentry_t message_adaptor_inbox_message_s;
+
+/**
+ * @ brief Message adaptor plugin context structure
+ */
+typedef struct message_adaptor_plugin_context_s
+{
+       long long int duid;
+       char *access_token;
+       char *app_id;
+       int service_id;
+       char *app_key;
+       char *uid;
+       char *imei;
+       char *imsi;
+
+       GMutex connection_state_mutex;
+       message_connection_state_t connection_state;
+       message_connection_policy_e connection_policy;
+
+       // Encryption
+       unsigned char enc_key[32];
+       unsigned char enc_vec[16];
+       //bool enc_key_updated;
+       unsigned char gpb_key[32];
+       unsigned char gpb_vec[16];
+       //bool gpb_key_updated;
+       unsigned char exp_key[32];
+       unsigned char exp_vec[16];
+       //bool exp_key_updated;
+
+       char *plugin_uri;
+
+       GMutex plugin_data_mutex;
+       void *plugin_data;
+} message_adaptor_plugin_context_t;
+
+typedef struct message_adaptor_plugin_context_s *message_adaptor_plugin_context_h;
+
+/**
+ * @ brief Message adaptor result code for internal use
+ */
+typedef enum message_plugin_result_code_e
+{
+       MESSAGE_PLUGIN_RESULT_SUCCEDED = 0,
+       MESSAGE_PLUGIN_RESULT_FAILED = -1,
+       MESSAGE_PLUGIN_RESULT_CANCELED = -2
+} message_plugin_result_code_t;
+
+typedef struct curl_cb_data_s
+{
+       char *data;
+       int size;
+} curl_cb_data_t;
+
+/**
+ * @ brief Message adaptor phone number structure
+ */
+typedef struct
+{
+       char *phonenumber;
+       char *ccc;
+} message_adaptor_phone_number_s;
+
+/**
+ * @ brief Message adaptor chat id structure
+ */
+typedef struct
+{
+       long long int chatid;
+       char *msisdn;
+} message_adaptor_chat_id_s;
+
+/**
+ * @ brief Message adaptor end chat structure
+ */
+typedef struct {
+       long long int chatroom_id;
+       bool deny_invitation;
+} message_adaptor_end_chat_s;
+
+void message_adaptor_destroy_chat_msg_s(message_adaptor_chat_msg_s *msg);
+void message_adaptor_destroy_processed_msg_s(message_adaptor_processed_msg_s *msg);
+void message_adaptor_destroy_delivery_ack_s(message_adaptor_delivery_ack_s *ack);
+void message_adaptor_destroy_read_ack_s(message_adaptor_read_ack_s *ack);
+void message_adaptor_destroy_ordered_chat_member_s(message_adaptor_ordered_chat_member_s *member);
+void message_adaptor_destroy_inbox_message_s(message_adaptor_inbox_message_s *msg);
+void message_adaptor_destroy_phone_number_s(message_adaptor_phone_number_s *num);
+void message_adaptor_destroy_chat_id_s(message_adaptor_chat_id_s *id);
+void message_adaptor_destroy_end_chat_s(message_adaptor_end_chat_s *msg);
+
+/**
+* @brief The handle for Message Plugin Listener
+*/
+typedef struct message_adaptor_plugin_listener_s *message_adaptor_plugin_listener_h;
+
+/**
+ * @ brief Message adaptor plugin handle
+ */
+typedef struct message_adaptor_plugin_handle_s
+{
+       // Mandatory functions to handle plugin in adaptor
+       //struct message_adaptor_plugin_handle_s * (*create_plugin_handle)(void);
+       message_error_code_t (*create_context)(message_adaptor_plugin_context_h *context,
+                                                       char *duid,
+                                                       char *access_token,
+                                                       char *app_id,
+                                                       int service_id);
+
+       message_error_code_t (*destroy_context)(message_adaptor_plugin_context_h context);
+
+       message_error_code_t (*destroy_handle)(struct message_adaptor_plugin_handle_s *handle);
+       message_error_code_t (*set_listener)(message_adaptor_plugin_listener_h listener);
+       message_error_code_t (*unset_listener)(void);
+
+       message_error_code_t (*set_server_info)(message_adaptor_plugin_context_h context,
+                                                       GHashTable *server_info,
+                                                       void *request,
+                                                       message_adaptor_error_code_h *error,
+                                                       void *response);
+
+       message_error_code_t (*get_key)(message_adaptor_plugin_context_h handle,
+                                                       char **in_uid,
+                                                       char **in_gcmid,
+                                                       char **in_del_gcm_id,
+                                                       char **key,
+                                                       char **expiredkey,
+                                                       char **gpbauthkey,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void **server_data);
+
+       message_error_code_t (*request_chat_id) (message_adaptor_plugin_context_h handle,
+                                                       char *uid,
+                                                       message_adaptor_phone_number_s **phone_numbers,
+                                                       unsigned int phone_numbers_len,
+                                                       void *user_data,
+                                                       message_adaptor_chat_id_s ***chat_ids,
+                                                       unsigned int *chat_ids_len,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void **server_data);
+
+       message_error_code_t (*request_msisdn) (message_adaptor_plugin_context_h handle,
+                                                       char *uid,
+                                                       long long int *chat_ids,
+                                                       unsigned int chat_ids_len,
+                                                       void *user_data,
+                                                       message_adaptor_chat_id_s ***msisdns,
+                                                       unsigned int *msisdns_len,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void **server_data);
+
+       message_error_code_t (*channel_auth_request)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       const char *uid,
+                                                       long long int duid,
+                                                       const char *appid,
+                                                       const char *access_token,
+                                                       int timeout_second,
+                                                       void *user_data,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       message_error_code_t (*client_echo_reply) (message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*create_chatroom_request)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       int *chat_type,
+                                                       long long int **receivers,
+                                                       int *receivers_len,
+                                                       const char *chatroom_title,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*change_chatroom_meta_request)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       const char *chatroom_title,
+                                                       int default_message_ttl,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*chat_request)(message_adaptor_plugin_context_h context,\
+                                                       long long int *request_id,
+                                                       long long int *chatroom_id,
+                                                       message_adaptor_chat_msg_s *msgs,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*allow_chat_request)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       long long int *chatroom_id,
+                                                       bool is_auto_allow,
+                                                       int max_count,
+                                                       bool need_delivery_ack,
+                                                       long long int delivery_ack_timestamp,
+                                                       bool need_read_ack,
+                                                       long long int last_read_ack_timestamp,
+                                                       bool need_ordered_chat_member_list,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*get_all_unread_message_request)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       int *max_count,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+
+       message_error_code_t (*forward_online_message_reply)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       long long int *chatroom_id,
+                                                       bool *mark_as_read,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*forward_unread_message_reply)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       const char **next_pagination_key,
+                                                       int *max_count,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*read_message_request)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       long long int *chatroom_id,
+                                                       message_inboxentry_t *inbox_msg,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*invite_request)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       long long int *chatroom_id,
+                                                       long long int *inviting_members,
+                                                       int *inviting_members_len,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*end_chat_request)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       message_adaptor_end_chat_s **end_chats,
+                                                       int *end_chats_len,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*unseal_message_request)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       long long int *chatroom_id,
+                                                       long long int *sender_id,
+                                                       long long int *message_id,
+                                                       const char *message_detail,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*save_call_log_request)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       long long int *chatroom_id,
+                                                       const char **call_id,
+                                                       const char **call_log_type,
+                                                       long long int *call_sender_id,
+                                                       long long int *call_receiver_id,
+                                                       int *conversaction_second,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*current_time_request)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       message_error_code_t (*is_typing)(message_adaptor_plugin_context_h context,
+                                                       long long int *request_id,
+                                                       long long int *chatroom_id,
+                                                       char **state,
+                                                       int *chat_type,
+                                                       int *refreshtime,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *user_data);
+
+       //message_error_code_t (*message_set_key)(message_adaptor_plugin_context_h context, char *key, bool is_gpb);
+       message_error_code_t (*connect_to_server)(message_adaptor_plugin_context_h context);
+       message_error_code_t (*decode_push_message)(message_adaptor_plugin_context_h context, char *in_msg, char **out_msg);
+       message_error_code_t (*disconnect_to_server)(message_adaptor_plugin_context_h context);
+       message_error_code_t (*get_connection_state)(message_adaptor_plugin_context_h context,
+                                                       message_connection_state_t *state);
+       char *plugin_uri;               // get from config file
+
+} message_adaptor_plugin_handle_t;
+typedef struct message_adaptor_plugin_handle_s *message_adaptor_plugin_handle_h;
+
+
+/**
+ * Callback function variable for service channel (= service adaptor)
+ */
+
+/**
+* @brief Callback for ClientEcho API(sent from remote server, referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data     specifies additional reply data from server(unused)
+* @pre  ClientEcho()(requested by remote server) will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_client_echo_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_create_chatroom_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   chatroom_id             specifies chatroom id
+* @param[in]   wrong_receiver  specifies wrong receivers information
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_create_chatroom_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_create_chatroom_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               int default_message_ttl,
+                                               message_adaptor_wrong_receiver_s *wrong_receiver,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+typedef void (*message_adaptor_service_change_chatroom_meta_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_chat_request API (referenced by Service Adaptor)
+* @param[in]   request_id                      specifies request id for received data
+* @param[in]   chatroom_id                     specifies chatroom id
+* @param[in]   processed_msgs          specifies processed message information
+* @param[in]   processed_msgs_len      specifies the number of processed message
+* @param[in]   error_code                      specifies error code
+* @param[in]   server_data                     specifies additional reply data from server(unused)
+* @pre  message_adaptor_chat_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_chat_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_processed_msg_s **processed_msgs,
+                                               unsigned int processed_msgs_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_allow_chat_request API (referenced by Service Adaptor)
+* @param[in]   request_id                                      specifies request id for received data
+* @param[in]   chatroom_id                                     specifies chatroom id
+* @param[in]   deliveryacks                                    specifies last receipt messages information for each user
+* @param[in]   deliveryacks_len                                specifies the number of deliveryacks
+* @param[in]   read_acks                                       specifies last read message information for each user
+* @param[in]   read_acks_len                           specifies the number of wartermarks
+* @param[in]   ordered_chat_members                    specifies chat member list aligned to participation order
+* @param[in]   ordered_chat_members_len                specifies the number of ordered_chat_members
+* @param[in]   error_code                                      specifies error code
+* @param[in]   server_data                                     specifies additional reply data from server(unused)
+* @pre  message_adaptor_allow_chat_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_allow_chat_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_delivery_ack_s **deliveryacks,
+                                               unsigned int deliveryacks_len,
+                                               unsigned long long last_delivery_ack_timestamp,
+                                               message_adaptor_read_ack_s **read_acks,
+                                               unsigned int read_acks_len,
+                                               unsigned long long last_read_ack_timestamp,
+                                               message_adaptor_ordered_chat_member_s **ordered_chat_members,
+                                               unsigned int ordered_chat_members_len,
+                                               const char *chatroom_title,
+                                               int default_message_ttl,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_get_all_unread_message_request API (referenced by Service Adaptor)
+* @param[in]   request_id      specifies request id for received data
+* @param[in]   error_code      specifies error code
+* @param[in]   server_data     specifies additional reply data from server(unused)
+* @pre  message_adaptor_get_all_unread_message_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_get_all_unread_message_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for ForwardOnlineMessage API (sent from remote server, referenced by Service Adaptor)
+* @details This function is used for transferring a message from server to client requested by user
+*                who sent request messages via message_adaptor_chat_request()
+* @param[in]   request_id      specifies request id for received data
+* @param[in]   chatroom_id     specifies chatroom id
+* @param[in]   chat_type               specifies chat room type(0: SINGLE, 1: GROUP)
+* @param[in]   inbox_msg       specifies one message transferred from sender to receiver
+* @param[in]   error_code      specifies error code
+* @param[in]   server_data     specifies additional reply data from server(unused)
+* @pre  ForwardOnlineMessage()(requested by remote server) will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_forward_online_message_request_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               int chat_type,
+                                               message_inboxentry_t *inbox_msg,
+                                               bool skip_reply,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for ForwardUnreadMessage API (sent from remote server, referenced by Service Adaptor)
+* @details This function is used for transferring unread messages from server to client requested by user
+*                who sent request messages via message_adaptor_get_all_unread_message_request() or
+*                message_adaptor_allow_chat_request()
+* @param[in]   request_id                      specifies request id for received data
+* @param[in]   inbox_msgs                      specifies messages transferred from sender to receiver
+* @param[in]   inbox_msg_len           specifies the number of inbox message
+* @param[in]   next_pagination_key     specifies value for using pagination(NULL for unused case)
+* @param[in]   error_code                      specifies error code
+* @param[in]   server_data                     specifies additional reply data from server(unused)
+* @pre  ForwardUnreadMessage()(requested by remote server) will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_forward_unread_message_request_cb) (message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_inboxentry_t ***inbox_msgs,
+                                               unsigned int inbox_msgs_len,
+                                               char **next_pagination_key,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_read_message_request API (referenced by Service Adaptor)
+* @param[in]   request_id      specifies request id for received data
+* @param[in]   chatroom_id     specifies chatroom id
+* @param[in]   error_code      specifies error code
+* @param[in]   server_data     specifies additional reply data from server(unused)
+* @pre  message_adaptor_read_message_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_read_message_reply_cb) (message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_invite_chat_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   chatroom_id             specifies chatroom id
+* @param[in]   sent_time               specifies time when server received request message by client
+* @param[in]   wrong_receiver  specifies wrong receivers information
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_invite_chat_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_invite_chat_reply_cb) (message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               long long int sent_time,
+                                               message_adaptor_wrong_receiver_s *wrong_receiver,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_end_chat_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_end_chat_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_end_chat_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_unseal_message_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_unseal_message_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_unseal_message_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_save_call_log_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_save_call_log_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_save_call_log_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+
+/**
+* @brief Callback for message_adaptor_current_time_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   current_time_millis     specifies current UTC time in milliseconds
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_current_time_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_service_current_time_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int current_time_millis,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+typedef void (*message_adaptor_service_typing_updated_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               long long int *sender,
+                                               char ** state,
+                                               int *contentType,
+                                               int *refershTime,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for notification of termination of Listener(referenced by Service Adaptor)
+* @details This function called when channel is disconnected by server
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @return      void.
+*/
+typedef void (*message_adaptor_service_completion_cb)(message_adaptor_plugin_context_h context,
+                                               message_connection_state_t state,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+
+
+typedef struct message_adaptor_listener_s
+{
+       void (*client_echo_cb)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*create_chatroom_reply_cb)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       int default_message_ttl,
+                                                       message_adaptor_wrong_receiver_s *wrong_receiver,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*change_chatroom_meta_reply_cb)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*chat_reply_cb)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       message_adaptor_processed_msg_s **processed_msgs,
+                                                       unsigned int processed_msgs_len,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*allow_chat_reply_cb) (message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       message_adaptor_delivery_ack_s **deliveryacks,
+                                                       unsigned int deliveryacks_len,
+                                                       unsigned long long last_delivery_ack_timestamp,
+                                                       message_adaptor_read_ack_s **read_acks,
+                                                       unsigned int read_acks_len,
+                                                       unsigned long long last_read_ack_timestamp,
+                                                       message_adaptor_ordered_chat_member_s **ordered_chat_members,
+                                                       unsigned int ordered_chat_members_len,
+                                                       const char *chatroom_title,
+                                                       int default_message_ttl,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+
+       void (*get_all_unread_message_reply_cb) (message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*forward_online_message_request_cb)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       int chat_type,
+                                                       message_inboxentry_t *inbox_msg,
+                                                       bool skip_reply,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+
+       void (*forward_unread_message_request_cb)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       message_inboxentry_t ***inbox_msgs,
+                                                       unsigned int inbox_msgs_len,
+                                                       char **next_pagination_key,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*read_message_reply_cb) (message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*invite_chat_reply_cb) (message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       long long int sent_time,
+                                                       message_adaptor_wrong_receiver_s *wrong_receiver,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*end_chat_reply_cb) (message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*unseal_message_reply_cb) (message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*save_call_log_reply_cb) (message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*current_time_reply_cb)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int current_time_millis,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*typing_updated_cb)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       long long int *sender,
+                                                       char ** state,
+                                                       int *contentType,
+                                                       int *refershTime,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+
+       void (*completion_cb)(message_adaptor_plugin_context_h context,
+                                                       message_connection_state_t state,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data );
+
+
+} message_adaptor_listener_t;
+typedef struct message_adaptor_listener_s *message_adaptor_listener_h;
+
+
+/**
+ * Message adaptor listener for plugins
+ * Listener is used by plugins
+ */
+
+
+/**
+* @brief Callback for ClientEcho API(sent from remote server)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data     specifies additional reply data from server(unused)
+* @pre  ClientEcho()(requested by remote server) will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_client_echo_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_plugin_handle->create_chatroom_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   chatroom_id             specifies chatroom id
+* @param[in]   wrong_receiver  specifies wrong receivers information
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_plugin_handle->create_chatroom_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_create_chatroom_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               int default_message_ttl,
+                                               message_adaptor_wrong_receiver_s *wrong_receiver,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+typedef void (*message_adaptor_plugin_change_chatroom_meta_reply_cb)(message_adaptor_plugin_context_h context,
+                                                       long long int request_id,
+                                                       long long int chatroom_id,
+                                                       message_adaptor_error_code_t **error_code,
+                                                       void *server_data);
+/**
+* @brief Callback for message_adaptor_plugin_handle->chat_request API (referenced by Service Adaptor)
+* @param[in]   request_id                      specifies request id for received data
+* @param[in]   chatroom_id                     specifies chatroom id
+* @param[in]   processed_msgs          specifies processed message information
+* @param[in]   processed_msgs_len      specifies the number of processed message
+* @param[in]   error_code                      specifies error code
+* @param[in]   server_data                     specifies additional reply data from server(unused)
+* @pre  message_adaptor_plugin_handle->chat_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_chat_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_processed_msg_s **processed_msgs,
+                                               unsigned int processed_msgs_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_plugin_handle->allow_chat_request API (referenced by Service Adaptor)
+* @param[in]   request_id                                      specifies request id for received data
+* @param[in]   chatroom_id                                     specifies chatroom id
+* @param[in]   deliveryacks                                    specifies last receipt messages information for each user
+* @param[in]   deliveryacks_len                                specifies the number of deliveryacks
+* @param[in]   read_acks                                       specifies last read message information for each user
+* @param[in]   read_acks_len                           specifies the number of wartermarks
+* @param[in]   ordered_chat_members                    specifies chat member list aligned to participation order
+* @param[in]   ordered_chat_members_len                specifies the number of ordered_chat_members
+* @param[in]   error_code                                      specifies error code
+* @param[in]   server_data                                     specifies additional reply data from server(unused)
+* @pre  message_adaptor_plugin_handle->allow_chat_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_allow_chat_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_delivery_ack_s **deliveryacks,
+                                               unsigned int deliveryacks_len,
+                                               unsigned long long last_delivery_ack_timestamp,
+                                               message_adaptor_read_ack_s **read_acks,
+                                               unsigned int read_acks_len,
+                                               unsigned long long last_read_ack_timestamp,
+                                               message_adaptor_ordered_chat_member_s **ordered_chat_members,
+                                               unsigned int ordered_chat_members_len,
+                                               const char *chatroom_title,
+                                               int default_message_ttl,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_plugin_handle->get_all_unread_message_request API (referenced by Service Adaptor)
+* @param[in]   request_id      specifies request id for received data
+* @param[in]   error_code      specifies error code
+* @param[in]   server_data     specifies additional reply data from server(unused)
+* @pre  message_adaptor_plugin_handle->get_all_unread_message_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_get_all_unread_message_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for ForwardOnlineMessage API (sent from remote server, referenced by Service Adaptor)
+* @details This function is used for transferring a message from server to client requested by user
+*                who sent request messages via message_adaptor_chat_request()
+* @param[in]   request_id      specifies request id for received data
+* @param[in]   chatroom_id     specifies chatroom id
+* @param[in]   chat_type               specifies chat room type(0: SINGLE, 1: GROUP)
+* @param[in]   inbox_msg       specifies one message transferred from sender to receiver
+* @param[in]   error_code      specifies error code
+* @param[in]   server_data     specifies additional reply data from server(unused)
+* @pre  ForwardOnlineMessage()(requested by remote server) will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_forward_online_message_request_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               int chat_type,
+                                               message_inboxentry_t *inbox_msg,
+                                               bool skip_reply,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for ForwardUnreadMessage API (sent from remote server, referenced by Service Adaptor)
+* @details This function is used for transferring unread messages from server to client requested by user
+*                who sent request messages via message_adaptor_get_all_unread_message_request() or
+*                message_adaptor_allow_chat_request()
+* @param[in]   request_id                      specifies request id for received data
+* @param[in]   inbox_msgs                      specifies messages transferred from sender to receiver
+* @param[in]   inbox_msg_len           specifies the number of inbox message
+* @param[in]   next_pagination_key     specifies value for using pagination(NULL for unused case)
+* @param[in]   error_code                      specifies error code
+* @param[in]   server_data                     specifies additional reply data from server(unused)
+* @pre  ForwardUnreadMessage()(requested by remote server) will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_forward_unread_message_request_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_inboxentry_t ***inbox_msgs,
+                                               unsigned int inbox_msgs_len,
+                                               char **next_pagination_key,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_plugin_handle->read_message_request API (referenced by Service Adaptor)
+* @param[in]   request_id      specifies request id for received data
+* @param[in]   chatroom_id     specifies chatroom id
+* @param[in]   error_code      specifies error code
+* @param[in]   server_data     specifies additional reply data from server(unused)
+* @pre  message_adaptor_plugin_handle->read_message_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_read_message_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_plugin_handle->invite_chat_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   chatroom_id             specifies chatroom id
+* @param[in]   sent_time               specifies time when server received request message by client
+* @param[in]   wrong_receiver  specifies wrong receivers information
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_plugin_handle->invite_chat_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_invite_chat_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               long long int sent_time,
+                                               message_adaptor_wrong_receiver_s *wrong_receiver,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_plugin_handle->end_chat_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_plugin_handle->end_chat_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_end_chat_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_plugin_handle->unseal_message_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   chatroom_id             specifies chatroom id
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_plugin_handle->end_chat_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_unseal_message_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for message_adaptor_plugin_handle->save_call_log_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre  message_adaptor_plugin_handle->save_call_log_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_save_call_log_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+
+/**
+* @brief Callback for  message_adaptor_plugin_handle->current_time_request API (referenced by Service Adaptor)
+* @param[in]   request_id              specifies request id for received data
+* @param[in]   current_time_millis     specifies current UTC time in milliseconds
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @pre   message_adaptor_plugin_handle->current_time_request() will invoke this callback.
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_current_time_reply_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int current_time_millis,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+typedef void (*message_adaptor_plugin_typing_updated_cb)(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               long long int *sender,
+                                               char ** state,
+                                               int *contentType,
+                                               int *refershTime,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Callback for notification of termination of Listener(referenced by Service Adaptor)
+* @details This function called when channel is disconnected by server
+* @param[in]   error_code              specifies error code
+* @param[in]   server_data             specifies additional reply data from server(unused)
+* @return      void.
+*/
+typedef void (*message_adaptor_plugin_completion_cb)(message_adaptor_plugin_context_h context,
+                                               message_connection_state_t state,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+ * Message adaptor listener for plugins
+ * Listener is used by plugins
+ */
+typedef struct message_adaptor_plugin_listener_s
+{
+       message_adaptor_plugin_client_echo_cb message_adaptor_client_echo;
+       message_adaptor_plugin_create_chatroom_reply_cb message_adaptor_create_chatroom_reply;
+       message_adaptor_plugin_change_chatroom_meta_reply_cb message_adaptor_change_chatroom_meta_reply;
+       message_adaptor_plugin_chat_reply_cb message_adaptor_chat_reply;
+       message_adaptor_plugin_allow_chat_reply_cb message_adaptor_allow_chat_reply;
+       message_adaptor_plugin_get_all_unread_message_reply_cb message_adaptor_get_all_unread_message_reply;
+       message_adaptor_plugin_forward_online_message_request_cb message_adaptor_forward_online_message_request;
+       message_adaptor_plugin_forward_unread_message_request_cb message_adaptor_forward_unread_message_request;
+       message_adaptor_plugin_read_message_reply_cb message_adaptor_read_message_reply;
+       message_adaptor_plugin_invite_chat_reply_cb message_adaptor_invite_chat_reply;
+       message_adaptor_plugin_end_chat_reply_cb message_adaptor_end_chat_reply;
+       message_adaptor_plugin_unseal_message_reply_cb message_adaptor_unseal_message_reply;
+       message_adaptor_plugin_save_call_log_reply_cb message_adaptor_save_call_log_reply;
+       message_adaptor_plugin_current_time_reply_cb message_adaptor_current_time_reply;
+       message_adaptor_plugin_typing_updated_cb message_adaptor_typing_updated;
+       message_adaptor_plugin_completion_cb message_adaptor_completion;
+
+} message_adaptor_plugin_listener_t;
+
+/**
+ * Loads plugin from selected path
+ */
+ EXPORT_API
+int message_adaptor_load_plugin(message_adaptor_h adaptor, const char *plugin_path);
+
+/**
+ * Unloads selected plugin
+ */
+ EXPORT_API
+int message_adaptor_unload_plugin(message_adaptor_h adaptor, message_adaptor_plugin_h plugin);
+
+ EXPORT_API
+message_error_code_t message_adaptor_set_connected(message_adaptor_plugin_h plugin, int connected);
+
+ EXPORT_API
+message_error_code_t message_adaptor_wait_connected(message_adaptor_plugin_h plugin);
+
+/**
+ * Gets plugin name
+ */
+ EXPORT_API
+const char *message_adaptor_get_plugin_uri(message_adaptor_plugin_h plugin);
+
+/**
+ * Refresh access token
+ */
+EXPORT_API
+message_error_code_t message_adaptor_refresh_access_token(message_adaptor_plugin_context_h context,
+                                               const char *new_access_token);
+
+/**
+ * Refresh uid
+ */
+EXPORT_API
+message_error_code_t message_adaptor_refresh_uid(message_adaptor_plugin_context_h context,
+                                               const char *new_uid);
+
+/**
+ * Create error code
+ */
+EXPORT_API
+message_adaptor_error_code_h message_adaptor_create_error_code(const char *code, const char *msg);
+
+/**
+ * Destroy error code
+ */
+EXPORT_API
+void message_adaptor_destroy_error_code(message_adaptor_error_code_h *error_code);
+
+/**
+ * Creates message adaptor
+ */
+EXPORT_API
+message_adaptor_h message_adaptor_create(const char *plugins_dir);
+
+/**
+ * Destroys message adaptor
+ * Destroys message adaptor. If message adaptor was started it is stopped first.
+ */
+EXPORT_API
+void message_adaptor_destroy(message_adaptor_h adaptor);
+
+/**
+ * Starts message adaptor
+ * Starts message adaptor and loads plugins that were found in plugins search dir
+ * specified in message_adaptor_create
+ */
+EXPORT_API
+int message_adaptor_start(message_adaptor_h adaptor);
+
+/**
+ * Stops message adaptor.
+ */
+EXPORT_API
+int message_adaptor_stop(message_adaptor_h adaptor);
+
+/**
+ * Registers plugin state listener
+ */
+EXPORT_API
+int message_adaptor_register_listener(message_adaptor_h adaptor, message_adaptor_listener_h listener);
+
+/**
+ * Unregisters plugin state listener
+ */
+EXPORT_API
+int message_adaptor_unregister_listener(message_adaptor_h adaptor, message_adaptor_listener_h listener);
+
+/**
+ * Creates plugin context.
+ */
+EXPORT_API
+message_adaptor_plugin_context_h message_adaptor_create_plugin_context(message_adaptor_plugin_h plugin,
+                                               char *plugin_uri,
+                                               char *duid,
+                                               char *access_token,
+                                               char *app_id,
+                                               int service_id);
+
+/**
+ * Destroys plugin context.
+ */
+EXPORT_API
+void message_adaptor_destroy_plugin_context(message_adaptor_plugin_h plugin, message_adaptor_plugin_context_h plugin_context);
+
+/**
+ * Gets plugin with specified unique name
+ */
+EXPORT_API
+message_adaptor_plugin_h message_adaptor_get_plugin_by_name(message_adaptor_h adaptor, const char *plugin_uri);
+
+////////////////////////////////////////////////////////////
+// Adaptor Plugin call Functions
+////////////////////////////////////////////////////////////
+
+/**
+* @brief Set server information for Message Plugin
+*
+* @param[in]   plugin                          specifies Message Adaptor Plugin handle
+* @param[in]   context                         specifies Message Adaptor Plugin Context handle
+* @param[in]   server_info                     specifies server information for Message Plugin
+* @param[in]   request                         specifies optional parameter
+* @param[out]  error                           specifies error code
+* @param[out]  response                        specifies optional parameter
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t - MESSAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+message_error_code_t message_adaptor_set_server_info(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               GHashTable *server_info,
+                                               void *request,
+                                               message_adaptor_error_code_h *error,
+                                               void *response);
+/**
+* @brief Request encryption/decryption key from remote server
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   in_gcmid                specifies GCM Registration ID for use of Google Cloud Messaging
+* @param[in]   in_del_gcm_id   specifies Paramter for deletion of gcmid in db
+* @param[out]  key                     specifies user key for en/decryption of messages
+* @param[out]  expiredkey      specifies expired key
+* @param[out]  gpbauthkey      specifies system key for en/decryption of ChannelAuth Request/Reply messages
+* @param[out]  error_code      specifies error code
+* @param[out]  server_data     specifies additional reply data from server(JSON format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in message_error_code_e - MESSAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+message_error_code_t message_adaptor_get_key(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               char **in_gcmid,
+                                               char **in_del_gcm_id,
+                                               char **key,
+                                               char **expiredkey,
+                                               char **gpbauthkey,
+                                               message_adaptor_error_code_t **error_code,
+                                               void **server_data);
+
+/**
+* @brief Request Chat ID corresponds to MSISDN to remote server
+* @param[in]   plugin                          specifies Message-adaptor Plugin handle
+* @param[in]   context                         specifies Message-adaptor Plugin context
+* @param[in]   phone_numbers           specifies List of phone numbers to request chat id
+* @param[in]   phone_numbers_len       specifies the number of phone numbers
+* @param[in]   user_data                       specifies additional input data(JSON format, unused)
+* @param[out]  chat_ids                                specifies chat ids correspond to requested phone numbers
+* @param[out]  chat_ids_len                    specifies the number of chat ids
+* @param[out]  error_code                      specifies error code
+* @param[out]  server_data                     specifies additional reply data from server(JSON format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in message_error_code_e - MESSAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+message_error_code_t message_adaptor_request_chat_id(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h handle,
+                                               message_adaptor_phone_number_s **phone_numbers,
+                                               unsigned int phone_numbers_len,
+                                               void *user_data,
+                                               message_adaptor_chat_id_s ***chat_ids,
+                                               unsigned int *chat_ids_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void **server_data);
+
+/**
+* @brief Request MSISDN corresponds to CHAT ID to remote server
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   chat_ids                specifies chat ids correspond to requested phone numbers
+* @param[in]   chat_ids_len    specifies the number of chat ids
+* @param[in]   user_data       specifies additional input data(JSON format, unused)
+* @param[out]  msisdn          specifies List of phone numbers to request chat id
+* @param[out]  msisdn_len      specifies the number of phone numbers
+* @param[out]  error_code      specifies error code
+* @param[out]  server_data     specifies additional reply data from server(JSON format)
+* @return 0 on success, otherwise a positive error value
+* @retval error code defined in message_error_code_e - MESSAGE_ADAPTOR_ERROR_NONE if Successful
+*/
+EXPORT_API
+message_error_code_t message_adaptor_request_msisdn (message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h handle,
+                                               long long int *chat_ids,
+                                               unsigned int chat_ids_len,
+                                               void *user_data,
+                                               message_adaptor_chat_id_s ***msisdns,
+                                               unsigned int *msisdns_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void **server_data);
+
+
+/**
+* @brief Channel Authorization Request.
+*
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   request_id      specifies unique request ID
+* @param[in]   timeout_second  specifies timeout second for wating this function (default = 0 : as long as possible be allowed by plugin)
+* @param[in]   user_data       specifies additional user input data (unused)
+* @param[out]  error_code      specifies error code
+* @param[out]  server_data     specifies additional server output data (unused)
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_channel_auth_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               const int timeout_second,
+                                               void *user_data,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Client Echo Reply.(Client -> Server)
+*
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   request_id      specifies unique request ID
+* @param[in]   error_code      specifies error code
+* @param[in]   server_data     specifies server data to be sent(not used)
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_client_echo_reply (message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data);
+
+/**
+* @brief Create Chatroom Request.
+*
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   request_id      specifies unique request ID
+* @param[in]   chattype                specifies chat type (0 - SINGLE, 1 - GROUP)
+* @param[in]   receivers               specifies the receivers devices ID
+* @param[in]   receivers_len   specifies the number of receivers
+* @param[in]   user_data       specifies additional user input data (unused)
+* @param[out]  error_code      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_create_chatroom_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               int chat_type,
+                                               long long int **receivers,
+                                               unsigned int receivers_len,
+                                               const char *chatroom_title,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief Change Chatroom meta Request.
+*
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   request_id      specifies unique request ID
+* @param[in]   chattype                specifies chat type (0 - SINGLE, 1 - GROUP)
+* @param[in]   receivers               specifies the receivers devices ID
+* @param[in]   receivers_len   specifies the number of receivers
+* @param[in]   user_data       specifies additional user input data (unused)
+* @param[out]  error_code      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_change_chatroom_meta_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               const char *chatroom_title,
+                                               int default_message_ttl,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+/**
+* @brief Chat Request.
+*
+* @param[in]   plugin                  specifies Message-adaptor Plugin handle
+* @param[in]   context                 specifies Message-adaptor Plugin context
+* @param[in]   request_id              specifies unique request ID
+* @param[in]   chatroom_id             specifies chatroom ID
+* @param[in]   chat_msgs               specifies message data
+* @param[in]   chat_msgs_len   specifies the number of message data
+* @param[in]   user_data               specifies additional user input data (unused)
+* @param[out]  error_code              specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_chat_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_chat_msg_s **chat_msgs,
+                                               unsigned int chat_msgs_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief Allow Chat Request.
+*
+* @param[in]   plugin                                          specifies Message-adaptor Plugin handle
+* @param[in]   context                                         specifies Message-adaptor Plugin context
+* @param[in]   request_id                                      specifies unique request ID
+* @param[in]   chatroom_id                                     specifies chatroom ID
+* @param[in]   max_count                                       specifies the max number of ForwardUnreadMessage (default : 500)
+* @param[in]   need_delivery_ack                               specifies whether receive delivery ack data or not (0 - do not receive delivery ack data, 1 - receive delivery ack data)
+* @param[in]   need_delivery_ack_timestamp     specifies       latest receipt time of delivery ack data
+* @param[in]   need_read_ack                           specifies whether receive water mark data or not (0 - do not receive water mark data, 1 - receive read_ack data)
+* @param[in]   last_read_ack_timestamp         specifies time of last read_ack
+* @param[in]   need_ordered_chat_member_list   specifies whether need odered chat memebr list or not
+* @param[in]   user_data                                       specifies additional user input data (unused)
+* @param[out]  error_code                                      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_allow_chat_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               bool is_auto_allow,
+                                               int max_count,
+                                               bool need_delivery_ack,
+                                               long long int delivery_ack_timestamp,
+                                               bool need_read_ack,
+                                               long long int last_read_ack_timestamp,
+                                               bool need_ordered_chat_member_list,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief Get All Unread Message Request.
+*
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   request_id      specifies unique request ID
+* @param[in]   max_count       specifies the max number of ForwardUnreadMessage (default : 500)
+* @param[in]   user_data       specifies additional user input data (unused)
+* @param[out]  error_code      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_get_all_unread_message_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               int max_count,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief Forward Online Message Reply.
+*
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   request_id      specifies unique request ID
+* @param[in]   chatroom_id     specifies chatroom ID
+* @param[in]   mark_as_read    marks the received message as read
+* @param[in]   user_data       specifies additional user input data (unused)
+* @param[out]  error_code      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_forward_online_message_reply(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               bool mark_as_read,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief Forward Unread Message Reply.
+*
+* @param[in]   plugin                          specifies Message-adaptor Plugin handle
+* @param[in]   context                         specifies Message-adaptor Plugin context
+* @param[in]   request_id                      specifies unique request ID
+* @param[in]   next_pagination_key     specifies the next pagination key
+* @param[in]   max_count                       specifies the max number of unread messages to be shown in one page(default : 500)
+* @param[in]   user_data                       specifies additional user input data (unused)
+* @param[out]  error_code                      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_forward_unread_message_reply(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               const char *next_pagination_key,
+                                               int max_count,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief Read Message Request.
+*
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   request_id      specifies unique request ID
+* @param[in]   chatroom_id     specifies chatroom ID
+* @param[in]   inbox_msg       specifies the message to be read
+* @param[in]   user_data       specifies additional user input data (unused)
+* @param[out]  error_code      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_read_message_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_inboxentry_t *inbox_msg,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief Invite Request.
+*
+* @param[in]   plugin                          specifies Message-adaptor Plugin handle
+* @param[in]   context                         specifies Message-adaptor Plugin context
+* @param[in]   request_id                      specifies unique request ID
+* @param[in]   chatroom_id                     specifies chatroom ID
+* @param[in]   inviting_members                specifies members IDs to be invited to chatroom
+* @param[in]   inviting_members_len    specifies the number of members IDs
+* @param[in]   user_data                       specifies additional user input data (unused)
+* @param[out]  error_code                      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_invite_chat_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               long long int *inviting_members,
+                                               unsigned int inviting_members_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief End Chat Request.
+*
+* @param[in]   plugin                  specifies Message-adaptor Plugin handle
+* @param[in]   context                 specifies Message-adaptor Plugin context
+* @param[in]   request_id              specifies unique request ID
+* @param[in]   end_chats               specifies chatrooms IDs
+* @param[in]   end_chats_len           specifies the number of chatrooms
+* @param[in]   user_data                       specifies additional user input data (unused)
+* @param[out]  error_code                      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_end_chat_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_end_chat_s **end_chats,
+                                               unsigned int end_chats_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief Unseal Message Request.
+*
+* @param[in]   plugin                          specifies Message-adaptor Plugin handle
+* @param[in]   context                         specifies Message-adaptor Plugin context
+* @param[in]   request_id                      specifies unique request ID
+* @param[in]   chatroom_id                     specifies chatroom ID
+* @param[in]   sender_id                       specifies message sender ID for 'Unseal Message'
+* @param[in]   message_id                      specifies message ID for 'Unseal Message'
+* @param[in]   user_data                       specifies additional user input data (unused)
+* @param[out]  error_code                      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_unseal_message_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               long long int sender_id,
+                                               long long int message_id,
+                                               const char *message_detail,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+/**
+* @brief Save Call Log Request.
+*
+* @param[in]   plugin                          specifies Message-adaptor Plugin handle
+* @param[in]   context                         specifies Message-adaptor Plugin context
+* @param[in]   request_id                      specifies unique request ID
+* @param[in]   chatroom_id                     specifies chatroom ID
+* @param[in]   call_id                         specifies unique call ID
+* @param[in]   call_log_type                   specifies call log type string
+* @param[in]   call_sender_id                  specifies caller's unique ID
+* @param[in]   call_receiver_id                specifies callee's unique ID
+* @param[in]   conversaction_second            specifies calling time
+* @param[in]   user_data                       specifies additional user input data (unused)
+* @param[out]  error_code                      specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_save_call_log_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               const char *call_id,
+                                               const char *call_log_type,
+                                               long long int call_sender_id,
+                                               long long int call_receiver_id,
+                                               int conversaction_second,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+
+
+/**
+* @brief Current Time Request.
+*
+* @param[in]   plugin                  specifies Message-adaptor Plugin handle
+* @param[in]   context                 specifies Message-adaptor Plugin context
+* @param[in]   request_id              specifies unique request ID
+* @param[in]   user_data               specifies additional user input data (unused)
+* @param[out]  error_code              specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_current_time_request(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+EXPORT_API
+message_error_code_t message_adaptor_is_typing(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               long long int *request_id,
+                                               long long int *chatroom_id,
+                                               char **state,
+                                               int *chat_type,
+                                               int *refreshtime,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *user_data);
+/*
+EXPORT_API
+message_error_code_t message_adaptor_plugin_set_key(message_adaptor_plugin_h plugin,
+                                                                                               message_adaptor_plugin_context_h context,
+                                                                                               char *key_str,
+                                                                                               bool is_gpb);
+*/
+
+/**
+* @brief Establish a TCP server connection
+* @details create socket and establish connection, then start recv listener
+* @param[in]   plugin                  specifies Message-adaptor Plugin handle
+* @param[in]   context                 specifies Message-adaptor Plugin context
+* @param[out]  error_code              specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_connect(message_adaptor_plugin_h plugin, message_adaptor_plugin_context_h context, message_adaptor_error_code_h *error_code);
+
+
+
+/**
+* @brief Disestablish a TCP server connection
+* @details destroy socket and disestablish connection, then stop recv listener
+* @param[in]   plugin                  specifies Message-adaptor Plugin handle
+* @param[in]   context                 specifies Message-adaptor Plugin context
+* @param[out]  error_code              specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_disconnect(message_adaptor_plugin_h plugin, message_adaptor_plugin_context_h context, message_adaptor_error_code_h *error_code);
+
+/**
+* @brief get TCP server connection state
+* @details get connection state flag
+* @param[in]   plugin                  specifies Message-adaptor Plugin handle
+* @param[in]   context                 specifies Message-adaptor Plugin context
+* @param[out]  state                   specifies TCP connection state
+* @param[out]  error_code              specifies error code
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+EXPORT_API
+message_error_code_t message_adaptor_get_connection_state(message_adaptor_plugin_h plugin, message_adaptor_plugin_context_h context, message_connection_state_t *state, message_adaptor_error_code_h *error_code);
+
+/**
+* @brief Decode Push Messages received from SPP Push server
+* @param[in]   plugin          specifies Message-adaptor Plugin handle
+* @param[in]   context         specifies Message-adaptor Plugin context
+* @param[in]   in_msg          specifies Input Messages(json format, include encrypted fields)
+* @param[out]  out_msg         specifies Output Messages(decrypted)
+* @param[out]  error_code      specifies error to be sent to server
+* @return MESSAGE_ADAPTOR_ERROR_NONE (0) on success, otherwise a positive error value
+* @retval error code defined in message_error_code_t
+*/
+
+EXPORT_API
+message_error_code_t message_adaptor_decode_push_message(message_adaptor_plugin_h plugin,
+                                               message_adaptor_plugin_context_h context,
+                                               char *in_msg,
+                                               char **out_msg,
+                                               message_adaptor_error_code_h *error_code);
+
+#endif
diff --git a/message-adaptor.manifest b/message-adaptor.manifest
new file mode 100644 (file)
index 0000000..9cc5e17
--- /dev/null
@@ -0,0 +1,13 @@
+<manifest>
+       <define>
+       <domain name="message-adaptor" />
+               <request>
+               </request>
+       </define>
+       <assign>
+               <filesystem path="/usr/lib/libmessage-adaptor.so" label="_" exec_label="none"/>
+       </assign>
+       <request>
+               <domain name="message-adaptor" />
+       </request>
+</manifest>
diff --git a/message-adaptor.pc.in b/message-adaptor.pc.in
new file mode 100644 (file)
index 0000000..17cfa3c
--- /dev/null
@@ -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 (file)
index 0000000..dc946a0
--- /dev/null
@@ -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 (file)
index 0000000..f2ba724
--- /dev/null
@@ -0,0 +1,2095 @@
+/*
+* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <glib.h>
+
+
+#include "message-adaptor.h"
+#include "message-adaptor-log.h"
+
+
+/**
+ * Message adaptor plugin
+ */
+typedef struct message_adaptor_plugin_s {
+       message_adaptor_h                       adaptor;                /* Adaptor */
+       char                                    *path;                  /* Plugin library path */
+       message_adaptor_plugin_handle_h         handle;                 /* Plugin handle */
+       void                                    *dl_handle;             /* Plugin library handle */
+       int                                     ref_counter;            /* Plugin reference counter */
+       GMutex                                  ref_counter_mutex;      /* Plugin reference counter mutex */
+       message_adaptor_plugin_listener_h       plugin_listener;        /* Plugin callback listener */
+       GMutex                                  plugin_listener_mutex;  /* Plugin callback listener mutex */
+       int                                     connected;              /* connected flag */
+       GMutex                                  plugin_connect_mutex;
+       GCond                                   plugin_connect_cond;
+} message_adaptor_plugin_t;
+
+/**
+ * Message adaptor
+ */
+typedef struct message_adaptor_s {
+       GMutex  message_adaptor_mutex;          /* Adaptor mutex */
+       int     started;                        /* Started flag */
+       char    *plugins_dir;                   /* Plugins directory path */
+       GList   *plugins;                       /* List of loaded plugins */
+       GMutex  plugins_mutex;                  /* Plugin list mutex */
+       GList   *adaptor_listeners;             /* List of vservice channel listener (for now not effective) */
+       GMutex  adaptor_listeners_mutex;        /* Listener list mutex */
+} message_adaptor_t;
+
+/**
+ * Creates plugin
+ */
+static message_adaptor_plugin_h message_adaptor_create_plugin(const char *plugin_path);
+
+/**
+ * Destroys plugin and deletes all resources associated with it
+ */
+static void message_adaptor_destroy_plugin(message_adaptor_plugin_h plugin);
+
+/**
+ * Loads plugins from selected directory
+ */
+static int message_adaptor_load_plugins_from_directory(message_adaptor_h adaptor, const char *dir_path);
+
+/**
+ * Checks if plugin is loaded by selected plugin adaptor
+ */
+static int message_adaptor_has_plugin(message_adaptor_h adaptor, message_adaptor_plugin_h plugin);
+
+/**
+ * Increases adaptor's plugin references counter
+ */
+static void message_adaptor_plugin_ref(message_adaptor_plugin_h);
+
+/**
+ * Decreases adaptor's plugin references counter
+ */
+static void message_adaptor_plugin_unref(message_adaptor_plugin_h);
+
+
+/**
+ * Definition of callback function variables for service adaptor
+ */
+
+message_adaptor_service_client_echo_cb _service_adaptor_service_client_echo_cb = NULL;
+message_adaptor_service_create_chatroom_reply_cb _service_adaptor_service_create_chatroom_reply_cb = NULL;
+message_adaptor_service_change_chatroom_meta_reply_cb _service_adaptor_service_change_chatroom_meta_reply_cb = NULL;
+message_adaptor_service_chat_reply_cb _service_adaptor_service_chat_reply_cb = NULL;
+message_adaptor_service_allow_chat_reply_cb _service_adaptor_service_allow_chat_reply_cb = NULL;
+message_adaptor_service_get_all_unread_message_reply_cb _service_adaptor_service_get_all_unread_message_reply_cb = NULL;
+message_adaptor_service_forward_online_message_request_cb _service_adaptor_service_forward_online_message_request_cb = NULL;
+message_adaptor_service_forward_unread_message_request_cb _service_adaptor_service_forward_unread_message_request_cb = NULL;
+message_adaptor_service_read_message_reply_cb _service_adaptor_service_read_message_reply_cb = NULL;
+message_adaptor_service_invite_chat_reply_cb _service_adaptor_service_invite_chat_reply_cb = NULL;
+message_adaptor_service_end_chat_reply_cb _service_adaptor_service_end_chat_reply_cb = NULL;
+message_adaptor_service_unseal_message_reply_cb _service_adaptor_service_unseal_message_reply_cb = NULL;
+message_adaptor_service_save_call_log_reply_cb _service_adaptor_service_save_call_log_reply_cb = NULL;
+message_adaptor_service_current_time_reply_cb _service_adaptor_service_current_time_reply_cb = NULL;
+message_adaptor_service_typing_updated_cb _service_adaptor_service_typing_updated_cb = NULL;
+message_adaptor_service_completion_cb _service_adaptor_service_completion_cb = NULL;
+/*
+ * Required function for sample callback functions
+ */
+
+void
+message_adaptor_client_echo_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_client_echo_cb) {
+               _service_adaptor_service_client_echo_cb(context, request_id, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_create_chatroom_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               int default_message_ttl,
+                                               message_adaptor_wrong_receiver_s *wrong_receiver,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_create_chatroom_reply_cb) {
+               _service_adaptor_service_create_chatroom_reply_cb(context, request_id,
+                               chatroom_id, default_message_ttl, wrong_receiver, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_change_chatroom_meta_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_change_chatroom_meta_reply_cb) {
+               _service_adaptor_service_change_chatroom_meta_reply_cb(context, request_id,
+                               chatroom_id, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_chat_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_processed_msg_s **processed_msgs,
+                                               unsigned int processed_msgs_len,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_chat_reply_cb) {
+               _service_adaptor_service_chat_reply_cb(context,
+                               request_id, chatroom_id, processed_msgs,
+                               processed_msgs_len, error_code, server_data);
+       }
+}
+
+
+void
+message_adaptor_allow_chat_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_delivery_ack_s **deliveryacks,
+                                               unsigned int deliveryacks_len,
+                                               unsigned long long last_delivery_ack_timestamp,
+                                               message_adaptor_read_ack_s **read_acks,
+                                               unsigned int read_acks_len,
+                                               unsigned long long last_read_ack_timestamp,
+                                               message_adaptor_ordered_chat_member_s **ordered_chat_members,
+                                               unsigned int ordered_chat_members_len,
+                                               const char *chatroom_title,
+                                               int default_message_ttl,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_allow_chat_reply_cb) {
+               _service_adaptor_service_allow_chat_reply_cb(context,
+                               request_id, chatroom_id,
+                               deliveryacks, deliveryacks_len, last_delivery_ack_timestamp,
+                               read_acks, read_acks_len, last_read_ack_timestamp,
+                               ordered_chat_members, ordered_chat_members_len,
+                               chatroom_title, default_message_ttl,
+                               error_code, server_data);
+       }
+}
+
+void
+message_adaptor_get_all_unread_message_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_get_all_unread_message_reply_cb) {
+               _service_adaptor_service_get_all_unread_message_reply_cb(context,
+                               request_id, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_forward_online_message_request_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id, int chat_type,
+                                               message_inboxentry_t *inbox_msg,
+                                               bool skip_reply,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_forward_online_message_request_cb) {
+               _service_adaptor_service_forward_online_message_request_cb(context,
+                               request_id, chatroom_id, chat_type,
+                               inbox_msg, skip_reply, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_forward_unread_message_request_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_inboxentry_t ***inbox_msgs,
+                                               unsigned int inbox_msgs_len,
+                                               char **next_pagination_key,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_forward_unread_message_request_cb) {
+               _service_adaptor_service_forward_unread_message_request_cb(context,
+                               request_id, inbox_msgs, inbox_msgs_len,
+                               next_pagination_key, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_read_message_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_read_message_reply_cb) {
+               _service_adaptor_service_read_message_reply_cb(context,
+                               request_id, chatroom_id, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_invite_chat_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               long long int sent_time,
+                                               message_adaptor_wrong_receiver_s *wrong_receiver,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_invite_chat_reply_cb) {
+               _service_adaptor_service_invite_chat_reply_cb(context,
+                               request_id, chatroom_id, sent_time,
+                               wrong_receiver, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_end_chat_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_end_chat_reply_cb) {
+               _service_adaptor_service_end_chat_reply_cb(context,
+                               request_id, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_unseal_message_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_unseal_message_reply_cb) {
+               _service_adaptor_service_unseal_message_reply_cb(context,
+                               request_id, chatroom_id, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_save_call_log_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_save_call_log_reply_cb) {
+               _service_adaptor_service_save_call_log_reply_cb(context,
+                               request_id, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_current_time_reply_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int current_time_millis,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_current_time_reply_cb) {
+               _service_adaptor_service_current_time_reply_cb(context,
+                               request_id, current_time_millis, error_code, server_data);
+       }
+}
+
+void
+message_adaptor_typing_updated_cb(message_adaptor_plugin_context_h context,
+                                               long long int request_id,
+                                               long long int chatroom_id,
+                                               long long int *sender,
+                                               char **state,
+                                               int *contentType,
+                                               int *refreshTime,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       plugin_req_id_print();
+       if (_service_adaptor_service_typing_updated_cb) {
+               _service_adaptor_service_typing_updated_cb(context,
+                               request_id, chatroom_id, sender,
+                               state, contentType, refreshTime,
+                               error_code, server_data);
+       }
+}
+
+void
+message_adaptor_completion_cb(message_adaptor_plugin_context_h context,
+                                               message_connection_state_t state,
+                                               message_adaptor_error_code_t **error_code,
+                                               void *server_data)
+{
+       if (_service_adaptor_service_completion_cb) {
+               _service_adaptor_service_completion_cb(context,
+                               state, error_code, server_data);
+       }
+}
+
+
+/* //------------------------------------------------------------------------
+   // Functions implementations
+   //------------------------------------------------------------------------ */
+
+/* //////////////////////////////////////////////////////
+   // Mandatory: External adaptor management function
+   ////////////////////////////////////////////////////// */
+
+EXPORT_API
+message_adaptor_h message_adaptor_create(const char *plugins_dir)
+{
+       message_adaptor_h message_adaptor = (message_adaptor_h) malloc(sizeof(message_adaptor_t));
+       if (NULL == message_adaptor) {
+               return NULL;
+       }
+
+       message_adaptor->started = 0;
+       message_adaptor->plugins_dir = strdup(plugins_dir);
+
+       g_mutex_init(&message_adaptor->message_adaptor_mutex);
+       g_mutex_init(&message_adaptor->plugins_mutex);
+       g_mutex_init(&message_adaptor->adaptor_listeners_mutex);
+
+       g_mutex_lock(&message_adaptor->adaptor_listeners_mutex);
+       message_adaptor->adaptor_listeners = NULL;
+       g_mutex_unlock(&message_adaptor->adaptor_listeners_mutex);
+
+       g_mutex_lock(&message_adaptor->plugins_mutex);
+       message_adaptor->plugins = NULL;
+       g_mutex_unlock(&message_adaptor->plugins_mutex);
+
+       return message_adaptor;
+
+}
+
+EXPORT_API
+void message_adaptor_destroy(message_adaptor_h adaptor)
+{
+       if (NULL == adaptor) {
+               message_adaptor_error("Invalid argument");
+               return ;
+       }
+
+       g_mutex_lock(&adaptor->message_adaptor_mutex);
+       if (adaptor->started) {
+               message_adaptor_error("Message adaptor is running. Forcing stop before destroy");
+               message_adaptor_stop(adaptor);
+       }
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       if (NULL != adaptor->plugins) {
+               g_list_free_full(adaptor->plugins, (GDestroyNotify) message_adaptor_plugin_unref);
+               adaptor->plugins = NULL;
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+       if (NULL != adaptor->adaptor_listeners) {
+               g_list_free(adaptor->adaptor_listeners);
+               adaptor->adaptor_listeners = NULL;
+       }
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+
+       free(adaptor->plugins_dir);
+       adaptor->plugins_dir = NULL;
+
+       g_mutex_unlock(&adaptor->message_adaptor_mutex);
+
+       free(adaptor);
+}
+
+EXPORT_API
+int message_adaptor_start(message_adaptor_h adaptor)
+{
+       message_adaptor_debug("Starting message adaptor");
+       if (NULL == adaptor) {
+               message_adaptor_error("Invalid argument");
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->message_adaptor_mutex);
+       int result = MESSAGE_ADAPTOR_ERROR_NONE;
+       if (adaptor->started) {
+               message_adaptor_error("Message adaptor is already started");
+               result = MESSAGE_ADAPTOR_ERROR_START;
+       } else {
+               adaptor->started = 1;
+               result = message_adaptor_load_plugins_from_directory(adaptor, adaptor->plugins_dir);
+               if (MESSAGE_ADAPTOR_ERROR_NONE != result) {
+                       adaptor->started = 0;
+                       message_adaptor_error("Could not load plugins from directory");
+               } else {
+                       message_adaptor_debug("Message adaptor started successfully");
+               }
+       }
+       g_mutex_unlock(&adaptor->message_adaptor_mutex);
+
+       return result;
+}
+
+/**
+ * Stops message adaptor.
+ */
+EXPORT_API
+int message_adaptor_stop(message_adaptor_h adaptor)
+{
+       if (NULL == adaptor) {
+               message_adaptor_error("Invalid argument");
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->message_adaptor_mutex);
+       int result = MESSAGE_ADAPTOR_ERROR_NONE;
+       if (!adaptor->started) {
+               result = MESSAGE_ADAPTOR_ERROR_START;
+       } else {
+               if (NULL != adaptor->plugins) {
+                       g_mutex_lock(&adaptor->plugins_mutex);
+                       g_list_free_full(adaptor->plugins, (GDestroyNotify) message_adaptor_plugin_unref);
+                       adaptor->plugins = NULL;
+                       g_mutex_unlock(&adaptor->plugins_mutex);
+               }
+               adaptor->started = 0;
+               message_adaptor_debug("Message adaptor stopped");
+       }
+
+       g_mutex_unlock(&adaptor->message_adaptor_mutex);
+       return result;
+}
+
+/**
+ * Registers plugin state listener
+ */
+       EXPORT_API
+int message_adaptor_register_listener(message_adaptor_h adaptor, message_adaptor_listener_h listener)
+{
+       if ((NULL == adaptor) || (NULL == listener)) {
+               message_adaptor_error("Invalid argument");
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+
+       adaptor->adaptor_listeners = g_list_append(adaptor->adaptor_listeners, listener);
+
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+
+       _service_adaptor_service_client_echo_cb =
+               (message_adaptor_service_client_echo_cb)listener->client_echo_cb;
+       _service_adaptor_service_create_chatroom_reply_cb =
+               (message_adaptor_service_create_chatroom_reply_cb)listener->create_chatroom_reply_cb;
+       _service_adaptor_service_change_chatroom_meta_reply_cb =
+               (message_adaptor_service_change_chatroom_meta_reply_cb)listener->change_chatroom_meta_reply_cb;
+       _service_adaptor_service_chat_reply_cb =
+               (message_adaptor_service_chat_reply_cb)listener->chat_reply_cb;
+       _service_adaptor_service_allow_chat_reply_cb =
+               (message_adaptor_service_allow_chat_reply_cb)listener->allow_chat_reply_cb;
+       _service_adaptor_service_get_all_unread_message_reply_cb =
+               (message_adaptor_service_get_all_unread_message_reply_cb)listener->get_all_unread_message_reply_cb;
+       _service_adaptor_service_forward_online_message_request_cb =
+               (message_adaptor_service_forward_online_message_request_cb)listener->forward_online_message_request_cb;
+       _service_adaptor_service_forward_unread_message_request_cb =
+               (message_adaptor_service_forward_unread_message_request_cb)listener->forward_unread_message_request_cb;
+       _service_adaptor_service_read_message_reply_cb =
+               (message_adaptor_service_read_message_reply_cb)listener->read_message_reply_cb;
+       _service_adaptor_service_invite_chat_reply_cb =
+               (message_adaptor_service_invite_chat_reply_cb)listener->invite_chat_reply_cb;
+       _service_adaptor_service_end_chat_reply_cb =
+               (message_adaptor_service_end_chat_reply_cb)listener->end_chat_reply_cb;
+       _service_adaptor_service_unseal_message_reply_cb =
+               (message_adaptor_service_unseal_message_reply_cb)listener->unseal_message_reply_cb;
+       _service_adaptor_service_save_call_log_reply_cb =
+               (message_adaptor_service_save_call_log_reply_cb)listener->save_call_log_reply_cb;
+       _service_adaptor_service_current_time_reply_cb =
+               (message_adaptor_service_current_time_reply_cb)listener->current_time_reply_cb;
+       _service_adaptor_service_typing_updated_cb =
+               (message_adaptor_service_typing_updated_cb)listener->typing_updated_cb;
+       _service_adaptor_service_completion_cb =
+               (message_adaptor_service_completion_cb)listener->completion_cb;
+
+       return MESSAGE_ADAPTOR_ERROR_NONE;
+}
+
+/**
+ * Unregisters plugin state listener
+ */
+EXPORT_API
+int message_adaptor_unregister_listener(message_adaptor_h adaptor, message_adaptor_listener_h listener)
+{
+       if ((NULL == adaptor) || (NULL == listener)) {
+               message_adaptor_error("Invalid argument");
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       g_mutex_lock(&adaptor->adaptor_listeners_mutex);
+
+       if (NULL == g_list_find(adaptor->adaptor_listeners, listener)) {
+               g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+               message_adaptor_error("Could not find listener");
+               return MESSAGE_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       adaptor->adaptor_listeners = g_list_remove(adaptor->adaptor_listeners, listener);
+
+       g_mutex_unlock(&adaptor->adaptor_listeners_mutex);
+
+       _service_adaptor_service_client_echo_cb = NULL;
+       _service_adaptor_service_create_chatroom_reply_cb = NULL;
+       _service_adaptor_service_change_chatroom_meta_reply_cb = NULL;
+       _service_adaptor_service_chat_reply_cb = NULL;
+       _service_adaptor_service_allow_chat_reply_cb = NULL;
+       _service_adaptor_service_get_all_unread_message_reply_cb = NULL;
+       _service_adaptor_service_forward_online_message_request_cb = NULL;
+       _service_adaptor_service_forward_unread_message_request_cb = NULL;
+       _service_adaptor_service_read_message_reply_cb = NULL;
+       _service_adaptor_service_invite_chat_reply_cb = NULL;
+       _service_adaptor_service_end_chat_reply_cb = NULL;
+       _service_adaptor_service_unseal_message_reply_cb = NULL;
+       _service_adaptor_service_save_call_log_reply_cb = NULL;
+       _service_adaptor_service_current_time_reply_cb = NULL;
+       _service_adaptor_service_typing_updated_cb = NULL;
+       _service_adaptor_service_completion_cb = NULL;
+
+       return MESSAGE_ADAPTOR_ERROR_NONE;
+}
+
+/* /////////////////////////////////////////////////////////////
+   // Plugin create / destroy / ref. count / get plugin name
+   ///////////////////////////////////////////////////////////// */
+static message_adaptor_plugin_h message_adaptor_create_plugin(const char *plugin_path)
+{
+       if (NULL == plugin_path) {
+               message_adaptor_error("Invalid argument");
+               return NULL;
+       }
+
+       void *dl_handle = dlopen(plugin_path, RTLD_LAZY);
+       if (NULL == dl_handle) {
+               message_adaptor_error("Could not load plugin %s: %s", plugin_path, dlerror());
+               return NULL;
+       }
+
+       message_adaptor_plugin_handle_h (*get_adaptee_handle)(void) = NULL;
+
+       get_adaptee_handle = (message_adaptor_plugin_handle_h (*)(void))(dlsym(dl_handle, "create_plugin_handle"));
+       if (NULL == get_adaptee_handle) {
+               dlclose(dl_handle);
+               message_adaptor_error("Could not get function pointer to create_plugin_handle");
+               return NULL;
+       }
+
+       plugin_req_enter();
+       message_adaptor_plugin_handle_h handle = get_adaptee_handle();
+       plugin_req_exit_void();
+       if (NULL == handle) {
+               dlclose(dl_handle);
+               message_adaptor_error("Could not get adaptee handle");
+               return NULL;
+       }
+
+       message_adaptor_plugin_h plugin = (message_adaptor_plugin_h) calloc(1, sizeof(message_adaptor_plugin_t));
+       if (NULL == plugin) {
+               dlclose(dl_handle);
+               message_adaptor_error("Could not create plugin object");
+               return NULL;
+       }
+
+       message_adaptor_plugin_listener_h listener =
+               (message_adaptor_plugin_listener_h) calloc(1, sizeof(message_adaptor_plugin_listener_t));
+       if (NULL == listener) {
+               free(plugin);
+               dlclose(dl_handle);
+               message_adaptor_error("Could not create listener object");
+               return NULL;
+       }
+
+       plugin->path = g_strdup(plugin_path);
+       plugin->handle = handle;
+       plugin->dl_handle = dl_handle;
+       plugin->ref_counter = 0;
+
+       g_mutex_init(&plugin->ref_counter_mutex);
+       g_mutex_init(&plugin->plugin_listener_mutex);
+
+       plugin->connected = 0;
+
+       g_mutex_init(&plugin->plugin_connect_mutex);
+       g_cond_init(&plugin->plugin_connect_cond);
+
+       listener->message_adaptor_client_echo = message_adaptor_client_echo_cb;
+       listener->message_adaptor_create_chatroom_reply = message_adaptor_create_chatroom_reply_cb;
+       listener->message_adaptor_change_chatroom_meta_reply = message_adaptor_change_chatroom_meta_reply_cb;
+       listener->message_adaptor_chat_reply = message_adaptor_chat_reply_cb;
+       listener->message_adaptor_allow_chat_reply = message_adaptor_allow_chat_reply_cb;
+       listener->message_adaptor_get_all_unread_message_reply = message_adaptor_get_all_unread_message_reply_cb;
+       listener->message_adaptor_forward_online_message_request = message_adaptor_forward_online_message_request_cb;
+       listener->message_adaptor_forward_unread_message_request = message_adaptor_forward_unread_message_request_cb;
+       listener->message_adaptor_read_message_reply = message_adaptor_read_message_reply_cb;
+       listener->message_adaptor_invite_chat_reply = message_adaptor_invite_chat_reply_cb;
+       listener->message_adaptor_end_chat_reply = message_adaptor_end_chat_reply_cb;
+       listener->message_adaptor_unseal_message_reply = message_adaptor_unseal_message_reply_cb;
+       listener->message_adaptor_save_call_log_reply = message_adaptor_save_call_log_reply_cb;
+       listener->message_adaptor_current_time_reply = message_adaptor_current_time_reply_cb;
+       listener->message_adaptor_typing_updated = message_adaptor_typing_updated_cb;
+       listener->message_adaptor_completion = message_adaptor_completion_cb;
+
+       plugin_req_enter();
+       plugin->handle->set_listener(listener);
+       plugin_req_exit_void();
+
+       g_mutex_lock(&plugin->plugin_listener_mutex);
+       plugin->plugin_listener = listener;
+       g_mutex_unlock(&plugin->plugin_listener_mutex);
+
+       return plugin;
+}
+
+static void message_adaptor_destroy_plugin(message_adaptor_plugin_h plugin)
+{
+       if (NULL == plugin) {
+               message_adaptor_error("Invalid argument");
+               return;
+       }
+
+       if (NULL != plugin->handle) {
+               plugin->handle->destroy_handle(plugin->handle);
+
+               g_mutex_lock(&plugin->plugin_listener_mutex);
+               plugin_req_enter();
+               plugin->handle->unset_listener();
+               plugin_req_exit_void();
+               g_mutex_unlock(&plugin->plugin_listener_mutex);
+
+               plugin->handle = NULL;
+       }
+
+       if (NULL != plugin->dl_handle) {
+               dlclose(plugin->dl_handle);
+               plugin->dl_handle = NULL;
+       }
+
+       free(plugin->path);
+       plugin->path = NULL;
+
+       free(plugin);
+}
+
+static int message_adaptor_load_plugins_from_directory(message_adaptor_h adaptor, const char *dir_path)
+{
+       char *plugin_path = NULL;
+       DIR *dir = NULL;
+       struct dirent dir_entry, *result = NULL;
+
+       message_adaptor_debug("Starting load plugins from directory");
+
+       if ((NULL == adaptor) || (NULL == dir_path)) {
+               message_adaptor_error("Invalid argument");
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+
+       dir = opendir(dir_path);
+       if (NULL == dir) {
+               message_adaptor_error("Could not open dir path (%s)", dir_path);
+               return MESSAGE_ADAPTOR_ERROR_NOT_FOUND;
+       }
+
+       int ret = MESSAGE_ADAPTOR_ERROR_NONE;
+       while (0 == (readdir_r(dir, &dir_entry, &result))) {
+
+               if (NULL == result) {
+                       message_adaptor_error("Could not open directory %s", plugin_path);
+                       break;
+               }
+
+               if (dir_entry.d_type & DT_DIR) {
+                       continue;
+               }
+
+               plugin_path = g_strconcat(dir_path, "/", dir_entry.d_name, NULL);
+               message_adaptor_plugin_h plugin = message_adaptor_create_plugin(plugin_path);
+
+               if (NULL != plugin) {
+                       message_adaptor_debug("Loaded plugin: %s", plugin_path);
+                       plugin->adaptor = adaptor;
+                       message_adaptor_plugin_ref(plugin);
+                       g_mutex_lock(&adaptor->plugins_mutex);
+                       adaptor->plugins = g_list_append(adaptor->plugins, plugin);
+                       g_mutex_unlock(&adaptor->plugins_mutex);
+               } else {
+                       message_adaptor_error("Could not load plugin %s", plugin_path);
+               }
+
+               free(plugin_path);
+               plugin_path = NULL;
+       }
+
+       message_adaptor_debug("End load plugins from directory");
+       closedir(dir);
+       return ret;
+}
+
+
+static int message_adaptor_has_plugin(message_adaptor_h adaptor, message_adaptor_plugin_h plugin)
+{
+       if ((NULL == adaptor) || (NULL == plugin)) {
+               message_adaptor_error("Invalid argument");
+               return 0;
+       }
+
+       int result = 0;
+
+       g_mutex_lock(&adaptor->plugins_mutex);
+       if (NULL != g_list_find(adaptor->plugins, plugin)) {
+               result = 1;
+       }
+       g_mutex_unlock(&adaptor->plugins_mutex);
+
+       return result;
+}
+
+static void message_adaptor_plugin_ref(message_adaptor_plugin_h plugin)
+{
+       if (NULL == plugin) {
+               message_adaptor_error("Invalid argument");
+               return;
+       }
+
+       g_mutex_lock(&plugin->ref_counter_mutex);
+       plugin->ref_counter = plugin->ref_counter + 1;
+       if (NULL != plugin->handle) {
+               message_adaptor_info("plugin name : %s, ref_counter: %d", plugin->handle->plugin_uri, plugin->ref_counter);
+       } else {
+               message_adaptor_info("ref_counter : %d", plugin->ref_counter);
+       }
+       g_mutex_unlock(&plugin->ref_counter_mutex);
+}
+
+static void message_adaptor_plugin_unref(message_adaptor_plugin_h plugin)
+{
+       if (NULL == plugin) {
+               message_adaptor_error("Invalid argument");
+               return ;
+       }
+
+       int should_destroy = 0;
+
+       g_mutex_lock(&plugin->ref_counter_mutex);
+       plugin->ref_counter = plugin->ref_counter - 1;
+
+       if (NULL != plugin->handle) {
+               message_adaptor_info("plugin name : %s, ref_counter: %d", plugin->handle->plugin_uri, plugin->ref_counter);
+       } else {
+               message_adaptor_info("ref_counter : %d", plugin->ref_counter);
+       }
+
+       if (0 >= plugin->ref_counter) {
+               should_destroy = 1;
+       }
+       g_mutex_unlock(&plugin->ref_counter_mutex);
+
+       if (should_destroy) {
+               message_adaptor_debug("Plugin is being destroyed");
+               message_adaptor_destroy_plugin(plugin);
+       }
+}
+
+
+/**
+ * Refresh access token
+ */
+EXPORT_API
+message_error_code_t message_adaptor_refresh_access_token(message_adaptor_plugin_context_h context,
+                                               const char *new_access_token)
+{
+       if ((NULL == context) || (NULL == new_access_token) || (0 >= strlen(new_access_token))) {
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+       if ((NULL == context->access_token) || (0 >= strlen(context->access_token))) {
+               return MESSAGE_ADAPTOR_ERROR_NOT_AUTHORIZED;
+       }
+
+       free(context->access_token);
+       context->access_token = NULL;
+       context->access_token = strdup(new_access_token);
+
+       return MESSAGE_ADAPTOR_ERROR_NONE;
+}
+
+EXPORT_API
+message_error_code_t message_adaptor_refresh_uid(message_adaptor_plugin_context_h context,
+                                               const char *new_uid)
+{
+       if ((NULL == context) || (NULL == new_uid) || (0 >= strlen(new_uid))) {
+               return MESSAGE_ADAPTOR_ERROR_INVALID_ARGUMENT;
+       }
+       message_adaptor_debug_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;
+}