initial commit of smart reply API library 79/78679/1 submit/tizen/20170223.040009
authorHaejun Lee <haejun82.lee@samsung.com>
Wed, 6 Jul 2016 11:37:27 +0000 (20:37 +0900)
committerHaejun Lee <haejun82.lee@samsung.com>
Wed, 6 Jul 2016 11:40:22 +0000 (20:40 +0900)
Change-Id: I51dc7f75377e9a996968ec75d77a980753f810ca

33 files changed:
CMakeLists.txt [new file with mode: 0755]
LICENSE [new file with mode: 0755]
doc/smartreply_doc.h [new file with mode: 0644]
include/analyzer_iface.h [new file with mode: 0755]
include/analyzer_mgr.h [new file with mode: 0755]
include/analyzer_mgr_iface.h [new file with mode: 0755]
include/db_listener_iface.h [new file with mode: 0755]
include/db_mgr.h [new file with mode: 0755]
include/db_mgr_iface.h [new file with mode: 0755]
include/dbus_listener_iface.h [new file with mode: 0755]
include/dbus_server.h [new file with mode: 0755]
include/dbus_server_iface.h [new file with mode: 0755]
include/event.h [new file with mode: 0755]
include/json.h [new file with mode: 0755]
include/request_handler.h [new file with mode: 0755]
include/response_handler.h [new file with mode: 0755]
include/scope_mutex.h [new file with mode: 0755]
include/smartreply_service.h [new file with mode: 0755]
include/smartreply_util.h [new file with mode: 0755]
include/types_internal.h [new file with mode: 0755]
packaging/smartreply.manifest [new file with mode: 0755]
packaging/smartreply.spec [new file with mode: 0755]
smartreply.pc.in [new file with mode: 0755]
src/db_mgr.cpp [new file with mode: 0755]
src/dbus_client.cpp [new file with mode: 0755]
src/dbus_client.h [new file with mode: 0755]
src/dbus_server.cpp [new file with mode: 0755]
src/event.cpp [new file with mode: 0755]
src/json.cpp [new file with mode: 0755]
src/request_handler.cpp [new file with mode: 0755]
src/scope_mutex.cpp [new file with mode: 0755]
src/smartreply_service.cpp [new file with mode: 0755]
src/starter.cpp [new file with mode: 0755]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..2be5678
--- /dev/null
@@ -0,0 +1,76 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(smartreply)
+
+SET(target "smartreply")
+SET(DEST_INCLUDE_DIR "include/smartreply")
+SET(SRC_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include")
+
+FILE(GLOB_RECURSE SRCS src/*.cpp)
+MESSAGE("Sources: ${SRCS}")
+
+SET(VERSION_MAJOR 1)
+SET(VERSION "${VERSION_MAJOR}.0.0")
+
+SET(CMAKE_INSTALL_PREFIX /usr)
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+# dependency
+SET(DEPS "aul dlog glib-2.0 json-glib-1.0 gio-2.0 bundle pkgmgr-info")
+
+INCLUDE(FindPkgConfig)
+INCLUDE_DIRECTORIES(
+       ${CMAKE_CURRENT_SOURCE_DIR}/include
+       /usr/include
+       /usr/include/glib-2.0
+       /usr/lib/glib-2.0/include
+       /usr/include/dlog
+       /usr/include/json-glib-1.0
+)
+
+ADD_DEFINITIONS(-O2 -Wall -std=c++0x -fPIC -fvisibility=default -Wl,--as-needed -Wl,--rpath=/usr/lib)
+
+#Building Library
+pkg_check_modules(api_pkg REQUIRED ${DEPS})
+
+FOREACH(flag ${api_pkg_CFLAGS})
+   SET(API_EXTRA_CFLAGS "${API_EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${API_EXTRA_CFLAGS} -fPIC -Wall -Werror")
+SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
+#SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+
+
+ADD_LIBRARY(${target} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${target} ${api_pkg_LDFLAGS})
+#SET_TARGET_PROPERTIES(${target} PROPERTIES COMPILE_FLAGS ${API_EXTRA_CFLAGS})
+SET_TARGET_PROPERTIES(${target} PROPERTIES COMPILE_DEFINITIONS "LOG_TAG=\"SMARTREPLY-API\"")
+SET_TARGET_PROPERTIES(${target} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${target} PROPERTIES VERSION ${VERSION})
+
+# Installing
+INSTALL(TARGETS ${target} DESTINATION lib)
+
+# Install header file
+FILE(GLOB HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h)
+INSTALL(FILES ${HEADER_FILES} DESTINATION ${DEST_INCLUDE_DIR})
+#INSTALL(
+#  DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include DESTINATION include/smartreply
+#  FILES_MATCHING PATTERN "*.h"
+#)
+SET(PC_NAME ${PROJECT_NAME})
+SET(PC_INCLUDE "/usr/include/smartreply")
+SET(PC_DESCRIPTION "Tizen SmartReply Framework Native API")
+SET(PC_REQUIRED ${DEPS})
+SET(PC_LDFLAGS -l${target})
+SET(PC_CFLAGS -I\${includedir}/smartreply)
+
+CONFIGURE_FILE(
+        ${PROJECT_NAME}.pc.in
+        ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc
+        @ONLY
+)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc DESTINATION lib/pkgconfig)
+
+#test case
+#ADD_SUBDIRECTORY(test)
diff --git a/LICENSE b/LICENSE
new file mode 100755 (executable)
index 0000000..1da314d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,204 @@
+Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+
+                                 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 (c) 2014 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.
+
diff --git a/doc/smartreply_doc.h b/doc/smartreply_doc.h
new file mode 100644 (file)
index 0000000..66ac76b
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright   2000-2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * PROPRIETARY/CONFIDENTIAL
+ *
+ * This software is the confidential and proprietary information of
+ * SAMSUNG ELECTRONICS ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall
+ * use it only in accordance with the terms of the license agreement
+ * you entered into with SAMSUNG ELECTRONICS.
+ * SAMSUNG make no representations or warranties about the suitability
+ * of the software, either express or implied, including but not
+ * limited to the implied warranties of merchantability, fitness for
+ * a particular purpose, or non-infringement.
+ * SAMSUNG shall not be liable for any damages suffered by licensee as
+ * a result of using, modifying or distributing this software or its derivatives.
+ */
+
+#ifndef __SMARTREPLY_DOC_H__
+#define __SMARTREPLY_DOC_H__
+
+/**
+* @ingroup CAPI_SMARTREPLY_SERVICE_MODULE
+* @defgroup    CAPI_SMARTREPLY_SERVICE SmartReply Service
+* @brief    The Smart Reply APIs provides functions to generate reply candidates for received message.
+*
+* @section CAPI_SMARTREPLY_SERVICE_HEADER Required Header
+*   \#include <smartreply_service.h>
+*
+* @section CAPI_SMARTREPLY_SERVICE_OVERVIEW Overview
+* The Smat Reply APIs provides functions to generate reply candidates for received message.\n
+* This provides following functionalities.\n
+* - Get candidate reply messages for a given received message sync/asynchronously
+* - Access & destory candidate reply list
+* - Record user's replied message to update future candidate messages
+* - Preload engine to reduce message generation time
+*
+* @section CAPI_SMARTREPLY_SERVICE Related Features
+* This API is related with the following features:\n
+*  - http://developer.samsung.com/tizen/feature/samsung_extension\n
+*
+*/
+
+#endif /* __SMARTREPLY_DOC_H__ */
+
diff --git a/include/analyzer_iface.h b/include/analyzer_iface.h
new file mode 100755 (executable)
index 0000000..68da144
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SMARTREPLY_ANALYZER_INTERFACE_H__
+#define __SMARTREPLY_ANALYZER_INTERFACE_H__
+
+namespace smr {
+
+       /* Forward Declaration */
+       class json;
+
+       class analyzer_iface {
+               public:
+                       virtual ~analyzer_iface() {}
+
+                       virtual bool init() = 0;
+
+                       virtual bool is_supported(const char* subject) = 0;
+
+                       virtual int subscribe(const char* subject, smr::json option, smr::json* request_result) = 0;
+
+                       virtual int unsubscribe(const char* subject, smr::json option) = 0;
+
+                       virtual int read(const char* subject, smr::json option, smr::json* request_result) = 0;
+
+                       virtual int write(const char* subject, smr::json data, smr::json* request_result) = 0;
+
+       };      /* class analyzer_iface */
+
+}      /* namespace smr */
+
+#endif /* End of __SMARTREPLY_ANALYZER_INTERFACE_H__ */
diff --git a/include/analyzer_mgr.h b/include/analyzer_mgr.h
new file mode 100755 (executable)
index 0000000..757ca30
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SMARTREPLY_ANALYZER_MANAGER_H__
+#define __SMARTREPLY_ANALYZER_MANAGER_H__
+
+namespace smr {
+       /* Forward Declaration */
+       class json;
+       class analyzer_iface;
+
+       namespace analyzer_manager {
+               /*
+                */
+               bool register_subject(const char* subject, smr::analyzer_iface* ca);
+
+               /*
+                */
+               bool publish(const char* subject, smr::json option, int error, smr::json data_updated);
+
+               /*
+                */
+               bool reply_to_read(const char* subject, smr::json option, int error, smr::json data_read);
+
+       }       /* namespace smr::analyzer_manager */
+}      /* namespace smr */
+
+#endif /* End of __SMARTREPLY_ANALYZER_MANAGER_H__ */
diff --git a/include/analyzer_mgr_iface.h b/include/analyzer_mgr_iface.h
new file mode 100755 (executable)
index 0000000..1a6c785
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SMARTREPLY_ANALYZER_MANAGER_INTERFACE_H__
+#define __SMARTREPLY_ANALYZER_MANAGER_INTERFACE_H__
+
+namespace smr {
+       /* Forward Declaration */
+       class json;
+       class analyzer_iface;
+
+       class analyzer_manager_iface {
+               public:
+                       virtual ~analyzer_manager_iface() {}
+               //      virtual bool register_subject(const char* subject, smr::analyzer_iface* ca) = 0;
+               //      virtual bool publish(const char* subject, smr::json& option, int error, smr::json& data_updated) = 0;
+               //      virtual bool reply_to_read(const char* subject, smr::json& option, int error, smr::json& data_read) = 0;
+       };      /* class analyzer_manager_iface */
+
+       namespace analyzer_manager {
+               void set_instance(analyzer_manager_iface* mgr);
+       }       /* namespace smr::analyzer_manager */
+
+}      /* namespace smr */
+
+#endif /* End of __SMARTREPLY_ANALYZER_MANAGER_INTERFACE_H__ */
diff --git a/include/db_listener_iface.h b/include/db_listener_iface.h
new file mode 100755 (executable)
index 0000000..37e21b8
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SMARTREPLY_DATABASE_LISTENER_INTERFACE_H__
+#define __SMARTREPLY_DATABASE_LISTENER_INTERFACE_H__
+
+#include <vector>
+
+namespace smr {
+       /* Forward Declaration */
+       class json;
+
+       class db_listener_iface {
+               public:
+                       virtual ~db_listener_iface() {}
+
+                       /**
+                        * @brief       Called when a table creation is done.
+                        * @param[in]   query_id        The query id passed through smr::db_manager::create_table().
+                        * @param[in]   error           Error code. If success, 0. Otherwise, a negative value.
+                        */
+                       virtual void on_creation_result_received(unsigned int query_id, int error) = 0;
+
+                       /**
+                        * @brief       Called when a record insertion is done.
+                        * @param[in]   query_id        The query id passed through smr::db_manager::insert().
+                        * @param[in]   error           Error code. If success, 0. Otherwise, a negative value.
+                        * @param[in]   row_id          The row id of the inserted record.
+                        */
+                       virtual void on_insertion_result_received(unsigned int query_id, int error, int64_t row_id) = 0;
+
+                       /**
+                        * @brief       Called when a query execution is done.
+                        * @param[in]   query_id        The query id passed through smr::db_manager::execute().
+                        * @param[in]   error           Error code. If success, 0. Otherwise, a negative value.
+                        * @param[in]   records         Data records retreived.
+                        */
+                       virtual void on_query_result_received(unsigned int query_id, int error, std::vector<json>& records) = 0;
+       };
+
+}      /* namespace smr */
+
+#endif /* End of __SMARTREPLY_DATABASE_LISTENER_INTERFACE_H__ */
diff --git a/include/db_mgr.h b/include/db_mgr.h
new file mode 100755 (executable)
index 0000000..0749ea7
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SMARTREPLY_DB_MANAGER_H__
+#define __SMARTREPLY_DB_MANAGER_H__
+
+#include <cstddef>
+#include <sys/types.h>
+#include <vector>
+
+namespace smr {
+       /* Forward Declaration */
+       class json;
+       class db_listener_iface;
+
+       namespace db_manager {
+               /**
+                * @brief               Create a table if not exists. Async.
+                * @details             The column @c row_id is created by default, thus do not use the same column name.
+                *                              It is the primary of the auto-increment integer type.
+                * @param[in]   query_id        This number will be returned through db_listener_iface::on_creation_result_received().
+                * @param[in]   table_name      A table name to be created.
+                * @param[in]   columns         Columns. In SQL format. INTEGER, REAL, and TEXT types are allowed.
+                * @param[in]   option          Additional options. Allows NULL.
+                * @param[in]   listener        A listner object to receive the result. Allows NULL.
+                */
+               bool create_table(unsigned int query_id, const char* table_name, const char* columns, const char* option = NULL, db_listener_iface* listener = NULL);
+
+               /**
+                * @brief               Insert a record to a table. Async.
+                * @param[in]   query_id        This number will be returned through db_listener_iface::on_insertion_result_received().
+                * @param[in]   table_name      A table name in which the record is inserted.
+                * @param[in]   record          A json object containing key, value pairs.
+                * @param[in]   listener        A listner object to receive the result. Allows NULL.
+                */
+               bool insert(unsigned int query_id, const char* table_name, json& record, db_listener_iface* listener = NULL);
+
+               /**
+                * @brief               Execute a SQL query. Async.
+                * @param[in]   query_id        This number will be returned through db_listener_iface::on_query_result_received().
+                * @param[in]   query           A query to be executed.
+                * @param[in]   listener        A listner object to receive the result.
+                */
+               bool execute(unsigned int query_id, const char* query, db_listener_iface* listener);
+
+               /**
+                * @brief               Insert a record to a table. Sync.
+                * @attention   This cannot be used in the main thread.
+                * @param[in]   table_name      A table name in which the record is inserted.
+                * @param[in]   record          A json object containing key, value pairs.
+                * @param[out]  row_id          The row id of the inserted record. If fails, a negative integer.
+                */
+               bool insert_sync(const char* table_name, json& record, int64_t* row_id);
+
+               /**
+                * @brief               Execute a SQL query. Sync.
+                * @attention   This cannot be used in the main thread.
+                * @param[in]   query           A query to be executed.
+                * @param[out]  records         Query result.
+                */
+               bool execute_sync(const char* query, std::vector<json>* records);
+
+       }       /* namespace smr::db_manager */
+}      /* namespace smr */
+
+#endif /* __SMARTREPLY_DB_MANAGER_H__ */
diff --git a/include/db_mgr_iface.h b/include/db_mgr_iface.h
new file mode 100755 (executable)
index 0000000..e5c6c3e
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SMARTREPLY_DB_MANAGER_INTERFACE_H__
+#define __SMARTREPLY_DB_MANAGER_INTERFACE_H__
+
+#include <sys/types.h>
+
+namespace smr {
+       /* Forward Declaration */
+       class json;
+       class db_listener_iface;
+
+       class db_manager_iface {
+               public:
+                       virtual ~db_manager_iface() {}
+                       virtual bool create_table(unsigned int query_id, const char* table_name, const char* columns, const char* option = NULL, db_listener_iface* listener = NULL) = 0;
+                       virtual bool insert(unsigned int query_id, const char* table_name, json& record, db_listener_iface* listener = NULL) = 0;
+                       virtual bool execute(unsigned int query_id, const char* query, db_listener_iface* listener) = 0;
+                       virtual bool insert_sync(const char* table_name, json& record, int64_t* row_id) = 0;
+                       virtual bool execute_sync(const char* query, std::vector<json>* records) = 0;
+       };      /* class db_manager */
+
+       namespace db_manager {
+               void set_instance(db_manager_iface* mgr);
+       }       /* namespace smr::db_manager */
+}      /* namespace smr */
+
+#endif /* __SMARTREPLY_DB_MANAGER_INTERFACE_H__ */
diff --git a/include/dbus_listener_iface.h b/include/dbus_listener_iface.h
new file mode 100755 (executable)
index 0000000..461a222
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SMARTREPLY_DBUS_LISTENER_INTERFACE_H__
+#define __SMARTREPLY_DBUS_LISTENER_INTERFACE_H__
+
+#include <glib.h>
+
+namespace smr {
+
+       class dbus_listener_iface {
+               public:
+                       virtual ~dbus_listener_iface() {}
+
+                       /**
+                        * @brief       Called when receiving a signal.
+                        * @param[in]   sender  The unique bus name of the sender of the signal.
+                        * @param[in]   path    The object path that the signal was emitted on.
+                        * @param[in]   iface   The name of the interface.
+                        * @param[in]   name    The name of the signal.
+                        * @param[in]   param   A GVariant tuple with parameters of the signal.
+                        */
+                       virtual void on_signal_received(const char* sender, const char* path, const char* iface, const char* name, GVariant* param) = 0;
+       };
+
+}      /* namespace smr */
+
+#endif /* End of __SMARTREPLY_DBUS_LISTENER_INTERFACE_H__ */
diff --git a/include/dbus_server.h b/include/dbus_server.h
new file mode 100755 (executable)
index 0000000..6d03024
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SMARTREPLY_DBUS_SERVER_H__
+#define __SMARTREPLY_DBUS_SERVER_H__
+
+#include <sys/types.h>
+
+namespace smr {
+       /* Forward Declaration */
+       class dbus_listener_iface;
+
+       namespace dbus_server {
+               /**
+                * @brief       Subscribes to signals.
+                * @param[in]   sender          Sensor name to match on. NULL to listen from all senders.
+                * @param[in]   path            Object path to match on. NULL to match on all object paths.
+                * @param[in]   iface           D-Bus interface name to match on. NULL to match on all interfaces.
+                * @param[in]   name            D-Bus signal name to match on. NULL to match on all signals.
+                * @param[in]   listener        Listener object to receive matching signals.
+                * @return      A subscription identifier that can be used with signal_unsubscribe().@n
+                *                      If failed, a negative value.
+                */
+               int64_t signal_subscribe(const char* sender, const char* path, const char* iface, const char* name, dbus_listener_iface* listener);
+
+               /**
+                * @brief       Unsubscribes from signals.
+                */
+               void signal_unsubscribe(int64_t subscription_id);
+
+       }       /* namespace smr::dbus_server */
+}      /* namespace smr */
+
+#endif /* End of __SMARTREPLY_DBUS_SERVER_H__ */
diff --git a/include/dbus_server_iface.h b/include/dbus_server_iface.h
new file mode 100755 (executable)
index 0000000..e1e2779
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SMARTREPLY_DBUS_SERVER_INTERFACE_H__
+#define __SMARTREPLY_DBUS_SERVER_INTERFACE_H__
+
+#include <sys/types.h>
+
+namespace smr {
+       /* Forward Declaration */
+       class dbus_listener_iface;
+
+       class dbus_server_iface {
+               public:
+                       virtual ~dbus_server_iface() {}
+                       virtual int64_t signal_subscribe(const char* sender, const char* path, const char* iface, const char* name, dbus_listener_iface* listener) = 0;
+                       virtual void signal_unsubscribe(int64_t subscription_id) = 0;
+       };      /* class smr::dbus_server */
+
+       namespace dbus_server {
+               void set_instance(dbus_server_iface* svr);
+       }
+
+}      /* namespace smr */
+
+#endif /* End of __SMARTREPLY_DBUS_SERVER_INTERFACE_H__ */
+
diff --git a/include/event.h b/include/event.h
new file mode 100755 (executable)
index 0000000..698f17b
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _EVENT_DRIVEN_THREAD_H_
+#define _EVENT_DRIVEN_THREAD_H_
+
+#include <glib.h>
+
+class event_driven_thread {
+       private:
+               struct event_message_s {
+                       bool is_stop_signal;
+                       int type;
+                       void* data;
+                       event_message_s() : is_stop_signal(false), type(-1), data(NULL) {}
+               };
+
+               struct {
+                       GThread *thread;
+                       gint is_running;
+                       GAsyncQueue *event_queue;
+               } thread_info;
+
+               static gpointer thread_func_wrapper(gpointer func);
+               void process_event_queue();
+               virtual void on_thread_event_popped(int type, void* data) = 0;
+               virtual void delete_thread_event(int type, void* data) = 0;
+
+       protected:
+               event_driven_thread();
+               bool push_thread_event(int type, void* data = NULL);
+
+       public:
+               virtual ~event_driven_thread();
+               bool start();
+               bool stop();
+               bool is_running();
+
+};     /* class event_driven_thread */
+
+#endif /* _EVENT_DRIVEN_THREAD_H_ */
diff --git a/include/json.h b/include/json.h
new file mode 100755 (executable)
index 0000000..29c444b
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SMARTREPLY_JSON_H__
+#define __SMARTREPLY_JSON_H__
+
+#include <sys/types.h>
+#include <glib.h>
+#include <string>
+#include <list>
+#include <types_internal.h>
+
+#define _J(cmt, jobj) \
+do { \
+       _SD("%s: %s", (cmt), jobj.str().c_str()); \
+} while(0)
+
+#define EMPTY_JSON_OBJECT      "{}"
+#define DEFAULT_PRECISION      3
+#define COMMON_ATTR_CLIENT_APP_ID      "_ClientAppId_"
+
+namespace smr {
+
+       class json {
+               private:
+                       typedef struct _JsonNode json_node_t;
+                       json_node_t * json_node;
+
+                       void parse(const char* s);
+                       void release();
+
+                       /* For json vs json comparison */
+                       bool get_member_list(json_node_t* node, std::list<std::string>& list);
+                       bool node_equals(json_node_t* lhs, json_node_t* rhs);
+                       bool value_equals(json_node_t* lhs, json_node_t* rhs);
+                       bool object_equals(json_node_t* lhs, json_node_t* rhs);
+                       bool array_equals(json_node_t* lhs, json_node_t* rhs);
+
+               public:
+                       json();
+                       json(const char* s);
+                       json(const std::string& s);
+
+                       /* This json(const json& j) only copies the reference to the underlying json node.
+                        * Therefore, changes applied to a json object affect the other.
+                        * If you need to create a 'real' copy of a json, which can be manipulated separately,
+                        * utilize the str() function, e.g., smr::json copy(original.str());
+                        */
+                       json(const json& j);
+
+                       //TODO: Constructor accepting a file descriptor?
+
+                       ~json();
+
+                       json& operator=(const char* s);
+                       json& operator=(const std::string& s);
+
+                       /* This operator=(const json& j) only copies the reference to the underlying json node.
+                        * Therefore, changes applied to a json object affect the other.
+                        * If you need to create a 'real' copy of a json, which can be manipulated separately,
+                        * utilize the str() function, e.g., smr::json copy = original.str();
+                        */
+                       json& operator=(const json& j);
+
+                       bool operator==(const json& rhs);
+                       bool operator!=(const json& rhs);
+
+                       char* dup_cstr();
+                       std::string str();
+
+                       bool get_keys(std::list<std::string>* list);
+
+                       bool set(const char* path, const char* key, json& val);
+                       bool set(const char* path, const char* key, int val);
+                       bool set(const char* path, const char* key, int64_t val);
+                       bool set(const char* path, const char* key, double val, int prec = DEFAULT_PRECISION);
+                       bool set(const char* path, const char* key, std::string val);
+
+                       bool get(const char* path, const char* key, json* val);
+                       bool get(const char* path, const char* key, int* val);
+                       bool get(const char* path, const char* key, int64_t* val);
+                       bool get(const char* path, const char* key, double* val);
+                       bool get(const char* path, const char* key, std::string* val);
+
+                       int array_get_size(const char* path, const char* key);
+
+                       bool array_append(const char* path, const char* key, json& val);
+                       bool array_append(const char* path, const char* key, int val);
+                       bool array_append(const char* path, const char* key, int64_t val);
+                       bool array_append(const char* path, const char* key, double val, int prec = DEFAULT_PRECISION);
+                       bool array_append(const char* path, const char* key, std::string val);
+
+                       bool array_set_at(const char* path, const char* key, int index, json& val);
+                       bool array_set_at(const char* path, const char* key, int index, int val);
+                       bool array_set_at(const char* path, const char* key, int index, int64_t val);
+                       bool array_set_at(const char* path, const char* key, int index, double val, int prec = DEFAULT_PRECISION);
+                       bool array_set_at(const char* path, const char* key, int index, std::string val);
+
+                       bool get_array_elem(const char* path, const char* key, int index, json* val);
+                       bool get_array_elem(const char* path, const char* key, int index, int* val);
+                       bool get_array_elem(const char* path, const char* key, int index, int64_t* val);
+                       bool get_array_elem(const char* path, const char* key, int index, double* val);
+                       bool get_array_elem(const char* path, const char* key, int index, std::string* val);
+
+#if 0
+//TODO: Implement below helper functions if necessary
+                       bool set_array(const char* path, const char* key, json val[], int size);
+                       bool set_array(const char* path, const char* key, int val[], int size);
+                       bool set_array(const char* path, const char* key, int64_t val[], int size);
+                       bool set_array(const char* path, const char* key, double val[], int size);
+                       bool set_array(const char* path, const char* key, std::string val[], int size);
+
+                       bool get_array(const char* path, const char* key, json** val, int* size);
+                       bool get_array(const char* path, const char* key, int** val, int* size);
+                       bool get_array(const char* path, const char* key, int64_t** val, int* size);
+                       bool get_array(const char* path, const char* key, double** val, int* size);
+                       bool get_array(const char* path, const char* key, std::string** val, int* size);
+#endif
+       };
+
+}      /* namespace smr */
+
+#endif // __SMARTREPLY_JSON_H__
+
diff --git a/include/request_handler.h b/include/request_handler.h
new file mode 100755 (executable)
index 0000000..f84a8c2
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SMARTREPLY_LIB_REQUEST_HANDLER_H__
+#define __SMARTREPLY_LIB_REQUEST_HANDLER_H__
+#include <string>
+#include "json.h"
+
+namespace smr { namespace request_handler {
+
+       typedef void (* subject_response_cb)(const char* subject, int req_id, int error, smr::json response);
+
+       int add_engine(const char* language, int* req_id, std::string* request_result);
+
+       int remove_engine(const char* language, int* req_id);
+
+       typedef void (* get_reply_response_cb)(int req_id, int error, void* ext, smr::json& response);
+       int get_reply_async(const char* input, const char* sender, int* req_id, void* ext, get_reply_response_cb cb);
+
+       int get_reply(const char* input, const char* sender, int* req_id, smr::json* request_result);
+
+       int send_feedback(const char* app_id, const char* sender, const char* req_message,
+                       const char* replied_str, int* req_id);
+
+       int is_supported(const char* language, int* req_id);
+
+       int is_loaded(const char* language, int* req_id);
+
+       int user_feedback(int* req_id);
+
+       int send_prepare_engine();
+
+} }    /* namespace smr::request_handler */
+
+#endif // __SMARTREPLY_LIB_REQUEST_HANDLER_H__
diff --git a/include/response_handler.h b/include/response_handler.h
new file mode 100755 (executable)
index 0000000..89c9657
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SMARTREPLY_LIB_RESPONSE_HANDLER_H__
+#define __SMARTREPLY_LIB_RESPONSE_HANDLER_H__
+
+namespace smr { namespace response_handler {
+
+       void deliver(const char* subject, int req_id, int error, const char* data);
+
+} }    /* namespace smr::response_handler */
+
+#endif // __SMARTREPLY_LIB_RESPONSE_HANDLER_H__
diff --git a/include/scope_mutex.h b/include/scope_mutex.h
new file mode 100755 (executable)
index 0000000..02d6225
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SMARTREPLY_SCOPE_MUTEX_H__
+#define __SMARTREPLY_SCOPE_MUTEX_H__
+
+#include <glib.h>
+#include <types_internal.h>
+
+namespace smr {
+       // RAII Class implementing the mutex helper on the base of GLib mutex,
+       // which automatically locks mutex during its creation and unlocks while exiting the scope.
+       class scope_mutex
+       {
+               private:
+                       GMutex *mutex;
+
+               public:
+                       scope_mutex(GMutex *m);
+                       ~scope_mutex();
+       };
+}      /* namespace smr */
+
+#endif // __SMARTREPLY_SCOPE_MUTEX_H__
diff --git a/include/smartreply_service.h b/include/smartreply_service.h
new file mode 100755 (executable)
index 0000000..3956ecc
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * Copyright   2000-2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * PROPRIETARY/CONFIDENTIAL
+ *
+ * This software is the confidential and proprietary information of
+ * SAMSUNG ELECTRONICS ("Confidential Information").
+ * You shall not disclose such Confidential Information and shall
+ * use it only in accordance with the terms of the license agreement
+ * you entered into with SAMSUNG ELECTRONICS.
+ * SAMSUNG make no representations or warranties about the suitability
+ * of the software, either express or implied, including but not
+ * limited to the implied warranties of merchantability, fitness for
+ * a particular purpose, or non-infringement.
+ * SAMSUNG shall not be liable for any damages suffered by licensee as
+ * a result of using, modifying or distributing this software or its derivatives.
+ */
+
+
+#ifndef __SMARTREPLY_SERVICE_H__
+#define __SMARTREPLY_SERVICE_H__
+
+#include <tizen_error.h>
+
+/**
+ *
+ * @file smartreply_service.h
+ * @brief This file contains the top level functions of SmartReply API.
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// SmartReply Service
+
+/**
+ * @ingroup    CAPI_SMARTREPLY_SERVICE_MODULE
+ * @defgroup   CAPI_SMARTREPLY_SERVICE SmartReply Service
+ *
+ * @addtogroup CAPI_SMARTREPLY_SERVICE
+ * @{
+ *
+ */
+
+/**
+ * @brief Enumeration of error codes for the SmartReply service
+ * @since_tizen 2.3.1
+ */
+typedef enum _smartreply_service_e {
+       SMARTREPLY_ERROR_NONE                                   = TIZEN_ERROR_NONE,     /**< Successful */
+       SMARTREPLY_ERROR_PERMISSION_DENIED              = TIZEN_ERROR_PERMISSION_DENIED,        /**< Permission Denied */
+       SMARTREPLY_ERROR_OUT_OF_MEMORY                  = TIZEN_ERROR_OUT_OF_MEMORY,    /**< Out of memory */
+       SMARTREPLY_ERROR_INVALID_PARAMETER              = TIZEN_ERROR_INVALID_PARAMETER,        /**< Invalid parameter */
+       SMARTREPLY_ERROR_CONNECTION_TIME_OUT    = TIZEN_ERROR_CONNECTION_TIME_OUT,      /**< Timeout error, no answer */
+       SMARTREPLY_ERROR_INVALID_OPERATION              = TIZEN_ERROR_INVALID_OPERATION,        /**< Operation is not valid */
+       SMARTREPLY_ERROR_UNKNOWN                                = TIZEN_ERROR_UNKNOWN,  /**< Unknown error */
+       SMARTREPLY_ERROR_NO_DATA                                = TIZEN_ERROR_NO_DATA,  /**< Requested data does not exist */
+       SMARTREPLY_ERROR_NOT_SUPPORTED_LANGUAGE = 2001, /**< Not supported language */
+       SMARTREPLY_ERROR_OPERATION_FAILED               = 2002, /**< Operation failed */
+} smartreply_service_e;
+
+
+typedef struct smartreply_reply_s* smartreply_reply_h;
+
+/**
+ * @brief      Checks whether engine supports the specified language
+ * @since_tizen 2.3.1
+ * @param[in]  language        Language code like 'en_US', 'ko_KR'
+ * @param[out] is_enable       True, if engine supports the language.  False, otherwise
+ * @return 0 on success, otherwise a negative error value
+ * @retval SMARTREPLY_ERROR_NONE Successful
+ */
+int smartreply_service_is_language_supported(const char* language, bool* is_enable);
+
+/**
+ * @brief      Requests Smart Replies to Engine
+ * @since_tizen 2.3.1
+ * @param[in]  app_id  Unique id of application
+ * @param[in]  sender  Sender information (phone number)
+ * @param[in]  message Received message from sender
+ * @param[out] candidate_list  Candidate answer list
+ * @param[out] count   The total number of the replies.
+ * @return 0 on success, otherwise a negative error value
+ * @retval SMARTREPLY_ERROR_NONE Successful
+ * @retval SMARTREPLY_ERROR_NOT_SUPPORTED Specified language is not supported
+ * @retval SMARTREPLY_ERROR_OPERATION_FAILED Operation failed because of a system error
+ * @retval SMARTREPLY_ERROR_OUT_OF_MEMORY Out of memory
+ * @see        smartreply_service_get_nth_reply_message()
+ * @see        smartreply_service_destory_list()
+ */
+int smartreply_service_get_replies(const char* app_id, const char* sender,
+       const char* message, smartreply_reply_h** candidate_list, int* count);
+
+/**
+ * @brief      Callback function to get Smart Replies from Engine
+ * @since_tizen 2.3.1
+ * @param[in]  request_id      Request ID returned by smartreply_service_get_replies_async()
+ * @param[in]  error   error code
+ *              SMARTREPLY_ERROR_NONE Successful
+ *              SMARTREPLY_ERROR_NOT_SUPPORTED Specified language is not supported
+ *              SMARTREPLY_ERROR_OPERATION_FAILED Operation failed because of a system error
+ *              SMARTREPLY_ERROR_OUT_OF_MEMORY Out of memory
+ * @param[in]  candidate_list  Candidate answer list
+ * @param[in]  count   The total number of the replies
+ * @see        smartreply_service_get_nth_reply_message()
+ * @see        smartreply_service_destory_list()
+ */
+typedef void (*smartreply_service_replies_received_cb)(int request_id, int error, smartreply_reply_h* candidate_list, int count);
+
+/**
+ * @brief      Request Smart Replies to Engine asynchronously
+ * @since_tizen 2.3.1
+ * @param[in]  app_id  Unique ID of application
+ * @param[in]  sender  Sender information (phone number)
+ * @param[in]  message Received message from sender
+ * @param[in]  callback                Callback function
+ * @return Incremental request ID which will also be passed by the first parameter of callback function
+ * @see        smartreply_service_get_nth_reply_message()
+ * @see        smartreply_service_destory_list()
+ * @see        smartreply_service_replies_received()
+ */
+int smartreply_service_get_replies_async(const char* app_id, const char* sender,
+    const char* message, smartreply_service_replies_received_cb callback);
+/**
+ * @brief      Get nth reply message
+ * @since_tizen 2.3.1
+ * @param[in]  reply_list The list that includes replied messages
+ * @param[in]  index   The reply number which you want to get
+ * @param[out] message The reply message
+ * @remarks    You should free message parameter
+ * @return 0 on success, otherwise a negative error value
+ * @retval SMARTREPLY_ERROR_NONE Successful
+ * @retval SMARTREPLY_ERROR_NO_DATA There is no data.
+ * @pre        smartreply_service_get_replies_async()
+ * @pre        smartreply_service_get_replies()
+ */
+int smartreply_service_get_nth_reply_message(smartreply_reply_h* reply_list,
+                                       int index, char** message);
+
+/**
+ * @brief      Get nth reply message with type
+ * @since_tizen 2.3.1
+ * @param[in]  reply_list The list that includes replied messages
+ * @param[in]  index   The reply number which you want to get
+ * @param[out] type    The type of the reply. one of "TEXT", "TIME", "DATE", "DAYOFWEEK", "LOCATION"
+ * @param[out] message The reply message
+ * @remarks    You should free message and type parameter
+ * @return 0 on success, otherwise a negative error value
+ * @retval SMARTREPLY_ERROR_NONE Successful
+ * @retval SMARTREPLY_ERROR_NO_DATA There is no data.
+ * @pre        smartreply_service_get_replies_async()
+ * @pre        smartreply_service_get_replies()
+ */
+int smartreply_service_get_nth_reply_message_with_type(smartreply_reply_h* reply_list,
+                                       int index, char** type, char** message);
+/**
+ * @brief      Deletes reply_list struct
+ * @since_tizen 2.3.1
+ * @param[in]  reply_list The list that you want to delete
+ * @return 0 on success, otherwise a negative error value
+ * @retval SMARTREPLY_ERROR_NONE Successful
+ * @retval SMARTREPLY_ERROR_NO_DATA There is no data.
+ * @pre        smartreply_service_get_replies_async()
+ * @pre        smartreply_service_get_replies()
+ */
+int smartreply_service_destory_list(smartreply_reply_h* reply_list);
+
+/**
+ * @brief      Records users' reply to history to update future replies
+ * @since_tizen 2.3.1
+ * @param[in]  app_id Unique ID of application
+ * @param[in]  sender  Sender information (phone number)
+ * @param[in]  received_message        The received message from sender
+ * @param[in]  replied_message The replied message
+ * @return 0 on success, otherwise a negative error value
+ * @retval SMARTREPLY_ERROR_NONE Successful
+ * @retval SMARTREPLY_ERROR_NOT_SUPPORTED Specified language is not supported
+ * @retval SMARTREPLY_ERROR_OPERATION_FAILED Operation failed because of a system error
+ * @retval SMARTREPLY_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int smartreply_service_record_user_reply(const char* app_id,
+const char* sender, const char* received_message, const char* replied_message);
+
+/**
+ * @brief      Preload Engines
+ * @remarks    This API preloads engines before finding reply which will reduce delay of getting reply
+ * @since_tizen 2.3.1
+ * @return 0 on success, otherwise a negative error value
+ * @retval SMARTREPLY_ERROR_NONE Successful
+ * @retval SMARTREPLY_ERROR_NOT_SUPPORTED Specified language is not supported.
+ * @retval SMARTREPLY_ERROR_OPERATION_FAILED Operation failed because of a system error
+ * @retval SMARTREPLY_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int smartreply_service_prepare_engine();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SMARTREPLY_SERVICE_H__ */
diff --git a/include/smartreply_util.h b/include/smartreply_util.h
new file mode 100755 (executable)
index 0000000..429d6b2
--- /dev/null
@@ -0,0 +1,102 @@
+/* Copyright (c) 2014 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 __SMARTREPLY_UTIL_H__
+#define __SMARTREPLY_UTIL_H__
+
+#include <dlog.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "CAPI_SMARTREPLY_SERVICE"
+
+#ifndef EXPORT_API
+#define EXPORT_API __attribute__ ((visibility("default")))
+#endif
+
+
+/*
+* Internal Macros
+*/
+#define SMARTREPLY_LOGD(fmt,args...)  LOGD(fmt, ##args)
+#define SMARTREPLY_LOGW(fmt,args...)  LOGW(fmt, ##args)
+#define SMARTREPLY_LOGI(fmt,args...)  LOGI(fmt, ##args)
+#define SMARTREPLY_LOGE(fmt,args...)  LOGE(fmt, ##args)
+#define SMARTREPLY_SECLOG(fmt,args...)  SECURE_LOGD(fmt, ##args)
+
+#define SMARTREPLY_CHECK_CONDITION(condition, error, msg)     \
+        do { \
+                if (condition) { \
+                } else { \
+                        SMARTREPLY_LOGE("%s(0x%08x)", msg, error); \
+                        return error; \
+                } \
+        } while (0)
+
+#define SMARTREPLY_NULL_ARG_CHECK_RETURN_FALSE(arg)\
+        do { \
+                if(arg != NULL) { \
+                } else  { \
+                        SMARTREPLY_LOGE("SMARTREPLY_ERROR_INVALID_PARAMETER");  \
+                        return false; };        \
+        } while (0)
+
+#define SMARTREPLY_NULL_ARG_CHECK(arg)        \
+        SMARTREPLY_CHECK_CONDITION(arg != NULL,SMARTREPLY_ERROR_INVALID_PARAMETER,"SMARTREPLY_ERROR_INVALID_PARAMETER")
+
+#define SMARTREPLY_PRINT_ERROR_CODE_RETURN(code) \
+        do{ \
+                SMARTREPLY_LOGE("%s(0x%08x)", #code, code); \
+                return code;    \
+        } while (0)
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////
+
+#define _S(s) #s
+
+/*
+ * @brief       Copies one string to another and releases receiver if needed.
+ * @details This function copies one string to another and releases receiver if needed.
+ * @since_tizen 2.4
+ *
+ * @param[out]  dst             The destination string pointer.
+ * @param[in]   src             The original string pointer.
+ * @param[in]   max_length      The maximum size of bytes to be copied.
+ * @return      0 on success, otherwise a negative error value.
+ * @retval      #SMARTREPLY_ERROR_NONE Successful
+ * @retval      #SMARTREPLY_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int smartreply_set_string(const char *src, const int max_length, char **dst);
+
+/*
+ * @brief       Copies one string to another.
+ * @details This function copies one string to another.
+ * @since_tizen 2.4
+ *
+ * @param[out]  dst             The destination string pointer.
+ * @param[in]   src             The original string pointer.
+ * @param[in]   max_length      The maximum size of bytes to be copied.
+ * @return      0 on success, otherwise a negative error value.
+ * @retval      #SMARTREPLY_ERROR_NONE Successful
+ * @retval      #SMARTREPLY_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int smartreply_get_string(const char *src, const int max_length, char **dst);
+
+
+#endif
+/* __SMARTREPLY_UTIL_H__ */
diff --git a/include/types_internal.h b/include/types_internal.h
new file mode 100755 (executable)
index 0000000..6b29d7a
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SMARTREPLY_TYPES_INTERNAL_H__
+#define __SMARTREPLY_TYPES_INTERNAL_H__
+
+//#include <stdio.h>
+
+#include <smartreply_service.h>
+#include <assert.h>
+#include <tizen_error.h>
+#include <dlog.h>
+
+#define EXTAPI __attribute__ ((visibility("default")))
+#define EMPTY_STRING   ""
+
+/* Internal Error Codes
+ * Please define the necessary error codes here.
+ * Note that, these error codes must be aligned with the error enums defined in all API headers.
+ */
+
+/* Logging and Error Handling */
+#define _I SLOGI
+#define _D SLOGD
+#define _W SLOGW
+#define _E SLOGE
+#define _SI SECURE_SLOGI
+#define _SD SECURE_SLOGD
+#define _SW SECURE_LOGW
+#define _SE SECURE_SLOGE
+
+/* Color code for dlog */
+#define RED(X)         "\033[1;31m" X "\033[0m"
+#define GREEN(X)       "\033[1;32m" X "\033[0m"
+#define YELLOW(X)      "\033[1;33m" X "\033[0m"
+#define BLUE(X)                "\033[1;34m" X "\033[0m"
+#define PURPLE(X)      "\033[1;35m" X "\033[0m"
+#define CYAN(X)                "\033[1;36m" X "\033[0m"
+
+
+#define STR_EQ(X, Y) (g_strcmp0((X), (Y)) == 0)
+
+#define IF_FAIL_RETURN_TAG(cond, ret, tag, fmt, arg...) \
+       do { if (!(cond)) { tag(fmt, ##arg); return ret; } } while (0)
+
+#define IF_FAIL_RETURN(cond, ret) \
+       do { if (!(cond)) { return ret; } } while (0)
+
+#define IF_FAIL_VOID_TAG(cond, tag, fmt, arg...) \
+       do { if (!(cond)) { tag(fmt, ##arg); return; } } while (0)
+
+#define IF_FAIL_VOID(cond) \
+       do { if (!(cond)) { return; } } while (0)
+
+#define IF_FAIL_CATCH_TAG(cond, tag, fmt, arg...) \
+       do { if (!(cond)) { tag(fmt, ##arg); goto CATCH; } } while (0)
+
+#define IF_FAIL_CATCH(cond) \
+       do { if (!(cond)) { goto CATCH; } } while (0)
+
+#define IS_FAILED(X) ((X) != SMARTREPLY_ERROR_NONE)
+
+#define ASSERT_ALLOC(X)                IF_FAIL_RETURN_TAG(X, SMARTREPLY_ERROR_OUT_OF_MEMORY, _E, "Memory allocation failed")
+#define ASSERT_NOT_NULL(X)     IF_FAIL_RETURN_TAG(X, SMARTREPLY_ERROR_INVALID_PARAMETER, _E, "Parameter null")
+#define CHECK_NULL(p) \
+        if (NULL == p) { \
+                LOGE("[%s] INVALID_PARAMETER(0x%08x) %s is null.", \
+                        __FUNCTION__, SMARTREPLY_ERROR_INVALID_PARAMETER, #p); \
+                return SMARTREPLY_ERROR_INVALID_PARAMETER; \
+        }
+
+#define SMR_MEM_DATA_CPY(dest,src,len,type) \
+                do{ \
+                        if(src!=NULL&&len>0) \
+                        { \
+                                dest = (type *) calloc (len+1 , sizeof (type)); \
+                                assert(dest); \
+                                memcpy(dest, src, len*sizeof(type)); \
+                        } \
+                } while(0);
+
+
+
+#define HANDLE_GERROR(Err) \
+       do { if ((Err)) { _E("GError: %s", Err->message); g_error_free(Err); Err = NULL; } } while (0)
+
+
+/* DBus */
+#define DBUS_DEST              "org.tizen.smartreply"
+#define DBUS_PATH              "/org/tizen/smartreply"
+#define DBUS_IFACE             "org.tizen.smartreply"
+#define DBUS_TIMEOUT   3000000
+
+#define METHOD_REQUEST "Request"
+#define METHOD_RESPOND "Respond"
+#define SIGNAL_LAUNCHED        "Launched"
+
+enum request_type {
+       REQ_ADD_ENGINE = 1,
+       REQ_REMOVE_ENGINE,
+       REQ_GET_REPLY,
+       REQ_FEEDBACK,
+       REQ_IS_SUPPORTED,
+       REQ_IS_LOADED,
+       REQ_PREPARE_ENGINE,
+};
+
+#define ARG_REQTYPE            "type"
+#define ARG_COOKIE             "cookie"
+#define ARG_REQID              "req_id"
+#define ARG_SUBJECT            "subject"
+#define ARG_INPUT              "input"
+
+#define ARG_RESULT_ERR "r_err"
+#define ARG_RESULT_ADD "r_add"
+#define ARG_OUTPUT             "output"
+
+
+#endif /* __SMARTREPLY_TYPES_INTERNAL_H__ */
diff --git a/packaging/smartreply.manifest b/packaging/smartreply.manifest
new file mode 100755 (executable)
index 0000000..a76fdba
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+       <request>
+               <domain name="_" />
+       </request>
+</manifest>
diff --git a/packaging/smartreply.spec b/packaging/smartreply.spec
new file mode 100755 (executable)
index 0000000..3637e3c
--- /dev/null
@@ -0,0 +1,90 @@
+Name:       smartreply
+Summary:    Tizen SmartReply Framework Native API
+Version:    1.1.0
+Release:    1
+Group:      Framework/system
+License:    Apache License, Version 2.0
+Source0:    %{name}-%{version}.tar.gz
+
+BuildRequires: cmake
+BuildRequires: pkgconfig(aul)
+BuildRequires: pkgconfig(bundle)
+BuildRequires: pkgconfig(capi-appfw-app-control)
+BuildRequires: pkgconfig(pkgmgr-info)
+#BuildRequires: pkgconfig(capi-security-privilege-manager)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(gio-2.0)
+BuildRequires: pkgconfig(json-glib-1.0)
+#BuildRequires: pkgconfig(security-server)
+
+
+%ifarch %{arm}
+%define ARCH arm
+%else
+%define ARCH i586
+%endif
+
+%description
+Tizen SmartReply Framework Native API
+
+%prep
+%setup -q
+
+%build
+%if 0%{?sec_build_binary_debug_enable}
+export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
+export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
+%endif
+
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
+
+export   CFLAGS+=" -Wextra -Wcast-align -Wcast-qual -Wshadow -Wwrite-strings -Wswitch-default"
+export CXXFLAGS+=" -Wextra -Wcast-align -Wcast-qual -Wshadow -Wwrite-strings -Wswitch-default -Wnon-virtual-dtor -Wno-c++0x-compat"
+
+export   CFLAGS+=" -Wno-unused-parameter -Wno-empty-body"
+export CXXFLAGS+=" -Wno-unused-parameter -Wno-empty-body"
+
+export   CFLAGS+=" -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-strict-aliasing -fno-unroll-loops -fsigned-char -fstrict-overflow -fno-common"
+export CXXFLAGS+=" -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-strict-aliasing -fno-unroll-loops -fsigned-char -fstrict-overflow"
+
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DMAJORVER=${MAJORVER} -DFULLVER=%{version}
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+# Lisence
+mkdir -p %{buildroot}/usr/share/license
+cp LICENSE %{buildroot}/usr/share/license/%{name}
+
+%post
+/sbin/ldconfig
+
+%postun
+/sbin/ldconfig
+
+%files
+%manifest packaging/%{name}.manifest
+%defattr(-,root,root,-)
+%{_libdir}/*.so*
+%{_datadir}/license/%{name}
+#%if %{BINTYPE} == "engineer"
+%{_includedir}/smartreply/smartreply_service.h
+
+#%endif
+
+%package devel
+Summary:    Tizen SmartReply Framework Native API (Development)
+Group:      Framework/system
+Requires:      %{name} = %{version}-%{release}
+
+%description devel
+Tizen SmartReply Framework Native API (Development)
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/smartreply/*.h
+%{_libdir}/pkgconfig/%{name}.pc
diff --git a/smartreply.pc.in b/smartreply.pc.in
new file mode 100755 (executable)
index 0000000..50edac1
--- /dev/null
@@ -0,0 +1,13 @@
+#Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=/usr
+libdir=/usr/lib
+includedir=@PC_INCLUDE@
+
+Name: @PC_NAME@
+Description: @PC_DESCRIPTION@
+Version: @VERSION@
+Requires: @PC_REQUIRED@
+Libs: -L${libdir} @PC_LDFLAGS@
+Cflags: -I${includedir}
diff --git a/src/db_mgr.cpp b/src/db_mgr.cpp
new file mode 100755 (executable)
index 0000000..ca88162
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <types_internal.h>
+#include <json.h>
+#include <db_listener_iface.h>
+#include <db_mgr.h>
+#include <db_mgr_iface.h>
+
+static smr::db_manager_iface *_instance = NULL;
+
+void smr::db_manager::set_instance(smr::db_manager_iface* mgr)
+{
+       _instance = mgr;
+}
+
+bool smr::db_manager::create_table(unsigned int query_id, const char* table_name, const char* columns, const char* option, db_listener_iface* listener)
+{
+       IF_FAIL_RETURN_TAG(_instance, false, _E, "Not initialized");
+       return _instance->create_table(query_id, table_name, columns, option, listener);
+}
+
+bool smr::db_manager::insert(unsigned int query_id, const char* table_name, json& record, db_listener_iface* listener)
+{
+       IF_FAIL_RETURN_TAG(_instance, false, _E, "Not initialized");
+       return _instance->insert(query_id, table_name, record, listener);
+}
+
+bool smr::db_manager::execute(unsigned int query_id, const char* query, db_listener_iface* listener)
+{
+       IF_FAIL_RETURN_TAG(_instance, false, _E, "Not initialized");
+       return _instance->execute(query_id, query, listener);
+}
+
+bool smr::db_manager::insert_sync(const char* table_name, json& record, int64_t* row_id)
+{
+       IF_FAIL_RETURN_TAG(_instance, false, _E, "Not initialized");
+       return _instance->insert_sync(table_name, record, row_id);
+}
+
+bool smr::db_manager::execute_sync(const char* query, std::vector<json>* records)
+{
+       IF_FAIL_RETURN_TAG(_instance, false, _E, "Not initialized");
+       return _instance->execute_sync(query, records);
+}
diff --git a/src/dbus_client.cpp b/src/dbus_client.cpp
new file mode 100755 (executable)
index 0000000..ce09c50
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glib.h>
+#include <gio/gio.h>
+//#include <security-server.h>
+#include <iostream>
+
+#include "json.h"
+#include "types_internal.h"
+#include "scope_mutex.h"
+#include "response_handler.h"
+#include "smartreply_service.h"
+#include "dbus_client.h"
+
+using namespace std;
+
+static GDBusConnection *dbus_connection = NULL;
+static GDBusNodeInfo *dbus_node_info = NULL;
+
+static const gchar introspection_xml[] =
+       "<node>"
+       "       <interface name='"DBUS_IFACE"'>"
+       "               <method name='"METHOD_RESPOND"'>"
+       "                       <arg type='i' name='"ARG_REQID"' direction='in'/>"
+       "                       <arg type='s' name='"ARG_SUBJECT"' direction='in'/>"
+       "                       <arg type='i' name='"ARG_RESULT_ERR"' direction='in'/>"
+       "                       <arg type='s' name='"ARG_OUTPUT"' direction='in'/>"
+       "               </method>"
+       "       </interface>"
+       "</node>";
+
+static const char* get_security_cookie()
+{
+       static string s_dummy = "";
+       /*
+       static char *cookie = NULL;
+       static GMutex cookie_mutex;
+       smr::scope_mutex sm(&cookie_mutex);
+
+       if (cookie == NULL) {
+               int raw_size = security_server_get_cookie_size();
+               IF_FAIL_RETURN_TAG(raw_size > 0, NULL, _E, "Invalid cookie size");
+
+               int ret;
+               char raw_cookie[raw_size];
+
+               ret = security_server_request_cookie(raw_cookie, raw_size);
+               IF_FAIL_RETURN_TAG(ret >= 0, NULL, _E, "Failed to get the security cookie");
+
+               cookie = g_base64_encode(reinterpret_cast<guchar*>(raw_cookie), raw_size);
+               IF_FAIL_RETURN_TAG(cookie, NULL, _E, "Failed to encode the cookie");
+       }*/
+
+       return s_dummy.c_str();
+}
+
+static void handle_response(const gchar *sender, GVariant *param, GDBusMethodInvocation *invocation)
+{
+       gint req_id = 0;
+       const gchar *subject = NULL;
+       gint error = 0;
+       const gchar *data = NULL;
+
+       g_variant_get(param, "(i&si&s)", &req_id, &subject, &error, &data);
+
+#ifdef SHOW_SENDER_MSG
+       _I("[Response] ReqId: %d, Subject: %s, Error: %d", req_id, subject, error);
+       _D("Data: %s", data);
+#endif
+
+       smr::response_handler::deliver(subject, req_id, error, data);
+
+       g_dbus_method_invocation_return_value(invocation, NULL);
+}
+
+static void handle_method_call(GDBusConnection *conn, const gchar *sender,
+               const gchar *obj_path, const gchar *iface, const gchar *method_name,
+               GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
+{
+       IF_FAIL_VOID_TAG(STR_EQ(obj_path, DBUS_PATH), _W, "Invalid path: %s", obj_path);
+       IF_FAIL_VOID_TAG(STR_EQ(iface, DBUS_IFACE), _W, "Invalid interface: %s", obj_path);
+
+       if (STR_EQ(method_name, METHOD_RESPOND)) {
+               handle_response(sender, param, invocation);
+       } else {
+               _W("Invalid method: %s", method_name);
+       }
+}
+
+smr::dbus_client::dbus_client()
+{
+}
+
+smr::dbus_client::~dbus_client()
+{
+       release();
+}
+
+bool smr::dbus_client::init()
+{
+       static GMutex connection_mutex;
+       smr::scope_mutex sm(&connection_mutex);
+
+       if (dbus_connection) {
+               return true;
+       }
+
+       GError *gerr = NULL;
+
+       dbus_node_info = g_dbus_node_info_new_for_xml(introspection_xml, NULL);
+       IF_FAIL_RETURN_TAG(dbus_node_info != NULL, false, _E, "Initialization failed");
+
+       gchar *addr = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, &gerr);
+       HANDLE_GERROR(gerr);
+       IF_FAIL_RETURN_TAG(addr != NULL, false, _E, "Getting address failed");
+       _SD("Address: %s", addr);
+
+       dbus_connection = g_dbus_connection_new_for_address_sync(addr,
+                       (GDBusConnectionFlags)(G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION),
+                       NULL, NULL, &gerr);
+       g_free(addr);
+       HANDLE_GERROR(gerr);
+       IF_FAIL_RETURN_TAG(dbus_connection != NULL, false, _E, "Connection failed");
+
+       GDBusInterfaceVTable vtable;
+       vtable.method_call = handle_method_call;
+       vtable.get_property = NULL;
+       vtable.set_property = NULL;
+
+       guint reg_id = g_dbus_connection_register_object(dbus_connection, DBUS_PATH,
+                       dbus_node_info->interfaces[0], &vtable, NULL, NULL, &gerr);
+       HANDLE_GERROR(gerr);
+       IF_FAIL_RETURN_TAG(reg_id>0, false, _E, "Object registration failed");
+
+       _I("Dbus connection established: %s", g_dbus_connection_get_unique_name(dbus_connection));
+       return true;
+}
+
+void smr::dbus_client::release()
+{
+       if (dbus_connection) {
+               g_dbus_connection_flush_sync(dbus_connection, NULL, NULL);
+               g_dbus_connection_close_sync(dbus_connection, NULL, NULL);
+               g_object_unref(dbus_connection);
+               dbus_connection = NULL;
+       }
+
+       if (dbus_node_info) {
+               g_dbus_node_info_unref(dbus_node_info);
+               dbus_node_info = NULL;
+       }
+}
+
+namespace {
+       struct UserData {
+               smr::dbus_client::dbus_client_request_callback cb;
+               void* ext;
+               int req_id;
+       };
+       void g_async_ready_callback(GObject *source_object,
+                                                       GAsyncResult *res,
+                                                       gpointer user_data) {
+
+               _I("g_async_ready_callback");
+
+               GError *err = NULL;
+               GVariant *response = g_dbus_connection_call_finish(dbus_connection, res, &err);
+
+               HANDLE_GERROR(err);
+               //IF_FAIL_RETURN_TAG(response, ERR_OPERATION_FAILED, _E, "Method call failed");
+
+               gint _error = SMARTREPLY_ERROR_OPERATION_FAILED;
+               const gchar *_req_result = NULL;
+               const gchar *_data_read = NULL;
+
+               g_variant_get(response, "(i&s&s)", &_error, &_req_result, &_data_read);
+
+               string req(_req_result);
+               string data(_data_read);
+
+               UserData* ud = (UserData*)user_data;
+
+               ud->cb(ud->req_id, _error, ud->ext, req, data);
+               delete ud;
+               g_variant_unref(response);
+       }
+}
+
+int smr::dbus_client::request_async(
+               int type, int req_id, const char* subject, const char* input, void* ext, dbus_client_request_callback cb)
+{
+#ifdef SHOW_SENDER_MSG
+       _SI("Requesting: %d, %d, %s, %s", type, req_id, subject, input);
+#endif
+
+       if (subject == NULL) {
+               subject = EMPTY_STRING;
+       }
+
+       if (input == NULL) {
+               input = EMPTY_JSON_OBJECT;
+       }
+
+       const char *cookie = get_security_cookie();
+       IF_FAIL_RETURN_TAG(cookie, SMARTREPLY_ERROR_OPERATION_FAILED, _E, "Cookie generation failed");
+
+       GVariant *param = g_variant_new("(isiss)", type, cookie, req_id, subject, input);
+       IF_FAIL_RETURN_TAG(param, SMARTREPLY_ERROR_OUT_OF_MEMORY, _E, "Memory allocation failed");
+
+       UserData* user = new UserData;
+       user->req_id = req_id;
+       user->cb = cb;
+       user->ext = ext;
+
+       g_dbus_connection_call(dbus_connection, DBUS_DEST, DBUS_PATH, DBUS_IFACE,
+                       METHOD_REQUEST, param, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, g_async_ready_callback, (void*)user);
+
+
+       return SMARTREPLY_ERROR_NONE;
+}
+
+int smr::dbus_client::request(
+               int type, int req_id, const char* subject, const char* input,
+               std::string* req_result, std::string* data_read)
+{
+       _SI("Requesting: %d, %d, %s, %s", type, req_id, subject, input);
+
+       if (subject == NULL) {
+               subject = EMPTY_STRING;
+       }
+
+       if (input == NULL) {
+               input = EMPTY_JSON_OBJECT;
+       }
+
+       const char *cookie = get_security_cookie();
+       IF_FAIL_RETURN_TAG(cookie, SMARTREPLY_ERROR_OPERATION_FAILED, _E, "Cookie generation failed");
+
+       GVariant *param = g_variant_new("(isiss)", type, cookie, req_id, subject, input);
+       IF_FAIL_RETURN_TAG(param, SMARTREPLY_ERROR_OUT_OF_MEMORY, _E, "Memory allocation failed");
+
+       GError *err = NULL;
+       GVariant *response = g_dbus_connection_call_sync(dbus_connection, DBUS_DEST, DBUS_PATH, DBUS_IFACE,
+                       METHOD_REQUEST, param, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, &err);
+       HANDLE_GERROR(err);
+       IF_FAIL_RETURN_TAG(response, SMARTREPLY_ERROR_OPERATION_FAILED, _E, "Method call failed");
+
+       gint _error = SMARTREPLY_ERROR_OPERATION_FAILED;
+       const gchar *_req_result = NULL;
+       const gchar *_data_read = NULL;
+
+       g_variant_get(response, "(i&s&s)", &_error, &_req_result, &_data_read);
+       if (req_result) {
+               *req_result = _req_result;
+       }
+       if (data_read) {
+               *data_read = _data_read;
+       }
+
+       g_variant_unref(response);
+
+       return _error;
+}
+
+int smr::dbus_client::request_with_no_reply(
+               int type, int req_id, const char* subject, const char* input)
+{
+       _SI("Requesting: %d, %d, %s, %s", type, req_id, subject, input);
+
+       if (subject == NULL) {
+               subject = EMPTY_STRING;
+       }
+
+       if (input == NULL) {
+               input = EMPTY_JSON_OBJECT;
+       }
+
+       const char *cookie = get_security_cookie();
+       IF_FAIL_RETURN_TAG(cookie, SMARTREPLY_ERROR_OPERATION_FAILED, _E, "Cookie generation failed");
+
+       GVariant *param = g_variant_new("(isiss)", type, cookie, req_id, subject, input);
+       IF_FAIL_RETURN_TAG(param, SMARTREPLY_ERROR_OUT_OF_MEMORY, _E, "Memory allocation failed");
+
+       GError *err = NULL;
+       g_dbus_connection_call(dbus_connection, DBUS_DEST, DBUS_PATH, DBUS_IFACE,
+                       METHOD_REQUEST, param, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, NULL, &err);
+
+       if (err) {
+               HANDLE_GERROR(err);
+               return SMARTREPLY_ERROR_OPERATION_FAILED;
+       }
+
+       return SMARTREPLY_ERROR_NONE;
+}
diff --git a/src/dbus_client.h b/src/dbus_client.h
new file mode 100755 (executable)
index 0000000..baa64cb
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SMARTREPLY_LIB_DBUS_HANDLER_H__
+#define __SMARTREPLY_LIB_DBUS_HANDLER_H__
+
+#include <string>
+
+namespace smr {
+
+       class dbus_client {
+               public:
+                       dbus_client();
+                       ~dbus_client();
+
+                       bool init();
+                       void release();
+
+                       typedef void (*dbus_client_request_callback)(int req_id, int error, void* ext, const std::string& req_result, const std::string& data_read);
+                       int request_async(int type, int req_id, const char* subject, const char* input, void* ext, dbus_client_request_callback cb);
+                       int request(int type, int req_id, const char* subject, const char* input, std::string* req_result, std::string* data_read);
+                       int request_with_no_reply(int type, int req_id, const char* subject, const char* input);
+
+       };      /* classs smr::dbus_client */
+
+}      /* namespace smr */
+
+#endif // __SMARTREPLY_LIB_DBUS_HANDLER_H__
diff --git a/src/dbus_server.cpp b/src/dbus_server.cpp
new file mode 100755 (executable)
index 0000000..9bc5c2e
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "types_internal.h"
+#include "dbus_server.h"
+#include "dbus_server_iface.h"
+#include "dbus_listener_iface.h"
+
+static smr::dbus_server_iface *_instance = NULL;
+
+void smr::dbus_server::set_instance(dbus_server_iface* svr)
+{
+       _instance = svr;
+}
+
+int64_t smr::dbus_server::signal_subscribe(const char* sender, const char* path, const char* iface, const char* name, dbus_listener_iface* listener)
+{
+       IF_FAIL_RETURN_TAG(_instance, false, _E, "Not initialized");
+       return _instance->signal_subscribe(sender, path, iface, name, listener);
+}
+
+void smr::dbus_server::signal_unsubscribe(int64_t subscription_id)
+{
+       IF_FAIL_VOID_TAG(_instance, _E, "Not initialized");
+       _instance->signal_unsubscribe(subscription_id);
+}
diff --git a/src/event.cpp b/src/event.cpp
new file mode 100755 (executable)
index 0000000..c467fb3
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <new>
+#include "types_internal.h"
+#include "event.h"
+
+event_driven_thread::event_driven_thread()
+{
+       thread_info.thread = NULL;
+       thread_info.is_running = 0;
+       thread_info.event_queue = NULL;
+}
+
+event_driven_thread::~event_driven_thread()
+{
+       stop();
+}
+
+bool event_driven_thread::start()
+{
+       if (!g_atomic_int_get(&thread_info.is_running)) {
+               thread_info.event_queue = g_async_queue_new();
+               g_atomic_int_set(&thread_info.is_running, 1);
+               thread_info.thread = g_thread_new(NULL, thread_func_wrapper, static_cast<gpointer>(this));
+       }
+
+       return true;
+}
+
+bool event_driven_thread::stop()
+{
+       if (g_atomic_int_get(&thread_info.is_running)) {
+               event_message_s* event = new(std::nothrow) event_message_s;
+               IF_FAIL_RETURN_TAG(event, false, _E, "Memory allocation failed");
+
+               event->is_stop_signal = true;
+               g_async_queue_push(thread_info.event_queue, event);
+               g_atomic_int_set(&thread_info.is_running, 0);
+
+               g_thread_join(thread_info.thread);
+
+               // Free the memory allocated for the event queue
+               while ((event = static_cast<event_message_s*>(g_async_queue_try_pop(thread_info.event_queue)))) {
+                       if (event->data) {
+                               delete_thread_event(event->type, event->data);
+                       }
+                       delete event;
+               }
+               g_async_queue_unref(thread_info.event_queue);
+       }
+
+       return true;
+}
+
+bool event_driven_thread::is_running()
+{
+       if (g_atomic_int_get(&thread_info.is_running)) {
+               return true;
+       }
+       return false;
+}
+
+bool event_driven_thread::push_thread_event(int type, void* data)
+{
+       if (g_atomic_int_get(&thread_info.is_running)) {
+               event_message_s* event = new(std::nothrow) event_message_s;
+               IF_FAIL_RETURN_TAG(event, false, _E, "Memory allocation failed");
+
+               event->type = type;
+               event->data = data;
+               g_async_queue_push(thread_info.event_queue, event);
+               return true;
+       } else {
+               // If failed, free the received data object & return false.
+               delete_thread_event(type, data);
+               return false;
+       }
+}
+
+gpointer event_driven_thread::thread_func_wrapper(gpointer func)
+{
+       static_cast<event_driven_thread*>(func)->process_event_queue();
+       return NULL;
+}
+
+void event_driven_thread::process_event_queue()
+{
+       event_message_s *event = NULL;
+
+       while (g_atomic_int_get(&thread_info.is_running)) {
+
+               event = static_cast<event_message_s*>(g_async_queue_pop(thread_info.event_queue));
+
+               if (event) {
+                       if (event->is_stop_signal){
+                               delete event;
+                               break;
+                       } else {
+                               on_thread_event_popped(event->type, event->data);
+                               delete event;
+                       }
+               }
+
+       }
+}
diff --git a/src/json.cpp b/src/json.cpp
new file mode 100755 (executable)
index 0000000..aece126
--- /dev/null
@@ -0,0 +1,909 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <sstream>
+#include <locale>
+#include <iomanip>
+#include <json-glib/json-glib.h>
+#include <json.h>
+
+#define PATH_DELIM '.'
+
+static double string_to_double(const char* in)
+{
+       // Locale-independent string-to-double conversion
+       double out;
+       std::istringstream istr(in);
+       istr.imbue(std::locale("C"));
+       istr >> out;
+       return out;
+}
+
+static std::string double_to_string(double in, int prec)
+{
+       // Locale-independent double-to-string conversion
+       std::ostringstream ostr;
+       ostr.imbue(std::locale("C"));
+       ostr << std::setprecision(prec) << std::fixed << in;
+       return ostr.str();
+}
+
+smr::json::json()
+{
+       JsonObject *obj = json_object_new();
+       IF_FAIL_VOID_TAG(obj, _E, "Json object construction failed");
+
+       json_node = json_node_new(JSON_NODE_OBJECT);
+       if (!json_node) {
+               json_object_unref(obj);
+               _E("Json object construction failed");
+       }
+
+       json_node_set_object(json_node, obj);
+       json_object_unref(obj);
+}
+
+smr::json::json(const json& j)
+{
+       json_node = json_node_copy(j.json_node);
+       IF_FAIL_VOID_TAG(json_node, _E, "Json object construction failed");
+}
+
+smr::json::json(const char* s)
+{
+       if (s) {
+               parse(s);
+       } else {
+               parse(EMPTY_JSON_OBJECT);
+       }
+}
+
+smr::json::json(const std::string& s)
+{
+       if (s.empty()) {
+               parse(EMPTY_JSON_OBJECT);
+       } else {
+               parse(s.c_str());
+       }
+}
+
+smr::json::~json()
+{
+       release();
+}
+
+void smr::json::parse(const char* s)
+{
+       _SD("Parsing %s", s);
+
+       gboolean result;
+       JsonParser *parser = NULL;
+       JsonNode *root = NULL;
+
+       parser = json_parser_new();
+       IF_FAIL_CATCH_TAG(parser, _E, "Memory allocation failed");
+
+       result = json_parser_load_from_data(parser, s, -1, NULL);
+       IF_FAIL_CATCH_TAG(result, _E, "Parsing failed");
+
+       root = json_parser_get_root(parser);
+       IF_FAIL_CATCH_TAG(root, _E, "Getting root failed");
+
+       json_node = json_node_copy(root);
+       IF_FAIL_CATCH_TAG(json_node, _E, "Copying failed");
+
+       g_object_unref(parser);
+       return;
+
+CATCH:
+       if (parser) {
+               g_object_unref(parser);
+       }
+}
+
+void smr::json::release()
+{
+       if (json_node) {
+               json_node_free(json_node);
+               json_node = NULL;
+       }
+}
+
+smr::json& smr::json::operator=(const json& j)
+{
+       release();
+       json_node = json_node_copy(j.json_node);
+       if (!json_node) {
+               _E("Json object copy failed");
+       }
+       return *this;
+}
+
+smr::json& smr::json::operator=(const char* s)
+{
+       release();
+       parse(s);
+       return *this;
+}
+
+smr::json& smr::json::operator=(const std::string& s)
+{
+       release();
+       parse(s.c_str());
+       return *this;
+}
+
+bool smr::json::operator==(const json& rhs)
+{
+       return node_equals(json_node, rhs.json_node);
+}
+
+bool smr::json::operator!=(const json& rhs)
+{
+       return !operator==(rhs);
+}
+
+/* TODO
+bool smr::json::contains(const json& subset) const
+{
+       return false;
+}
+*/
+
+char* smr::json::dup_cstr()
+{
+       IF_FAIL_RETURN_TAG(json_node, NULL, _E, "Json object not initialized");
+
+       JsonGenerator *jgen = NULL;
+       char *output = NULL;
+
+       jgen = json_generator_new();
+       IF_FAIL_CATCH(jgen);
+
+       json_generator_set_root(jgen, json_node);
+       output = json_generator_to_data(jgen, NULL);
+       IF_FAIL_CATCH(output);
+
+       g_object_unref(jgen);
+       return output;
+
+CATCH:
+       if (jgen) {
+               g_object_unref(jgen);
+       }
+
+       _E("Memory allocation failed");
+       return NULL;
+}
+
+std::string smr::json::str()
+{
+       std::string output;
+       char *_s = dup_cstr();
+       IF_FAIL_RETURN(_s, output = EMPTY_JSON_OBJECT);
+
+       output = _s;
+       g_free(_s);
+
+       return output;
+}
+
+static char** tokenize_path(const char* path, int* length)
+{
+       //TODO: Re-implement this tokenizer using C++ stuff
+       char** tokens;
+       const char* pch;
+       const char* begin;
+       int i;
+       int j;
+       int len;
+
+       if (path == NULL || strlen(path) == 0) {
+               *length = 0;
+               return NULL;
+       }
+
+       *length = 1;
+
+       for (pch = path; *pch != '\0'; pch++) {
+               if (*pch == PATH_DELIM) {
+                       *length = *length + 1;
+               }
+       }
+
+       tokens = static_cast<char**>(g_malloc((*length) * sizeof(char*)));
+       IF_FAIL_RETURN_TAG(tokens, NULL, _E, "Memory allocation failed");
+
+       begin = path;
+       i = 0;
+
+       for (pch = path; ; pch++) {
+               if (*pch == PATH_DELIM || *pch == '\0') {
+                       len = pch - begin;
+                       tokens[i] = static_cast<char*>(g_malloc((len+1) * sizeof(char)));
+                       IF_FAIL_CATCH_TAG(tokens[i], _E, "Memory allocation failed");
+                       strncpy(tokens[i], begin, len);
+                       tokens[i][len] = '\0';
+                       i++;
+                       begin = pch + 1;
+               }
+
+               if (*pch == '\0') {
+                       break;
+               }
+       }
+
+       return tokens;
+
+CATCH:
+       for (j=0; j<i; j++) {
+               g_free(tokens[j]);
+       }
+       g_free(tokens);
+       return NULL;
+}
+
+static void free_tokenized_path(int length, char** tokens)
+{
+       int i;
+       if (tokens) {
+               for (i=0; i<length; i++) {
+                       g_free(tokens[i]);
+               }
+               g_free(tokens);
+       }
+}
+
+static JsonObject* traverse(JsonNode* jnode, const char* path, bool force)
+{
+       IF_FAIL_RETURN_TAG(jnode, NULL, _E, "Invalid parameter");
+
+       int length = 0;
+       int depth = 0;
+       char **path_token = NULL;
+       JsonObject *jobj = NULL;
+       JsonObject *child_obj = NULL;
+       JsonNode *child_node = NULL;
+
+       jobj = json_node_get_object(jnode);
+       IF_FAIL_RETURN(jobj, NULL);
+
+       if (path) {
+               path_token = tokenize_path(path, &length);
+               IF_FAIL_RETURN_TAG(path_token, NULL, _E, "Invalid path");
+       }
+
+       for (depth=0; depth<length; depth++) {
+               if (!json_object_has_member(jobj, path_token[depth])) {
+                       if (force) {
+                               child_obj = json_object_new();
+                               IF_FAIL_CATCH_TAG(child_obj, _E, "Memory allocation failed");
+                               json_object_set_object_member(jobj, path_token[depth], child_obj);
+                       } else {
+                               goto CATCH;
+                       }
+               }
+               child_node = json_object_get_member(jobj, path_token[depth]);
+               IF_FAIL_CATCH(child_node && json_node_get_node_type(child_node) == JSON_NODE_OBJECT);
+
+               jobj = json_node_get_object(child_node);
+               IF_FAIL_CATCH(jobj);
+       }
+
+       free_tokenized_path(length, path_token);
+       return jobj;
+
+CATCH:
+       free_tokenized_path(length, path_token);
+       return NULL;
+}
+
+bool smr::json::set(const char* path, const char* key, json& val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key && val.json_node, false, _E, "Invalid parameter");
+
+       JsonObject *jobj = traverse(json_node, path, true);
+       IF_FAIL_RETURN(jobj, false);
+
+       if (json_object_has_member(jobj, key))
+               json_object_remove_member(jobj, key);
+
+       json_object_set_member(jobj, key, val.json_node);
+       val.json_node = NULL;
+       val = json();
+
+       return true;
+}
+
+bool smr::json::set(const char* path, const char* key, int val)
+{
+       return set(path, key, static_cast<int64_t>(val));
+}
+
+bool smr::json::set(const char* path, const char* key, int64_t val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
+
+       JsonObject *jobj = traverse(json_node, path, true);
+       IF_FAIL_RETURN(jobj, false);
+
+       if (json_object_has_member(jobj, key))
+               json_object_remove_member(jobj, key);
+
+       json_object_set_int_member(jobj, key, val);
+       return true;
+}
+
+bool smr::json::set(const char* path, const char* key, double val, int prec)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
+
+       JsonObject *jobj = traverse(json_node, path, true);
+       IF_FAIL_RETURN(jobj, false);
+
+       if (json_object_has_member(jobj, key)) {
+               json_object_remove_member(jobj, key);
+       }
+
+       //NOTE: json-glib causes a precision issue while handling double values
+       json_object_set_string_member(jobj, key, double_to_string(val, prec).c_str());
+       return true;
+}
+
+bool smr::json::set(const char* path, const char* key, std::string val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
+
+       JsonObject *jobj = traverse(json_node, path, true);
+       IF_FAIL_RETURN(jobj, false);
+
+       if (json_object_has_member(jobj, key)) {
+               json_object_remove_member(jobj, key);
+       }
+
+       json_object_set_string_member(jobj, key, val.c_str());
+       return true;
+}
+
+bool smr::json::get(const char* path, const char* key, json* val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+       JsonObject *jobj = NULL;
+       JsonNode *node = NULL;
+
+       jobj = traverse(json_node, path, false);
+       IF_FAIL_RETURN(jobj && json_object_has_member(jobj, key), false);
+
+       node = json_object_dup_member(jobj, key);
+       IF_FAIL_RETURN_TAG(node, false, _E, "Memory allocation failed");
+
+       if (val->json_node) {
+               json_node_free(val->json_node);
+       }
+       val->json_node = node;
+
+       return true;
+}
+
+static JsonNode* search_value_node(JsonNode* jnode, const char* path, const char* key)
+{
+       JsonNode *node = NULL;
+       JsonObject *jobj = NULL;
+       JsonNodeType ntype;
+
+       jobj = traverse(jnode, path, false);
+       IF_FAIL_RETURN(jobj && json_object_has_member(jobj, key), NULL);
+
+       node = json_object_get_member(jobj, key);
+       ntype = json_node_get_node_type(node);
+       IF_FAIL_RETURN(ntype == JSON_NODE_VALUE, NULL);
+
+       return node;
+}
+
+bool smr::json::get(const char* path, const char* key, int* val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+       int64_t v;
+
+       if (get(path, key, &v)) {
+               *val = v;
+               return true;
+       }
+
+       return false;
+}
+
+bool smr::json::get(const char* path, const char* key, int64_t* val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+       JsonNode *node = search_value_node(json_node, path, key);
+       IF_FAIL_RETURN(node, false);
+
+       GType vtype = json_node_get_value_type(node);
+       if (vtype == G_TYPE_INT64) {
+               *val = json_node_get_int(node);
+       } else if (vtype == G_TYPE_STRING) {
+               //TODO: if the string is not a number?
+               *val = static_cast<int64_t>(string_to_double(json_node_get_string(node)));
+       } else {
+               return false;
+       }
+
+       return true;
+}
+
+bool smr::json::get(const char* path, const char* key, double* val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+       JsonNode *node = search_value_node(json_node, path, key);
+       IF_FAIL_RETURN(node, false);
+
+       GType vtype = json_node_get_value_type(node);
+       if (vtype == G_TYPE_DOUBLE) {
+               *val = json_node_get_double(node);
+       } else if (vtype == G_TYPE_INT64) {
+               *val = json_node_get_int(node);
+       } else if (vtype == G_TYPE_STRING) {
+               //NOTE: json-glib causes a precision issue while handling double values
+               *val = string_to_double(json_node_get_string(node));
+       } else {
+               return false;
+       }
+
+       return true;
+}
+
+bool smr::json::get(const char* path, const char* key, std::string* val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+       JsonNode *node = search_value_node(json_node, path, key);
+       IF_FAIL_RETURN(node, false);
+
+       GType vtype = json_node_get_value_type(node);
+       IF_FAIL_RETURN(vtype == G_TYPE_STRING, false);
+
+       *val = json_node_get_string(node);
+       return true;
+}
+
+static JsonArray* search_array(JsonNode* jnode, const char* path, const char* key, bool force)
+{
+       JsonNode *node = NULL;
+       JsonArray *arr = NULL;
+       JsonObject *jobj = NULL;
+
+       jobj = traverse(jnode, path, force);
+       IF_FAIL_RETURN(jobj, NULL);
+
+       if (!json_object_has_member(jobj, key)) {
+               if (force) {
+                       arr = json_array_new();
+                       IF_FAIL_RETURN_TAG(arr, NULL, _E, "Memory allocation failed");
+                       json_object_set_array_member(jobj, key, arr);
+               } else {
+                       return NULL;
+               }
+       }
+       node = json_object_get_member(jobj, key);
+       IF_FAIL_RETURN_TAG(node && json_node_get_node_type(node) == JSON_NODE_ARRAY,
+                       NULL, _E, "Type mismatched: %s", key);
+
+       return json_node_get_array(node);
+}
+
+int smr::json::array_get_size(const char* path, const char* key)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, -1, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key, -1, _E, "Invalid parameter");
+
+       JsonArray *jarr = search_array(json_node, path, key, false);
+       IF_FAIL_RETURN_TAG(jarr, -1, _W, "Mismatched data type");
+
+       return json_array_get_length(jarr);
+}
+
+bool smr::json::array_append(const char* path, const char* key, json& val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key && val.json_node, false, _E, "Invalid parameter");
+
+       JsonArray *arr = search_array(json_node, path, key, true);
+       IF_FAIL_RETURN(arr, false);
+
+       json_array_add_element(arr, val.json_node);
+       val.json_node = NULL;
+       val = json();
+
+       return true;
+}
+
+bool smr::json::array_append(const char* path, const char* key, int val)
+{
+       return array_append(path, key, static_cast<int64_t>(val));
+}
+
+bool smr::json::array_append(const char* path, const char* key, int64_t val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
+
+       JsonArray *arr = search_array(json_node, path, key, true);
+       IF_FAIL_RETURN(arr, false);
+
+       json_array_add_int_element(arr, val);
+       return true;
+}
+
+bool smr::json::array_append(const char* path, const char* key, double val, int prec)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
+
+       JsonArray *arr = search_array(json_node, path, key, true);
+       IF_FAIL_RETURN(arr, false);
+
+       //NOTE: json-glib causes a precision issue while handling double values
+       json_array_add_string_element(arr, double_to_string(val, prec).c_str());
+       return true;
+}
+
+bool smr::json::array_append(const char* path, const char* key, std::string val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key, false, _E, "Invalid parameter");
+
+       JsonArray *arr = search_array(json_node, path, key, true);
+       IF_FAIL_RETURN(arr, false);
+
+       json_array_add_string_element(arr, val.c_str());
+       return true;
+}
+
+static JsonNode* search_array_elem(JsonNode* jnode, const char* path, const char* key, int index)
+{
+       JsonArray *jarr = search_array(jnode, path, key, false);
+       IF_FAIL_RETURN_TAG(jarr, NULL, _W, "Mismatched data type");
+
+       int size = json_array_get_length(jarr);
+       IF_FAIL_RETURN(size > index, NULL);
+
+       JsonNode *node = json_array_get_element(jarr, index);
+       IF_FAIL_RETURN_TAG(node, NULL, _E, "Failed to get an array element");
+
+       return node;
+}
+
+bool smr::json::array_set_at(const char* path, const char* key, int index, json& val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(val.json_node && key && index >= 0, false, _E, "Invalid parameter");
+
+       JsonNode *node = search_array_elem(json_node, path, key, index);
+       IF_FAIL_RETURN_TAG(node, false, _W, "Out of range");
+       IF_FAIL_RETURN_TAG(json_node_get_node_type(node) == JSON_NODE_OBJECT, false, _E, "Type mismatched: %s[%d]", key, index);
+
+       JsonObject *obj = json_node_get_object(val.json_node);
+       IF_FAIL_RETURN_TAG(obj, false, _E, "Getting object failed");
+
+       json_node_set_object(node, obj);
+       json_node_free(val.json_node);
+       val.json_node = NULL;
+       val = json();
+
+       return true;
+}
+
+bool smr::json::array_set_at(const char* path, const char* key, int index, int val)
+{
+       return array_set_at(path, key, index, static_cast<int64_t>(val));
+}
+
+bool smr::json::array_set_at(const char* path, const char* key, int index, int64_t val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key && index >= 0, false, _E, "Invalid parameter");
+
+       JsonNode *node = search_array_elem(json_node, path, key, index);
+       IF_FAIL_RETURN_TAG(node, false, _W, "Out of range");
+       IF_FAIL_RETURN_TAG(json_node_get_node_type(node) == JSON_NODE_VALUE, false, _E, "Type mismatched: %s[%d]", key, index);
+       IF_FAIL_RETURN_TAG(json_node_get_value_type(node) == G_TYPE_INT64, false, _E, "Type mismatched: %s[%d]", key, index);
+
+       json_node_set_int(node, val);
+       return true;
+}
+
+bool smr::json::array_set_at(const char* path, const char* key, int index, double val, int prec)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key && index >= 0, false, _E, "Invalid parameter");
+
+       JsonNode *node = search_array_elem(json_node, path, key, index);
+       IF_FAIL_RETURN_TAG(node, false, _W, "Out of range");
+       IF_FAIL_RETURN_TAG(json_node_get_node_type(node) == JSON_NODE_VALUE, false, _E, "Type mismatched: %s[%d]", key, index);
+       IF_FAIL_RETURN_TAG(json_node_get_value_type(node) == G_TYPE_STRING, false, _E, "Type mismatched: %s[%d]", key, index);
+
+       json_node_set_string(node, double_to_string(val, prec).c_str());
+       return true;
+}
+
+bool smr::json::array_set_at(const char* path, const char* key, int index, std::string val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key && index >= 0, false, _E, "Invalid parameter");
+
+       JsonNode *node = search_array_elem(json_node, path, key, index);
+       IF_FAIL_RETURN_TAG(node, false, _W, "Out of range");
+       IF_FAIL_RETURN_TAG(json_node_get_node_type(node) == JSON_NODE_VALUE, false, _E, "Type mismatched: %s[%d]", key, index);
+       IF_FAIL_RETURN_TAG(json_node_get_value_type(node) == G_TYPE_STRING, false, _E, "Type mismatched: %s[%d]", key, index);
+
+       json_node_set_string(node, val.c_str());
+       return true;
+}
+
+bool smr::json::get_array_elem(const char* path, const char* key, int index, json* val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
+
+       JsonNode *node = search_array_elem(json_node, path, key, index);
+       IF_FAIL_RETURN(node, false);
+
+       JsonNode *node_copy = json_node_copy(node);
+       IF_FAIL_RETURN_TAG(node_copy, false, _E, "Memory allocation failed");
+
+       if (val->json_node) {
+               json_node_free(val->json_node);
+       }
+       val->json_node = node_copy;
+
+       return true;
+}
+
+bool smr::json::get_array_elem(const char* path, const char* key, int index, int* val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
+
+       int64_t v;
+       if (get_array_elem(path, key, index, &v)) {
+               *val = v;
+               return true;
+       }
+
+       return false;
+}
+
+bool smr::json::get_array_elem(const char* path, const char* key, int index, int64_t* val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
+
+       JsonNode *node = search_array_elem(json_node, path, key, index);
+       IF_FAIL_RETURN(node, false);
+
+       JsonNodeType ntype = json_node_get_node_type(node);
+       IF_FAIL_RETURN_TAG(ntype == JSON_NODE_VALUE, false, _E, "Type mismatched: %s", key);
+
+       GType vtype = json_node_get_value_type(node);
+       if (vtype == G_TYPE_INT64) {
+               *val = json_node_get_int(node);
+       } else if (vtype == G_TYPE_STRING) {
+               *val = static_cast<int64_t>(string_to_double(json_node_get_string(node)));
+       } else {
+               _E("Type mismatched: %s", key);
+               return false;
+       }
+
+       return true;
+}
+
+bool smr::json::get_array_elem(const char* path, const char* key, int index, double* val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
+
+       JsonNode *node = search_array_elem(json_node, path, key, index);
+       IF_FAIL_RETURN(node, false);
+
+       JsonNodeType ntype = json_node_get_node_type(node);
+       IF_FAIL_RETURN_TAG(ntype == JSON_NODE_VALUE, false, _E, "Type mismatched: %s", key);
+
+       GType vtype = json_node_get_value_type(node);
+       if (vtype == G_TYPE_DOUBLE) {
+               *val = json_node_get_double(node);
+       } else if (vtype == G_TYPE_INT64) {
+               *val = json_node_get_int(node);
+       } else if (vtype == G_TYPE_STRING) {
+               //NOTE: json-glib causes a precision issue while handling double values
+               *val = string_to_double(json_node_get_string(node));
+       } else {
+               _E("Type mismatched: %s", key);
+               return false;
+       }
+
+       return true;
+}
+
+bool smr::json::get_array_elem(const char* path, const char* key, int index, std::string* val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key && val && index >= 0, false, _E, "Invalid parameter");
+
+       JsonNode *node = search_array_elem(json_node, path, key, index);
+       IF_FAIL_RETURN(node, false);
+
+       JsonNodeType ntype = json_node_get_node_type(node);
+       IF_FAIL_RETURN_TAG(ntype == JSON_NODE_VALUE, false, _E, "Type mismatched: %s", key);
+
+       GType vtype = json_node_get_value_type(node);
+       IF_FAIL_RETURN_TAG(vtype == G_TYPE_STRING, false, _E, "Type mismatched: %s", key);
+       *val = json_node_get_string(node);
+
+       const char * str = json_node_get_string(node);
+       _SI("1. json string CONVERT TO UTF-8 %s", str);
+
+       /*char  * p_dest = NULL;
+       p_dest =  (char *)calloc(1, sizeof(char) * strlen(str)+1);
+       //(str,len, to_codeset, from_codeset, bytes_read, bytes_written, error)
+       gsize len = strlen(str) ;
+       p_dest = g_convert(str, strlen(str), "euc-kr", "utf-8", NULL, &len, NULL);
+
+       std::string return_str(p_dest);
+       _I("  -> returned %s - %d",  return_str.c_str(), len);
+       val = &return_str;
+       delete (str);*/
+       //free (p_dest);*/
+       return true;
+}
+
+bool smr::json::get_member_list(json_node_t* node, std::list<std::string>& list)
+{
+       IF_FAIL_RETURN(node, false);
+       list.clear();
+
+       JsonObject *jobj = json_node_get_object(node);
+       IF_FAIL_RETURN_TAG(jobj, false, _E, "Getting json object failed");
+
+       GList *members = json_object_get_members(jobj);
+       IF_FAIL_RETURN(members, true);
+
+       for (GList *it = g_list_first(members); it; it = g_list_next(it)) {
+               const char *key = static_cast<const char*>(it->data);
+               if (!key) {
+                       list.clear();
+                       g_list_free(members);
+                       _E("Member list extraction failed");
+                       return false;
+               }
+
+               list.push_back(key);
+       }
+
+       g_list_free(members);
+       return true;
+}
+
+bool smr::json::get_keys(std::list<std::string>* list)
+{
+       IF_FAIL_RETURN_TAG(list, false, _E, "Invalid parameter");
+       return get_member_list(json_node, *list);
+}
+
+bool smr::json::node_equals(json_node_t* lhs, json_node_t* rhs)
+{
+       IF_FAIL_RETURN(lhs && rhs, false);
+
+       JsonNodeType ltype = json_node_get_node_type(lhs);
+       JsonNodeType rtype = json_node_get_node_type(rhs);
+       IF_FAIL_RETURN(ltype == rtype, false);
+
+       switch (ltype) {
+               case JSON_NODE_VALUE:
+                       IF_FAIL_RETURN(value_equals(lhs, rhs), false);
+                       break;
+               case JSON_NODE_OBJECT:
+                       IF_FAIL_RETURN(object_equals(lhs, rhs), false);
+                       break;
+               case JSON_NODE_ARRAY:
+                       IF_FAIL_RETURN(array_equals(lhs, rhs), false);
+                       break;
+               default:
+                       _W("Unsupported type");
+                       return false;
+       }
+
+       return true;
+}
+
+bool smr::json::value_equals(json_node_t* lhs, json_node_t* rhs)
+{
+       GType ltype = json_node_get_value_type(lhs);
+       GType rtype = json_node_get_value_type(rhs);
+       IF_FAIL_RETURN(ltype == rtype, false);
+
+       switch (ltype) {
+               case G_TYPE_INT64:
+                       return json_node_get_int(lhs) == json_node_get_int(rhs);
+               case G_TYPE_DOUBLE:
+                       return json_node_get_double(lhs) == json_node_get_double(rhs);
+               case G_TYPE_STRING:
+                       return STR_EQ(json_node_get_string(lhs), json_node_get_string(rhs));
+               default:
+                       _W("Unsupported type");
+                       return false;
+       }
+}
+
+bool smr::json::object_equals(json_node_t* lhs, json_node_t* rhs)
+{
+       std::list<std::string> lm, rm;
+       IF_FAIL_RETURN(get_member_list(lhs, lm), false);
+       IF_FAIL_RETURN(get_member_list(rhs, rm), false);
+       IF_FAIL_RETURN(lm.size() == rm.size(), false);
+
+       lm.sort();
+       rm.sort();
+
+       std::list<std::string>::iterator lit, rit;
+       lit = lm.begin();
+       rit = rm.begin();
+
+       while (lit != lm.end()) {
+               IF_FAIL_RETURN(*lit == *rit, false);
+
+               json_node_t *lhs_child = json_object_get_member(json_node_get_object(lhs), (*lit).c_str());
+               json_node_t *rhs_child = json_object_get_member(json_node_get_object(rhs), (*rit).c_str());
+               IF_FAIL_RETURN(node_equals(lhs_child, rhs_child), false);
+
+               ++lit;
+               ++rit;
+       }
+
+       return true;
+}
+
+bool smr::json::array_equals(json_node_t* lhs, json_node_t* rhs)
+{
+       JsonArray *larr = json_node_get_array(lhs);
+       JsonArray *rarr = json_node_get_array(rhs);
+
+       int size = json_array_get_length(larr);
+       IF_FAIL_RETURN(size == static_cast<int>(json_array_get_length(rarr)), false);
+
+       for (int i=0; i<size; ++i) {
+               json_node_t *lhs_child = json_array_get_element(larr, i);
+               json_node_t *rhs_child = json_array_get_element(rarr, i);
+               IF_FAIL_RETURN(node_equals(lhs_child, rhs_child), false);
+       }
+
+       return true;
+}
diff --git a/src/request_handler.cpp b/src/request_handler.cpp
new file mode 100755 (executable)
index 0000000..f09b0fa
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <new>
+#include <glib.h>
+#include <map>
+#include <string>
+#include <iostream>
+#include "types_internal.h"
+#include "scope_mutex.h"
+#include "smartreply_service.h"
+#include "request_handler.h"
+#include "response_handler.h"
+#include "dbus_client.h"
+
+using namespace std;
+
+typedef std::map<std::string, smr::request_handler::subject_response_cb> response_cb_map_t;
+
+static smr::dbus_client *dbus_handle = NULL;
+static response_cb_map_t *response_cb_map = NULL;
+
+namespace {
+       class exit_handler {
+               public:
+                       exit_handler() {}
+                       ~exit_handler() { delete dbus_handle; }
+       };
+}
+
+static exit_handler _exit_handler;
+
+static int generate_req_id()
+{
+       static GMutex rid_mutex;
+       static int req_id = 0;
+
+       smr::scope_mutex sm(&rid_mutex);
+
+       // Overflow handling
+       if (++req_id < 0) {
+               req_id = 1;
+       }
+
+       return req_id;
+}
+
+static bool initialize()
+{
+       static GMutex init_mutex;
+       smr::scope_mutex sm(&init_mutex);
+
+       if (dbus_handle) {
+               return true;
+       }
+
+       response_cb_map = new(std::nothrow) response_cb_map_t;
+       IF_FAIL_CATCH_TAG(response_cb_map, _E, "Memory allocation failed");
+
+       dbus_handle = new(std::nothrow) smr::dbus_client();
+       IF_FAIL_CATCH_TAG(dbus_handle, _E, "Memory allocation failed");
+       IF_FAIL_CATCH_TAG(dbus_handle->init(), _E, "Dbus initialization failed");
+
+       return true;
+
+CATCH:
+       delete dbus_handle;
+       delete response_cb_map;
+       dbus_handle = NULL;
+       response_cb_map = NULL;
+       return false;
+}
+
+int smr::request_handler::add_engine(const char* language, int* req_id, std::string *request_result)
+{
+       ASSERT_NOT_NULL(language);
+       ASSERT_NOT_NULL(req_id);
+       ASSERT_NOT_NULL(request_result);
+
+       IF_FAIL_RETURN_TAG(initialize(), SMARTREPLY_ERROR_OPERATION_FAILED, _E, "Connection failed");
+       *req_id = generate_req_id();
+
+       std::string result_str;
+       int error = dbus_handle->request(REQ_ADD_ENGINE, *req_id, language, NULL, &result_str, NULL);
+
+       if (request_result) {
+               *request_result = result_str;
+       }
+       _I("[add_engine():Client Get Result] Error: %#x", error);
+       _SI("[add_engine():Client Get Result] Result: %s", result_str.c_str());
+
+       return error;
+}
+
+int smr::request_handler::remove_engine(const char* language, int* req_id)
+{
+       ASSERT_NOT_NULL(language);
+       ASSERT_NOT_NULL(req_id);
+       IF_FAIL_RETURN_TAG(initialize(), SMARTREPLY_ERROR_OPERATION_FAILED, _E, "Connection failed");
+
+       *req_id = generate_req_id();
+
+       std::string result_str;
+       int error = dbus_handle->request(REQ_REMOVE_ENGINE, *req_id, language, NULL, &result_str, NULL);
+       _I("[remove_engine():Client Get Result] Error: %#x", error);
+       _SI("[remove_engine():Client Get Result] Result: %s", result_str.c_str());
+       return error;
+
+}
+
+
+namespace {
+
+struct UserData {
+       smr::request_handler::get_reply_response_cb cb;
+       void* ext;
+};
+void dbus_callback(int req_id, int error, void* ext, const std::string& req_result, const std::string& data_read) {
+
+       _I("dbus_callback");
+
+       UserData* ud = (UserData*)ext;
+       smr::json res = req_result;
+
+       ud->cb(req_id, error, ud->ext, res);
+       delete ud;
+}
+
+}
+
+int smr::request_handler::get_reply_async(const char* sender, const char* input, int* req_id, void* ext, get_reply_response_cb cb)
+{
+       ASSERT_NOT_NULL(input);
+       ASSERT_NOT_NULL(sender);
+       ASSERT_NOT_NULL(req_id);
+       IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
+
+       *req_id = generate_req_id();
+
+#ifdef SHOW_SENDER_MSG
+       _I("[Get Reply] ReqId: %d, Input: [%s]: %s", *req_id, sender, input);
+#endif
+
+       std::string result_str;
+
+       UserData* ud = new UserData;
+       ud->cb = cb;
+       ud->ext = ext;
+
+       int error = dbus_handle->request_async(REQ_GET_REPLY, *req_id, sender, input, (void*)ud, dbus_callback);
+
+       _I("[get_reply():Client Get Result] Error: %#x", error);
+
+       return error;
+}
+
+int smr::request_handler::get_reply(const char* sender, const char* input, int* req_id, smr::json* request_result)
+{
+       ASSERT_NOT_NULL(input);
+       ASSERT_NOT_NULL(sender);
+       ASSERT_NOT_NULL(req_id);
+       ASSERT_NOT_NULL(request_result);
+       IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
+
+       *req_id = generate_req_id();
+       _SI("[Get Reply] ReqId: %d, Input: [%s]: %s", *req_id, sender, input);
+       std::string result_str;
+
+       int error = dbus_handle->request(REQ_GET_REPLY, *req_id, sender, input, &result_str, NULL);
+
+       if (request_result) {
+               *request_result = result_str;
+       }
+       _I("[get_reply():Client Get Result] Error: %#x", error);
+       _SI("[get_reply():Client Get Result] Result: %s", result_str.c_str());
+
+       return error;
+}
+
+int smr::request_handler::send_feedback(const char* app_id, const char* sender, const char* req_message,
+                       const char* replied_str, int* req_id)
+{
+       ASSERT_NOT_NULL(app_id);
+       ASSERT_NOT_NULL(sender);
+       ASSERT_NOT_NULL(req_message);
+       ASSERT_NOT_NULL(replied_str);
+       ASSERT_NOT_NULL(req_id);
+
+       _I(GREEN("Request_handler - send_feedback"));
+
+       *req_id = generate_req_id();
+       //_SI("[User Feedback] ReqId: %d, Pairs : [%s]@[%s]: %s <- %s", *req_id, sender, app_id, req_message, replied_str);
+
+       std::string req_str;
+       req_str.append(sender);
+       req_str.append("@");
+       req_str.append(app_id);
+       req_str.append("@");
+       req_str.append(req_message);
+
+       int error = dbus_handle->request_with_no_reply(REQ_FEEDBACK, *req_id, replied_str, req_str.c_str());
+
+       _I("[send_feedback():Client Get Result] Error: %#x", error);
+
+       return error;
+}
+
+int smr::request_handler::send_prepare_engine()
+{
+       IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
+
+       int req_id = generate_req_id();
+       int error = dbus_handle->request_with_no_reply(REQ_PREPARE_ENGINE, req_id, NULL, NULL);
+       
+       
+       _I("[prepare_engine():Client Get Result] Error: %#x", error);
+       return error;
+}
+
+int smr::request_handler::is_supported(const char* language, int* req_id)
+{
+       ASSERT_NOT_NULL(language);
+       ASSERT_NOT_NULL(req_id);
+       IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
+
+       *req_id = generate_req_id();
+       _SI("[is_supported] ReqId: %d, Language: %s", *req_id, language);
+       std::string result_str;
+       int error = dbus_handle->request(REQ_IS_SUPPORTED, *req_id, language, NULL, &result_str, NULL);
+       _I("[is_supported():Client] Error: %#x", error);
+       _SI("[is_supported(): Client IS_SURPPOTED] Result: %s", result_str.c_str());
+       return error;
+}
+
+int smr::request_handler::is_loaded(const char* language, int* req_id)
+{
+       ASSERT_NOT_NULL(language);
+       ASSERT_NOT_NULL(req_id);
+       IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
+
+       *req_id = generate_req_id();
+       _SI("[is_loaded] ReqId: %d, Language: %s", *req_id, language);
+       std::string result_str;
+       int error = dbus_handle->request(REQ_IS_LOADED, *req_id, language, NULL, &result_str, NULL);
+       _I("[is_loaded():Client IS_LOAEDED] Error: %#x", error);
+       _SI("[is_loaded():Client IS_LOADED] Result: %s", result_str.c_str());
+       return error;
+}
+
+void smr::response_handler::deliver(const char* subject, int req_id, int error, const char* data)
+{
+       response_cb_map_t::iterator it = response_cb_map->find(subject);
+       IF_FAIL_VOID_TAG(it != response_cb_map->end(), _E, "Unknown subject '%s'", subject);
+
+       it->second(subject, req_id, error, data);
+}
diff --git a/src/scope_mutex.cpp b/src/scope_mutex.cpp
new file mode 100755 (executable)
index 0000000..ab7ced9
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "scope_mutex.h"
+
+smr::scope_mutex::scope_mutex(GMutex *m) : mutex(m)
+{
+       g_mutex_lock(mutex);
+}
+
+smr::scope_mutex::~scope_mutex()
+{
+       g_mutex_unlock(mutex);
+}
diff --git a/src/smartreply_service.cpp b/src/smartreply_service.cpp
new file mode 100755 (executable)
index 0000000..4977900
--- /dev/null
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2014 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 <string>
+#include <sstream>
+#include <vector>
+#include <thread>
+#include "request_handler.h"
+#include "smartreply_service.h"
+#include "smartreply_util.h"
+#include <iostream>
+#include <sys/time.h>
+
+#define SMR_UNDEFINED_APP_ID_STRING "com.samsung.undefined"
+#define SMR_UNDEFINED_APP_ID_LENGTH 22
+#define SMR_UNDEFINED_SENDER_STRING "anonymous"
+#define SMR_UNDEFINED_SENDER_LENGTH 10
+
+using namespace std;
+
+typedef struct smartreply_reply_s {
+    int count;
+    GList *reply;
+    //GList *cursor;
+} _smartreply_reply_s;
+
+
+typedef struct smartreply_message_s {
+    char* message;
+    //int no;
+} _smartreply_message_s;
+
+std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
+    std::stringstream ss(s);
+    std::string item;
+    while (std::getline(ss, item, delim)) {
+        elems.push_back(item);
+    }
+    return elems;
+}
+
+std::vector<std::string> split(const std::string &s, char delim) {
+    std::vector<std::string> elems;
+    split(s, delim, elems);
+    return elems;
+}
+
+std::string check_null_str(const char* str, const char* def) {
+        return std::string(str == NULL || (strlen(str) == 0) ? def : str);
+
+}
+
+int _list_add_all(smartreply_reply_h** candidate_list, int* length, std::string result_str)
+{
+    ASSERT_NOT_NULL(candidate_list);
+    if (result_str.size() == 0) return SMARTREPLY_ERROR_NONE;
+
+    std::vector<std::string> reply_list = split(result_str, '|');
+    int count  = reply_list.size();
+    _I("Candidate Replies Count: %d", count);
+
+    smartreply_reply_s *s_list = NULL;
+    smartreply_message_s *s_message = NULL;
+
+    s_list = (smartreply_reply_s*)calloc(1, sizeof(smartreply_reply_s));
+       if (s_list == NULL) {
+               return SMARTREPLY_ERROR_OUT_OF_MEMORY;
+       }
+
+    for (std::vector<std::string>::iterator it = reply_list.begin(); it != reply_list.end(); ++it) {
+        _SI("Smart Reply : %s", it->c_str());
+               s_message = (smartreply_message_s*)calloc(1, sizeof(smartreply_message_s));
+               if (s_message == NULL) {
+                       free(s_list);
+                       return SMARTREPLY_ERROR_OUT_OF_MEMORY;
+               }
+
+               SMR_MEM_DATA_CPY(s_message->message, it->c_str(), it->size(), char);
+               if (NULL == s_message->message)
+               {
+                       _E("[OUT_OF_MEMORY] Fail to create 's_message->message'.");
+                       free(s_message);
+                       free(s_list);
+                       return SMARTREPLY_ERROR_OUT_OF_MEMORY;
+               }
+
+        s_list->reply = g_list_append(s_list->reply, s_message);
+        s_list->count++;
+    }
+
+    /* if (s_list->count == 0)
+           s_list->cursor = s_list->reply;
+    */
+    *candidate_list = (smartreply_reply_h*)s_list;
+    *length = s_list->count;
+
+    return SMARTREPLY_ERROR_NONE;
+}
+
+namespace {
+       int getTime() {
+               struct timeval now;
+               gettimeofday(&now, 0);
+               return now.tv_sec * 1000 + now.tv_usec / 1000;
+       }
+       bool isAction(const string& message) {
+               return message.find("&") != string::npos;
+       }
+       bool splitActionMessage(const string& action_msg, string& action_type, string& message) {
+               if (isAction(action_msg) == false) {
+                       return false;
+               }
+               action_type = action_msg.substr(0, action_msg.find("&"));
+               message = action_msg.substr(action_msg.find("&") + 1);
+               return true;
+       }
+
+}
+
+EXPORT_API int smartreply_service_get_replies(const char* app_id,
+const char* sender, const char* message, smartreply_reply_h** candidate_list, int* length)
+{
+       int start = getTime();
+       
+    ASSERT_NOT_NULL(message);
+    ASSERT_NOT_NULL(candidate_list);
+    ASSERT_NOT_NULL(length);
+    int req_id;
+    int err = -1;
+    std::string _str(check_null_str(sender, SMR_UNDEFINED_SENDER_STRING));
+    _str.append("|");
+    _str.append(check_null_str(app_id, SMR_UNDEFINED_APP_ID_STRING));
+
+    std::string sender_str = _str;
+    _SI("[%s] %s", sender_str.c_str(), message);
+
+    smr::json replies_str;
+    err = smr::request_handler::get_reply(sender_str.c_str(), message, &req_id, &replies_str);
+    IF_FAIL_RETURN_TAG(err == SMARTREPLY_ERROR_NONE, err, _E, "Getting reply list failed");
+    _SI("Read server's response: %s", replies_str.str().c_str());
+
+    std::string reply_str;
+    replies_str.get(NULL, "replies", &reply_str);
+    err = _list_add_all(candidate_list, length, reply_str);
+
+       int end = getTime();
+       _I("GetReplyTime : %d msec", end - start);
+    return err;
+}
+
+namespace {
+       void get_reply_callback2(int req_id, int error, void* ext, smr::json& response) {
+               _I("get_reply_callback");
+               _SI("Read server's response: %s", response.str().c_str());
+
+               int length = 0;
+               smartreply_reply_h* candidate_list = NULL;
+
+               std::string reply_str;
+               response.get(NULL, "replies", &reply_str);
+               int err = _list_add_all(&candidate_list, &length, reply_str);
+
+               ((smartreply_service_replies_received_cb)ext)(req_id, err, candidate_list, length);
+       }
+}
+
+EXPORT_API int smartreply_service_get_replies_async(const char* app_id, const char* sender,
+    const char* message, smartreply_service_replies_received_cb cb) {
+
+       std::string _str(check_null_str(sender, SMR_UNDEFINED_SENDER_STRING));
+       _str.append("|");
+       _str.append(check_null_str(app_id, SMR_UNDEFINED_APP_ID_STRING));
+
+       std::string sender_str = _str;
+       _SI("[%s]", sender_str.c_str());
+       std::string msg(message);
+
+       int req_id = 0;
+       smr::request_handler::get_reply_async(sender_str.c_str(), message, &req_id, (void*)cb, get_reply_callback2);
+
+       return req_id;
+}
+
+
+EXPORT_API int smartreply_service_get_nth_reply_message_with_type(smartreply_reply_h *reply_list, int index, char** type, char **reply_str) {
+    ASSERT_NOT_NULL(reply_list);
+    ASSERT_NOT_NULL(reply_str);
+
+    GList *cursor = NULL;
+    smartreply_reply_s *list_s;
+    list_s = (smartreply_reply_s *)reply_list;
+    int i, j;
+    char *temp = NULL;
+
+    for (i=0, j=0, cursor = list_s->reply; cursor; cursor = cursor->next, i++) {
+            if (j == index)
+            {
+                    smartreply_message_s * _message;
+                    _message = (smartreply_message_s*)cursor->data;
+                    int len =  strlen(_message->message);
+                                               
+                                       string action_msg = _message->message;
+                                       //cout << action_msg << endl;
+                                       if (isAction(action_msg)) {
+                                               //cout << "action msg" << endl;
+                                               string atype, msg;
+                                               splitActionMessage(action_msg, atype, msg);
+                                               //cout << atype << " " << msg << endl;
+                       SMR_MEM_DATA_CPY(temp, msg.c_str(), msg.length(), char);
+                                               *reply_str = temp;                                               
+                                               if (type != NULL) {
+                                                       SMR_MEM_DATA_CPY(temp, atype.c_str(), atype.length(), char);
+                                                       *type = temp;
+                                               }                                       
+                                       }
+                                       else {
+                       SMR_MEM_DATA_CPY(temp, _message->message, len, char);
+                                               *reply_str = temp;
+                                               if (type != NULL) {
+                                                       SMR_MEM_DATA_CPY(temp, "TEXT", strlen("TEXT"), char);
+                                                       *type = temp;
+                                               }                                       
+                                       }
+                    return SMARTREPLY_ERROR_NONE;
+            }
+            j++;
+    }
+    //free(temp);
+    return SMARTREPLY_ERROR_NO_DATA;
+}
+
+EXPORT_API int smartreply_service_get_nth_reply_message(smartreply_reply_h *reply_list, int index, char **reply_str) {
+    int res = smartreply_service_get_nth_reply_message_with_type(reply_list, index, NULL, reply_str);
+       return res;
+}
+EXPORT_API int smartreply_service_destory_list(smartreply_reply_h *reply_list) {
+    ASSERT_NOT_NULL(reply_list);
+
+    smartreply_reply_s* _reply;
+    _reply = (smartreply_reply_s*) reply_list;
+
+    GList *cursor = NULL;
+    for (cursor = _reply->reply; cursor; cursor = cursor->next) {
+               free(cursor->data);
+       }
+
+    g_list_free(_reply->reply);
+
+    free(reply_list);
+    return SMARTREPLY_ERROR_NONE;
+}
+
+EXPORT_API int smartreply_service_is_language_supported(const char* language, bool *is_enable) {
+    int req_id;
+    *is_enable = smr::request_handler::is_supported(language, &req_id);
+    _I("smartreply_service_is_supported %s : %d", language, is_enable);
+    return SMARTREPLY_ERROR_NONE;
+}
+
+
+EXPORT_API int smartreply_service_record_user_reply(const char* app_id,
+const char* sender, const char* received_message, const char* replied_message)
+{
+    std::string snd(check_null_str(sender, SMR_UNDEFINED_SENDER_STRING));
+    std::string aid(check_null_str(app_id, SMR_UNDEFINED_APP_ID_STRING));
+
+    int req_id;
+    int err = smr::request_handler::send_feedback(aid.c_str(), snd.c_str(), received_message, replied_message, &req_id);
+    IF_FAIL_RETURN_TAG(err == SMARTREPLY_ERROR_NONE, err, _E, "Send User Feedback is failed");
+
+    return err;
+}
+
+EXPORT_API int smartreply_service_prepare_engine() 
+{
+       int err = smr::request_handler::send_prepare_engine();
+       return err;
+}
+
+
+
+// Depreciated
+/*
+EXPORT_API int smartreply_service_is_supported(const char* language, bool *is_enable) {
+    return smartreply_service_is_language_supported(language, is_enable);
+}
+
+EXPORT_API int smartreply_service_get_replis(const char* app_id,
+const char* sender, const char* message, smartreply_reply_h** candidate_list, int* length) {
+       return smartreply_service_get_replies(app_id, sender, message, candidate_list, length);
+}
+
+namespace {
+       void get_reply_callback(int req_id, int error, void* ext, smr::json& response) {
+               _I("get_reply_callback");
+               _I("Read server's response: %s", response.str().c_str());
+
+               int length = 0;
+               smartreply_reply_h* candidate_list = NULL;
+
+               std::string reply_str;
+               response.get(NULL, "replies", &reply_str);
+               int err = _list_add_all(&candidate_list, &length, reply_str);
+
+               ((get_replis_callback)ext)(req_id, err, candidate_list, length);
+       }
+}
+
+EXPORT_API int smartreply_service_get_replis_async(const char* app_id, const char* sender,
+    const char* message, get_replis_callback cb) {
+
+       std::string _str(check_null_str(sender, SMR_UNDEFINED_SENDER_STRING));
+       _str.append("|");
+       _str.append(check_null_str(app_id, SMR_UNDEFINED_APP_ID_STRING));
+
+       std::string sender_str = _str;
+       _I("[%s]", sender_str.c_str());
+       std::string msg(message);
+
+       int req_id = 0;
+       smr::request_handler::get_reply_async(sender_str.c_str(), message, &req_id, (void*)cb, get_reply_callback);
+
+       return req_id;
+}
+
+EXPORT_API int smartreply_service_send_feedback(const char* app_id,
+const char* sender, const char* req_message, const char* replied_str)
+{
+       return smartreply_service_record_user_reply(app_id, sender, req_message, replied_str);
+}*/
diff --git a/src/starter.cpp b/src/starter.cpp
new file mode 100755 (executable)
index 0000000..5cdd247
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glib-object.h>
+
+#if !defined(GLIB_VERSION_2_36)
+namespace {
+       class g_type_initializer {
+               public:
+                       g_type_initializer() { g_type_init(); }
+                       ~g_type_initializer() {}
+       };
+}      /* namespace smr */
+
+static g_type_initializer initializer;
+#endif