tizen 2.4 release accepted/tizen_2.4_mobile tizen_2.4 accepted/tizen/2.4/mobile/20151029.033406 submit/tizen_2.4/20151028.064059 tizen_2.4_mobile_release
authorjk7744.park <jk7744.park@samsung.com>
Sat, 24 Oct 2015 07:39:00 +0000 (16:39 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Sat, 24 Oct 2015 07:39:00 +0000 (16:39 +0900)
38 files changed:
.gitignore [new file with mode: 0644]
AUTHORS [new file with mode: 0644]
CMakeLists.txt [new file with mode: 0644]
LICENSE [new file with mode: 0644]
context-common.pc.in [new file with mode: 0644]
include/context_mgr.h [new file with mode: 0644]
include/context_mgr_iface.h [new file with mode: 0644]
include/db_listener_iface.h [new file with mode: 0644]
include/db_mgr.h [new file with mode: 0644]
include/db_mgr_iface.h [new file with mode: 0644]
include/dbus_listener_iface.h [new file with mode: 0644]
include/dbus_server.h [new file with mode: 0644]
include/dbus_server_iface.h [new file with mode: 0644]
include/event_driven.h [new file with mode: 0644]
include/json.h [new file with mode: 0644]
include/provider_iface.h [new file with mode: 0644]
include/request_handler.h [new file with mode: 0644]
include/scope_mutex.h [new file with mode: 0644]
include/shared_vars.h [new file with mode: 0644]
include/timer_listener_iface.h [new file with mode: 0644]
include/timer_mgr.h [new file with mode: 0644]
include/timer_mgr_iface.h [new file with mode: 0644]
include/types_internal.h [new file with mode: 0644]
packaging/context-common.manifest [new file with mode: 0644]
packaging/context-common.spec [new file with mode: 0644]
src/context_mgr.cpp [new file with mode: 0644]
src/db_mgr.cpp [new file with mode: 0644]
src/dbus_client.cpp [new file with mode: 0644]
src/dbus_client.h [new file with mode: 0644]
src/dbus_server.cpp [new file with mode: 0644]
src/event_driven.cpp [new file with mode: 0644]
src/json.cpp [new file with mode: 0644]
src/provider_iface.cpp [new file with mode: 0644]
src/request_handler.cpp [new file with mode: 0644]
src/response_handler.h [new file with mode: 0644]
src/scope_mutex.cpp [new file with mode: 0644]
src/shared_vars.cpp [new file with mode: 0644]
src/timer_mgr.cpp [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..a01ee28
--- /dev/null
@@ -0,0 +1 @@
+.*.swp
diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..10e3f20
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+Mu-Woong Lee <muwoong.lee@samsung.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3757f59
--- /dev/null
@@ -0,0 +1,58 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(context-common)
+INCLUDE(GNUInstallDirs)
+
+# Targets
+SET(target_lib "ctx-common")
+
+# Source Lists
+FILE(GLOB_RECURSE SRCS src/*.cpp)
+MESSAGE("Sources: ${SRCS}")
+
+# Dependencies
+SET(DEPS "glib-2.0 gio-2.0 json-glib-1.0 dlog capi-base-common security-server")
+
+INCLUDE(FindPkgConfig)
+INCLUDE_DIRECTORIES(
+       ${CMAKE_CURRENT_SOURCE_DIR}/include
+       ${CMAKE_CURRENT_SOURCE_DIR}/src/shared
+)
+ADD_DEFINITIONS(-g -O2 -Wall -fPIC -Wl,--as-needed)
+
+# Building Library
+pkg_check_modules(lib_pkg REQUIRED ${DEPS})
+
+FOREACH(flag ${lib_pkg_CFLAGS})
+   SET(LIB_EXTRA_CFLAGS "${LIB_EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+ADD_LIBRARY(${target_lib} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${target_lib} ${lib_pkg_LDFLAGS})
+SET_TARGET_PROPERTIES(${target_lib} PROPERTIES COMPILE_FLAGS ${LIB_EXTRA_CFLAGS})
+SET_TARGET_PROPERTIES(${target_lib} PROPERTIES COMPILE_DEFINITIONS "LOG_TAG=\"CONTEXT\"")
+SET_TARGET_PROPERTIES(${target_lib} PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${target_lib} PROPERTIES VERSION ${FULLVER})
+
+# Installing Library
+INSTALL(TARGETS ${target_lib} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT RuntimeLibraries)
+INSTALL(
+       DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/context-service/internal
+       FILES_MATCHING PATTERN "*.h"
+)
+
+SET(VERSION ${FULLVER})
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(PC_NAME ${PROJECT_NAME})
+SET(PC_INCLUDE "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/context-service/internal")
+SET(PC_LIBDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
+SET(PC_DESCRIPTION "Tizen Context-Service Shared Library")
+SET(PC_REQUIRED ${DEPS})
+SET(PC_LDFLAGS -l${target_lib})
+SET(PC_CFLAGS -I\${includedir}/context-service/internal)
+
+CONFIGURE_FILE(
+       ${PROJECT_NAME}.pc.in
+       ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc
+       @ONLY
+)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..1b01074
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,204 @@
+Copyright (c) 2015 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) 2015 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/context-common.pc.in b/context-common.pc.in
new file mode 100644 (file)
index 0000000..378b991
--- /dev/null
@@ -0,0 +1,13 @@
+#Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=@PREFIX@
+libdir=@PC_LIBDIR@
+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/include/context_mgr.h b/include/context_mgr.h
new file mode 100644 (file)
index 0000000..13765f0
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_MANAGER_H__
+#define __CONTEXT_MANAGER_H__
+
+namespace ctx {
+       /* Forward Declaration */
+       class json;
+       class context_provider_iface;
+       class context_provider_info;
+
+       enum operation_type_e {
+               OPS_SUBSCRIBE   = 1,
+               OPS_READ                = 2,
+               OPS_WRITE               = 4,
+       };
+
+       namespace context_manager {
+               /*
+                */
+               bool register_provider(const char *subject, context_provider_info &provider_info);
+
+               /*
+                */
+               bool register_trigger_item(const char *subject, int operation, ctx::json attributes, ctx::json options);
+
+               /*
+                */
+               bool publish(const char *subject, ctx::json option, int error, ctx::json data_updated);
+
+               /*
+                */
+               bool reply_to_read(const char *subject, ctx::json option, int error, ctx::json data_read);
+
+       }       /* namespace ctx::context_manager */
+}      /* namespace ctx */
+
+#endif /* End of __CONTEXT_MANAGER_H__ */
diff --git a/include/context_mgr_iface.h b/include/context_mgr_iface.h
new file mode 100644 (file)
index 0000000..dd29568
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_MANAGER_INTERFACE_H__
+#define __CONTEXT_MANAGER_INTERFACE_H__
+
+namespace ctx {
+       /* Forward Declaration */
+       class json;
+       class context_provider_iface;
+       class context_provider_info;
+
+       class context_manager_iface {
+       public:
+               virtual ~context_manager_iface() {}
+               virtual bool register_provider(const char *subject, context_provider_info &provider_info) = 0;
+               virtual bool register_trigger_item(const char *subject, int operation, ctx::json attributes, ctx::json options) = 0;
+               virtual bool publish(const char *subject, ctx::json &option, int error, ctx::json &data_updated) = 0;
+               virtual bool reply_to_read(const char *subject, ctx::json &option, int error, ctx::json &data_read) = 0;
+       };      /* class context_manager_iface */
+
+       namespace context_manager {
+               void set_instance(context_manager_iface* mgr);
+       }       /* namespace ctx::context_manager */
+
+}      /* namespace ctx */
+
+#endif /* End of __CONTEXT_MANAGER_INTERFACE_H__ */
diff --git a/include/db_listener_iface.h b/include/db_listener_iface.h
new file mode 100644 (file)
index 0000000..625c9fb
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_DATABASE_LISTENER_INTERFACE_H__
+#define __CONTEXT_DATABASE_LISTENER_INTERFACE_H__
+
+#include <vector>
+
+namespace ctx {
+       /* 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 ctx::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 ctx::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 ctx::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 ctx */
+
+#endif /* End of __CONTEXT_DATABASE_LISTENER_INTERFACE_H__ */
diff --git a/include/db_mgr.h b/include/db_mgr.h
new file mode 100644 (file)
index 0000000..f2f54be
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_DB_MANAGER_H__
+#define __CONTEXT_DB_MANAGER_H__
+
+#include <cstddef>
+#include <sys/types.h>
+#include <vector>
+
+namespace ctx {
+       /* 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 ctx::db_manager */
+}      /* namespace ctx */
+
+#endif /* __CONTEXT_DB_MANAGER_H__ */
diff --git a/include/db_mgr_iface.h b/include/db_mgr_iface.h
new file mode 100644 (file)
index 0000000..18e0841
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_DB_MANAGER_INTERFACE_H__
+#define __CONTEXT_DB_MANAGER_INTERFACE_H__
+
+#include <sys/types.h>
+
+namespace ctx {
+       /* 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 ctx::db_manager */
+}      /* namespace ctx */
+
+#endif /* __CONTEXT_DB_MANAGER_INTERFACE_H__ */
diff --git a/include/dbus_listener_iface.h b/include/dbus_listener_iface.h
new file mode 100644 (file)
index 0000000..4f64006
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_DBUS_LISTENER_INTERFACE_H__
+#define __CONTEXT_DBUS_LISTENER_INTERFACE_H__
+
+#include <glib.h>
+
+namespace ctx {
+
+       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 ctx */
+
+#endif /* End of __CONTEXT_DBUS_LISTENER_INTERFACE_H__ */
diff --git a/include/dbus_server.h b/include/dbus_server.h
new file mode 100644 (file)
index 0000000..009d34e
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_DBUS_SERVER_H__
+#define __CONTEXT_DBUS_SERVER_H__
+
+#include <sys/types.h>
+
+namespace ctx {
+       /* 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 ctx::dbus_server */
+}      /* namespace ctx */
+
+#endif /* End of __CONTEXT_DBUS_SERVER_H__ */
diff --git a/include/dbus_server_iface.h b/include/dbus_server_iface.h
new file mode 100644 (file)
index 0000000..6f10940
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_DBUS_SERVER_INTERFACE_H__
+#define __CONTEXT_DBUS_SERVER_INTERFACE_H__
+
+#include <sys/types.h>
+
+namespace ctx {
+       /* 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 ctx::dbus_server */
+
+       namespace dbus_server {
+               void set_instance(dbus_server_iface* svr);
+       }
+
+}      /* namespace ctx */
+
+#endif /* End of __CONTEXT_DBUS_SERVER_INTERFACE_H__ */
+
diff --git a/include/event_driven.h b/include/event_driven.h
new file mode 100644 (file)
index 0000000..00225ce
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2015 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:
+               typedef struct thread_info_s* thread_info_t;
+               thread_info_t thread_info;
+
+               static gpointer thread_func_wrapper(gpointer data);
+               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 100644 (file)
index 0000000..5c35299
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_JSON_H__
+#define __CONTEXT_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
+
+namespace ctx {
+
+       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., ctx::json copy(original.str());
+                */
+               json(const json& j);
+
+               ~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., ctx::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 set(const char* path, const char* key, GVariant *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);
+               bool get(const char* path, const char* key, GVariant **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);
+       };
+
+}      /* namespace ctx */
+
+#endif // __CONTEXT_JSON_H__
+
diff --git a/include/provider_iface.h b/include/provider_iface.h
new file mode 100644 (file)
index 0000000..f5268b6
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_PROVIDER_INTERFACE_H__
+#define __CONTEXT_PROVIDER_INTERFACE_H__
+
+namespace ctx {
+
+       /* Forward Declaration */
+       class json;
+
+       class context_provider_iface {
+       public:
+               virtual ~context_provider_iface() {}
+               virtual int subscribe(const char *subject, ctx::json option, ctx::json *request_result);
+               virtual int unsubscribe(const char *subject, ctx::json option);
+               virtual int read(const char *subject, ctx::json option, ctx::json *request_result);
+               virtual int write(const char *subject, ctx::json data, ctx::json *request_result);
+
+       protected:
+               context_provider_iface() {}
+
+       };      /* class context_provider_iface */
+
+       class context_provider_info {
+               typedef context_provider_iface *(*creator_t)(void *data);
+               typedef void (*destroyer_t)(void *data);
+
+       public:
+               creator_t create;
+               destroyer_t destroy;
+               void *data;
+               const char *privilege;
+
+               context_provider_info();
+               context_provider_info(creator_t cr, destroyer_t des, void *dat = NULL, const char *priv = NULL);
+       };
+
+}      /* namespace ctx */
+
+#endif /* End of __CONTEXT_PROVIDER_INTERFACE_H__ */
diff --git a/include/request_handler.h b/include/request_handler.h
new file mode 100644 (file)
index 0000000..a2faffb
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_LIB_REQUEST_HANDLER_H__
+#define __CONTEXT_LIB_REQUEST_HANDLER_H__
+
+#include <json.h>
+
+namespace ctx { namespace request_handler {
+
+       /*
+        */
+       typedef void(* subject_response_cb)(const char* subject, int req_id, int error, ctx::json response);
+
+       /*
+        */
+       bool register_callback(const char* subject, subject_response_cb callback);
+
+       /*
+        */
+       int subscribe(const char* subject, ctx::json* option, int* req_id, ctx::json* request_result = NULL);
+
+       /*
+        */
+       int unsubscribe(const char* subject, int req_id);
+
+       /*
+        */
+       int read(const char* subject, ctx::json* option, int* req_id, ctx::json* request_result = NULL);
+
+       /*
+        */
+       int read_sync(const char* subject, ctx::json* option, int* req_id, ctx::json* data_read);
+
+       /*
+        */
+       int write(const char* subject, ctx::json* data);
+
+       /*
+        */
+       int write_with_reply(const char* subject, ctx::json* data, ctx::json* request_result = NULL);
+
+       /*
+        */
+       int is_supported(const char* subject);
+
+} }    /* namespace ctx::request_handler */
+
+#endif // __CONTEXT_LIB_REQUEST_HANDLER_H__
diff --git a/include/scope_mutex.h b/include/scope_mutex.h
new file mode 100644 (file)
index 0000000..17c8cf5
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_SCOPE_MUTEX_H__
+#define __CONTEXT_SCOPE_MUTEX_H__
+
+#include <glib.h>
+#include <types_internal.h>
+
+namespace ctx {
+       // 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 ctx */
+
+#endif // __CONTEXT_SCOPE_MUTEX_H__
diff --git a/include/shared_vars.h b/include/shared_vars.h
new file mode 100644 (file)
index 0000000..a5bb371
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_SHARED_VARS_H__
+#define __CONTEXT_SHARED_VARS_H__
+
+#include <string>
+
+namespace ctx {
+       namespace shared {
+               extern std::string wifi_bssid;
+       }
+}
+
+#endif
diff --git a/include/timer_listener_iface.h b/include/timer_listener_iface.h
new file mode 100644 (file)
index 0000000..df11a92
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_TIMER_LISTENER_INTERFACE_H__
+#define __CONTEXT_TIMER_LISTENER_INTERFACE_H__
+
+namespace ctx {
+
+       class timer_listener_iface {
+               public:
+                       virtual ~timer_listener_iface() {}
+
+                       /**
+                        * @brief               Called when a timer is expired.
+                        * @param[in]   timer_id        The expired timers' ID
+                        * @return              @c true, if the timer needs to be repeated.@n
+                        *                              @c false, if the timer does not need to be repeated anymore.
+                        */
+                       virtual bool on_timer_expired(int timer_id, void* user_data) = 0;
+       };
+
+}      /* namespace ctx */
+
+#endif /* End of __CONTEXT_TIMER_LISTENER_INTERFACE_H__ */
diff --git a/include/timer_mgr.h b/include/timer_mgr.h
new file mode 100644 (file)
index 0000000..732cfdf
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_TIMER_MANAGER_H__
+#define __CONTEXT_TIMER_MANAGER_H__
+
+namespace ctx {
+       /* Forward Declaration */
+       class timer_listener_iface;
+
+       namespace timer_manager {
+
+               enum day_of_week_e {
+                       SUN = 0x01,
+                       MON = 0x02,
+                       TUE = 0x04,
+                       WED = 0x08,
+                       THU = 0x10,
+                       FRI = 0x20,
+                       SAT = 0x40,
+                       WEEKDAY = MON | TUE | WED | THU | FRI,
+                       WEEKEND = SAT | SUN,
+                       EVERYDAY = SUN | MON | TUE | WED | THU | FRI | SAT,
+               };
+
+               /**
+                * @brief               Sets a repeated timer for a given interval of time (s).
+                * @details             It is recommended to minize the number of timers initiated, to reduce battery consumptions.
+                *                              If it is possible to share a timer for multiple purposes, please do that.
+                * @param[in]   interval        Timer interval. The first timer will be expired after @c interval minutes,
+                *                                                      and will be repeated until the listener returns @c false.
+                * @param[in]   listener        A listner object to be notified.
+                * @return              Timer ID. A negative integer if failed to set a timer.
+                */
+               int set_for(int interval, timer_listener_iface* listener, void* user_data = NULL);
+
+               /**
+                * @brief               Sets a timer that will be expired at a specific time, at designated days of week.
+                * @details             It is recommended to minize the number of timers initiated, to reduce battery consumptions.
+                *                              If it is possible to share a timer for multiple purposes, please do that.
+                * @param[in]   hour            Hour
+                * @param[in]   min                     Minute
+                * @param[in]   day_of_week     The timer will expire at hour:min:00, at every day(s) of week designated here.
+                * @param[in]   listener        Listener object.
+                * @return              Timer ID. A negative integer if failed to set a timer.
+                */
+               int set_at(int hour, int min, int day_of_week, timer_listener_iface* listener, void* user_data = NULL);
+
+               /**
+                * @brief               Removes the timer specified by @c timer_id.
+                */
+               void remove(int timer_id);
+       }
+}      /* namespace ctx */
+
+#endif /* __CONTEXT_TIMER_MANAGER_H__ */
diff --git a/include/timer_mgr_iface.h b/include/timer_mgr_iface.h
new file mode 100644 (file)
index 0000000..ac59921
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_TIMER_MANAGER_INTERFACE_H__
+#define __CONTEXT_TIMER_MANAGER_INTERFACE_H__
+
+namespace ctx {
+       /* Forward Declaration */
+       class timer_listener_iface;
+
+       class timer_manager_iface {
+               public:
+                       virtual ~timer_manager_iface() {}
+
+                       /**
+                        * @brief       Sets a timer notifying at every @c interval minutes.
+                        * @param[in]   interval        Repeating interval. Seconds.
+                        * @param[in]   listener        Listener object.
+                        * @return      A timer identifier that can be used to distinguish timers.
+                        *                      The same ID will be delivered whenever the timer is expired.
+                        */
+                       virtual int set_for(int interval, timer_listener_iface* listener, void* user_data) = 0;
+
+                       /**
+                        * @brief       Sets a timer notifying at specific time at every days of week designated.
+                        * @param[in]   hour            Hour
+                        * @param[in]   min                     Minute
+                        * @param[in]   day_of_week     The timer will expire at hour:min:00, at every day(s) of week designated here.
+                        * @param[in]   listener        Listener object.
+                        * @return      A timer identifier that can be used to distinguish timers.
+                        *                      The same ID will be delivered whenever the timer is expired.
+                        */
+                       virtual int set_at(int hour, int min, int day_of_week, timer_listener_iface* listener, void* user_data) = 0;
+
+                       virtual void remove(int timer_id) = 0;
+       };
+
+       namespace timer_manager {
+               void set_instance(timer_manager_iface* mgr);
+       }
+}      /* namespace ctx */
+
+#endif /* __CONTEXT_TIMER_MANAGER_INTERFACE_H__ */
diff --git a/include/types_internal.h b/include/types_internal.h
new file mode 100644 (file)
index 0000000..49f928c
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_TYPES_INTERNAL_H__
+#define __CONTEXT_TYPES_INTERNAL_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.
+ */
+#define ERR_NONE                               TIZEN_ERROR_NONE
+#define ERR_INVALID_PARAMETER  TIZEN_ERROR_INVALID_PARAMETER
+#define ERR_INVALID_OPERATION  TIZEN_ERROR_INVALID_OPERATION
+#define ERR_OUT_OF_MEMORY              TIZEN_ERROR_OUT_OF_MEMORY
+#define ERR_PERMISSION_DENIED  TIZEN_ERROR_PERMISSION_DENIED
+#define ERR_NOT_SUPPORTED              TIZEN_ERROR_NOT_SUPPORTED
+#define ERR_NO_DATA                            TIZEN_ERROR_NO_DATA
+#define ERR_ALREADY_STARTED            (TIZEN_ERROR_CONTEXT | 0x01)
+#define ERR_NOT_STARTED                        (TIZEN_ERROR_CONTEXT | 0x02)
+#define ERR_OUT_OF_RANGE               (TIZEN_ERROR_CONTEXT | 0x03)
+#define ERR_OPERATION_FAILED   (TIZEN_ERROR_CONTEXT | 0x04)
+#define ERR_RULE_ENABLED               (TIZEN_ERROR_CONTEXT | 0x05)
+#define ERR_RULE_NOT_ENABLED   (TIZEN_ERROR_CONTEXT | 0x06)
+#define ERR_INVALID_RULE               (TIZEN_ERROR_CONTEXT | 0x07)
+#define ERR_RULE_NOT_EXIST             (TIZEN_ERROR_CONTEXT | 0x08)
+
+/* 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[0;31m" X "\033[0m"
+#define GREEN(X)       "\033[0;32m" X "\033[0m"
+#define YELLOW(X)      "\033[0;33m" X "\033[0m"
+#define BLUE(X)                "\033[0;34m" X "\033[0m"
+#define PURPLE(X)      "\033[0;35m" X "\033[0m"
+#define CYAN(X)                "\033[0;36m" X "\033[0m"
+
+#define REPLACE_NULL(X) ((X) ? (X) : "")
+#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) != ERR_NONE)
+
+#define ASSERT_ALLOC(X)                IF_FAIL_RETURN_TAG(X, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed")
+#define ASSERT_NOT_NULL(X)     IF_FAIL_RETURN_TAG(X, ERR_INVALID_PARAMETER, _E, "Parameter null")
+
+#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.context"
+#define DBUS_PATH              "/org/tizen/context"
+#define DBUS_IFACE             "org.tizen.context"
+#define DBUS_TIMEOUT   3000000
+
+#define METHOD_REQUEST "Request"
+#define METHOD_RESPOND "Respond"
+#define SIGNAL_LAUNCHED        "Launched"
+
+enum request_type {
+       REQ_SUBSCRIBE = 1,
+       REQ_UNSUBSCRIBE,
+       REQ_READ,
+       REQ_READ_SYNC,
+       REQ_WRITE,
+       REQ_SUPPORT,
+};
+
+#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 /* __CONTEXT_TYPES_INTERNAL_H__ */
diff --git a/packaging/context-common.manifest b/packaging/context-common.manifest
new file mode 100644 (file)
index 0000000..a76fdba
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+       <request>
+               <domain name="_" />
+       </request>
+</manifest>
diff --git a/packaging/context-common.spec b/packaging/context-common.spec
new file mode 100644 (file)
index 0000000..48814fd
--- /dev/null
@@ -0,0 +1,72 @@
+Name:       context-common
+Summary:    Context-Service Shared Library
+Version:    0.6.2
+Release:    1
+Group:      System/Libraries
+License:    Apache-2.0
+Source0:    %{name}-%{version}.tar.gz
+
+BuildRequires: cmake
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(gio-2.0)
+BuildRequires: pkgconfig(json-glib-1.0)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(capi-base-common)
+BuildRequires: pkgconfig(security-server)
+
+%description
+Context-Service Shared Library
+
+%prep
+%setup -q
+
+%build
+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"
+
+export   CFLAGS+=" -DTIZEN_ENGINEER_MODE"
+export CXXFLAGS+=" -DTIZEN_ENGINEER_MODE"
+export   FFLAGS+=" -DTIZEN_ENGINEER_MODE"
+
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DMAJORVER=${MAJORVER} -DFULLVER=%{version}
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+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*
+/usr/share/license/%{name}
+
+%package devel
+Summary:    Context-Service Shared Library (Development)
+Group:      System/Libraries
+Requires:      %{name} = %{version}-%{release}
+
+%description devel
+Context-Service Shared Library (DEV)
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/context-service/internal/*.h
+%{_libdir}/pkgconfig/%{name}.pc
diff --git a/src/context_mgr.cpp b/src/context_mgr.cpp
new file mode 100644 (file)
index 0000000..1bf2b2d
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015 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 <provider_iface.h>
+#include <context_mgr.h>
+#include <context_mgr_iface.h>
+
+static ctx::context_manager_iface *_instance = NULL;
+
+void ctx::context_manager::set_instance(context_manager_iface* mgr)
+{
+       _instance = mgr;
+}
+
+bool ctx::context_manager::register_provider(const char* subject, ctx::context_provider_info &provider_info)
+{
+       IF_FAIL_RETURN_TAG(_instance, false, _E, "Not initialized");
+       return _instance->register_provider(subject, provider_info);
+}
+
+bool ctx::context_manager::register_trigger_item(const char *subject, int operation, ctx::json attributes, ctx::json options)
+{
+       IF_FAIL_RETURN_TAG(_instance, false, _E, "Not initialized");
+       return _instance->register_trigger_item(subject, operation, attributes, options);
+}
+
+bool ctx::context_manager::publish(const char* subject, ctx::json option, int error, ctx::json data_updated)
+{
+       IF_FAIL_RETURN_TAG(_instance, false, _E, "Not initialized");
+       return _instance->publish(subject, option, error, data_updated);
+}
+
+bool ctx::context_manager::reply_to_read(const char* subject, ctx::json option, int error, ctx::json data_read)
+{
+       IF_FAIL_RETURN_TAG(_instance, false, _E, "Not initialized");
+       return _instance->reply_to_read(subject, option, error, data_read);
+}
diff --git a/src/db_mgr.cpp b/src/db_mgr.cpp
new file mode 100644 (file)
index 0000000..12a0211
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2015 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 ctx::db_manager_iface *_instance = NULL;
+
+void ctx::db_manager::set_instance(ctx::db_manager_iface* mgr)
+{
+       _instance = mgr;
+}
+
+bool ctx::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 ctx::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 ctx::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 ctx::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 ctx::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 100644 (file)
index 0000000..c3c183c
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2015 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 <types_internal.h>
+#include <scope_mutex.h>
+#include "response_handler.h"
+#include "dbus_client.h"
+
+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 char *cookie = NULL;
+       static GMutex cookie_mutex;
+       ctx::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 cookie;
+}
+
+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);
+       _D("[Response] ReqId: %d, Subject: %s, Error: %d", req_id, subject, error);
+
+       ctx::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);
+       }
+}
+
+ctx::dbus_client::dbus_client()
+{
+}
+
+ctx::dbus_client::~dbus_client()
+{
+       release();
+}
+
+bool ctx::dbus_client::init()
+{
+       static GMutex connection_mutex;
+       ctx::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 ctx::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;
+       }
+}
+
+int ctx::dbus_client::request(
+               int type, int req_id, const char* subject, const char* input,
+               std::string* req_result, std::string* data_read)
+{
+       _D("Requesting: %d, %d, %s", type, req_id, subject);
+
+       if (subject == NULL) {
+               subject = EMPTY_STRING;
+       }
+
+       if (input == NULL) {
+               input = EMPTY_JSON_OBJECT;
+       }
+
+       const char *cookie = get_security_cookie();
+       IF_FAIL_RETURN_TAG(cookie, ERR_OPERATION_FAILED, _E, "Cookie generation failed");
+
+       GVariant *param = g_variant_new("(isiss)", type, cookie, req_id, subject, input);
+       IF_FAIL_RETURN_TAG(param, ERR_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, ERR_OPERATION_FAILED, _E, "Method call failed");
+
+       gint _error = ERR_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 ctx::dbus_client::request_with_no_reply(
+               int type, int req_id, const char* subject, const char* input)
+{
+       _D("Requesting: %d, %d, %s", type, req_id, subject);
+
+       if (subject == NULL) {
+               subject = EMPTY_STRING;
+       }
+
+       if (input == NULL) {
+               input = EMPTY_JSON_OBJECT;
+       }
+
+       const char *cookie = get_security_cookie();
+       IF_FAIL_RETURN_TAG(cookie, ERR_OPERATION_FAILED, _E, "Cookie generation failed");
+
+       GVariant *param = g_variant_new("(isiss)", type, cookie, req_id, subject, input);
+       IF_FAIL_RETURN_TAG(param, ERR_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 ERR_OPERATION_FAILED;
+       }
+
+       return ERR_NONE;
+}
diff --git a/src/dbus_client.h b/src/dbus_client.h
new file mode 100644 (file)
index 0000000..9707f3d
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_LIB_DBUS_HANDLER_H__
+#define __CONTEXT_LIB_DBUS_HANDLER_H__
+
+#include <string>
+
+namespace ctx {
+
+       class dbus_client {
+               public:
+                       dbus_client();
+                       ~dbus_client();
+
+                       bool init();
+                       void release();
+
+                       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 ctx::dbus_client */
+
+}      /* namespace ctx */
+
+#endif // __CONTEXT_LIB_DBUS_HANDLER_H__
diff --git a/src/dbus_server.cpp b/src/dbus_server.cpp
new file mode 100644 (file)
index 0000000..9f0b927
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015 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 <dbus_server.h>
+#include <dbus_server_iface.h>
+#include <dbus_listener_iface.h>
+
+static ctx::dbus_server_iface *_instance = NULL;
+
+void ctx::dbus_server::set_instance(dbus_server_iface* svr)
+{
+       _instance = svr;
+}
+
+int64_t ctx::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 ctx::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_driven.cpp b/src/event_driven.cpp
new file mode 100644 (file)
index 0000000..2a383d6
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2015 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_driven.h>
+
+struct thread_info_s {
+       GThread *thread;
+       gint is_running;
+       GAsyncQueue *event_queue;
+};
+
+struct event_message_s {
+       int type;
+       void* data;
+       bool is_stop_signal;
+       event_message_s() : type(-1), data(NULL), is_stop_signal(false) {}
+};
+
+event_driven_thread::event_driven_thread()
+{
+       thread_info = static_cast<thread_info_s*>(g_malloc(sizeof(thread_info_s)));
+
+       if (thread_info) {
+               thread_info->thread = NULL;
+               thread_info->is_running = 0;
+               thread_info->event_queue = NULL;
+       }
+}
+
+event_driven_thread::~event_driven_thread()
+{
+       stop();
+       g_free(thread_info);
+}
+
+bool event_driven_thread::start()
+{
+       IF_FAIL_RETURN_TAG(thread_info, false, _E, "Memory allocation failed");
+
+       if (!g_atomic_int_get(&(thread_info->is_running))) {
+
+#if 0
+               int stack_size = sysconf(_SC_PAGESIZE) * 4;
+               void *stack = NULL;
+               stack = g_malloc(stack_size);
+               IF_FAIL_RETURN_TAG(stack, false, _E, "Memory allocation failed");
+#endif
+
+               thread_info->event_queue = g_async_queue_new();
+               if (thread_info->event_queue == NULL) {
+                       _E("Memory allocation failed");
+                       return false;
+               }
+
+               g_atomic_int_set(&thread_info->is_running, 1);
+
+#if 0
+               thread_info->pid = clone(&thread_func_wrapper, (char*)stack + stack_size,
+                               SIGCHLD | CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SYSVSEM, this);
+
+               if (thread_info->pid < 0) {
+                       _E(RED("Thread creation failed"));
+                       g_atomic_int_set(&thread_info->is_running, 0);
+                       g_free(stack);
+                       g_async_queue_unref(thread_info->event_queue);
+                       return false;
+               }
+
+               _I(PURPLE("PID %d initiated"), thread_info->pid);
+#endif
+
+               thread_info->thread = g_thread_new(NULL, thread_func_wrapper, static_cast<gpointer>(this));
+
+               if (thread_info->thread == NULL) {
+                       _E(RED("Thread creation failed"));
+                       g_atomic_int_set(&thread_info->is_running, 0);
+                       g_async_queue_unref(thread_info->event_queue);
+                       return false;
+               }
+
+               _I(PURPLE("A thread initiated"));
+       }
+
+       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);
+
+#if 0
+               pid_t pid = waitpid(thread_info->pid, NULL, 0);
+               _I(PURPLE("PID %d terminated"), pid);
+               if (pid < 0) {
+                       _E(RED("Failed to join %d from %d"), thread_info->pid, getpid());
+               }
+#endif
+               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;
+       }
+
+       return false;
+}
+
+gpointer event_driven_thread::thread_func_wrapper(gpointer data)
+{
+       static_cast<event_driven_thread*>(data)->process_event_queue();
+       return NULL;
+}
+
+void event_driven_thread::process_event_queue()
+{
+#if 0
+       struct sigaction signal_action;
+       signal_action.sa_handler = child_signal_handler;
+       sigemptyset(&signal_action.sa_mask);
+
+       sigaction(SIGINT, &signal_action, NULL);
+       sigaction(SIGHUP, &signal_action, NULL);
+       sigaction(SIGTERM, &signal_action, NULL);
+       sigaction(SIGQUIT, &signal_action, NULL);
+#endif
+
+       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 100644 (file)
index 0000000..13fa761
--- /dev/null
@@ -0,0 +1,951 @@
+/*
+ * Copyright (c) 2015 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     '.'
+#define GVAR_VALUES    "values"
+#define GVAR_TYPES     "types"
+
+static double string_to_double(const char* in)
+{
+       IF_FAIL_RETURN_TAG(in, 0, _E, "Parameter NULL");
+
+       // 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();
+}
+
+ctx::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);
+}
+
+ctx::json::json(const json& j)
+{
+       json_node = json_node_copy(j.json_node);
+       IF_FAIL_VOID_TAG(json_node, _E, "Json object construction failed");
+}
+
+ctx::json::json(const char* s)
+{
+       if (s) {
+               parse(s);
+       } else {
+               parse(EMPTY_JSON_OBJECT);
+       }
+}
+
+ctx::json::json(const std::string& s)
+{
+       if (s.empty()) {
+               parse(EMPTY_JSON_OBJECT);
+       } else {
+               parse(s.c_str());
+       }
+}
+
+ctx::json::~json()
+{
+       release();
+}
+
+void ctx::json::parse(const char* s)
+{
+       gboolean result;
+       JsonParser *parser = NULL;
+       JsonNode *root = NULL;
+
+       parser = json_parser_new();
+       IF_FAIL_VOID_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");
+
+CATCH:
+       if (parser)
+               g_object_unref(parser);
+}
+
+void ctx::json::release()
+{
+       if (json_node) {
+               json_node_free(json_node);
+               json_node = NULL;
+       }
+}
+
+ctx::json& ctx::json::operator=(const json& j)
+{
+       release();
+       json_node = json_node_copy(j.json_node);
+       if (!json_node) {
+               _E("Json object copy failed");
+       }
+       return *this;
+}
+
+ctx::json& ctx::json::operator=(const char* s)
+{
+       release();
+       if (s) {
+               parse(s);
+       } else {
+               parse(EMPTY_JSON_OBJECT);
+       }
+       return *this;
+}
+
+ctx::json& ctx::json::operator=(const std::string& s)
+{
+       release();
+       if (s.empty()) {
+               parse(EMPTY_JSON_OBJECT);
+       } else {
+               parse(s.c_str());
+       }
+       return *this;
+}
+
+bool ctx::json::operator==(const json& rhs)
+{
+       return node_equals(json_node, rhs.json_node);
+}
+
+bool ctx::json::operator!=(const json& rhs)
+{
+       return !operator==(rhs);
+}
+
+/* TODO
+bool ctx::json::contains(const json& subset) const
+{
+       return false;
+}
+*/
+
+char* ctx::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 ctx::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 ctx::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 ctx::json::set(const char* path, const char* key, int val)
+{
+       return set(path, key, static_cast<int64_t>(val));
+}
+
+bool ctx::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 ctx::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 ctx::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 ctx::json::set(const char* path, const char* key, GVariant *val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+       const gchar *type_str = g_variant_get_type_string(val);
+       IF_FAIL_RETURN_TAG(type_str, false, _E, "GVariant manipulation failed");
+
+       json_node_t *node = json_gvariant_serialize(val);
+       IF_FAIL_RETURN_TAG(node, false, _E, "GVariant manipulation failed");
+
+       json gvar_json;
+       gvar_json.set(NULL, GVAR_TYPES, type_str);
+       json_object_set_member(json_node_get_object(gvar_json.json_node), GVAR_VALUES, node);
+
+       return set(path, key, gvar_json);
+}
+
+bool ctx::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 ctx::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 ctx::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 ctx::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 ctx::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);
+
+       const char *str_val = json_node_get_string(node);
+       IF_FAIL_RETURN_TAG(str_val, false, _E, "Getting string failed");
+
+       *val = str_val;
+       return true;
+}
+
+bool ctx::json::get(const char* path, const char* key, GVariant **val)
+{
+       IF_FAIL_RETURN_TAG(this->json_node, false, _E, "Json object not initialized");
+       IF_FAIL_RETURN_TAG(key && val, false, _E, "Invalid parameter");
+
+       bool ret;
+       json gvar_json;
+       ret = get(path, key, &gvar_json);
+       IF_FAIL_RETURN(ret, false);
+
+       std::string gvar_types;
+       ret = gvar_json.get(NULL, GVAR_TYPES, &gvar_types);
+       IF_FAIL_RETURN(ret, false);
+
+       json gvar_values;
+       ret = gvar_json.get(NULL, GVAR_VALUES, &gvar_values);
+       IF_FAIL_RETURN(ret, false);
+
+       GError *gerr = NULL;
+       *val = json_gvariant_deserialize(gvar_values.json_node, gvar_types.c_str(), &gerr);
+       HANDLE_GERROR(gerr);
+       IF_FAIL_RETURN(*val, false);
+
+       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, _W, "Type mismatched: %s", key);
+
+       return json_node_get_array(node);
+}
+
+int ctx::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, _D, "Mismatched data type");
+
+       return json_array_get_length(jarr);
+}
+
+bool ctx::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 ctx::json::array_append(const char* path, const char* key, int val)
+{
+       return array_append(path, key, static_cast<int64_t>(val));
+}
+
+bool ctx::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 ctx::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 ctx::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 ctx::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 ctx::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 ctx::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 ctx::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 ctx::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 ctx::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 ctx::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 ctx::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 ctx::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 ctx::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);
+
+       const char *str_val = json_node_get_string(node);
+       IF_FAIL_RETURN_TAG(str_val, false, _E, "Getting string failed");
+
+       *val = str_val;
+       return true;
+}
+
+bool ctx::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 ctx::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 ctx::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 ctx::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 ctx::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 ctx::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/provider_iface.cpp b/src/provider_iface.cpp
new file mode 100644 (file)
index 0000000..1e06ce2
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015 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 <provider_iface.h>
+
+int ctx::context_provider_iface::subscribe(const char *subject, ctx::json option, ctx::json *request_result)
+{
+       return ERR_NOT_SUPPORTED;
+}
+
+int ctx::context_provider_iface::unsubscribe(const char *subject, ctx::json option)
+{
+       return ERR_NOT_SUPPORTED;
+}
+
+int ctx::context_provider_iface::read(const char *subject, ctx::json option, ctx::json *request_result)
+{
+       return ERR_NOT_SUPPORTED;
+}
+
+int ctx::context_provider_iface::write(const char *subject, ctx::json data, ctx::json *request_result)
+{
+       return ERR_NOT_SUPPORTED;
+}
+
+ctx::context_provider_info::context_provider_info()
+       : create(NULL)
+       , destroy(NULL)
+       , data(NULL)
+       , privilege(NULL)
+{
+}
+
+ctx::context_provider_info::context_provider_info(
+               ctx::context_provider_info::creator_t cr,
+               ctx::context_provider_info::destroyer_t des, void *dat, const char *priv)
+       : create(cr)
+       , destroy(des)
+       , data(dat)
+       , privilege(priv)
+{
+}
diff --git a/src/request_handler.cpp b/src/request_handler.cpp
new file mode 100644 (file)
index 0000000..8cd061b
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2015 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 <types_internal.h>
+#include <scope_mutex.h>
+#include <request_handler.h>
+#include "response_handler.h"
+#include "dbus_client.h"
+
+typedef std::map<std::string, ctx::request_handler::subject_response_cb> response_cb_map_t;
+
+static ctx::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; }
+       };
+}      /* namespace ctx */
+
+static exit_handler _exit_handler;
+
+static int generate_req_id()
+{
+       static GMutex rid_mutex;
+       static int req_id = 0;
+
+       ctx::scope_mutex sm(&rid_mutex);
+
+       // Overflow handling
+       if (++req_id < 0) {
+               req_id = 1;
+       }
+
+       return req_id;
+}
+
+static bool initialize()
+{
+       static GMutex init_mutex;
+       ctx::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) ctx::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 ctx::request_handler::subscribe(const char* subject, ctx::json* option, int* req_id, ctx::json* request_result)
+{
+       ASSERT_NOT_NULL(subject);
+       ASSERT_NOT_NULL(req_id);
+       IF_FAIL_RETURN_TAG(initialize(), ERR_OPERATION_FAILED, _E, "Connection failed");
+
+       *req_id = generate_req_id();
+
+       char *opt_str = NULL;
+       if (option) {
+               opt_str = option->dup_cstr();
+               IF_FAIL_RETURN_TAG(opt_str, ERR_OPERATION_FAILED, _E, "Json string creation failed");
+       }
+
+       _I("[Subscribe] ReqId: %d, Subject: %s", *req_id, subject);
+
+       std::string result_str;
+       int error = dbus_handle->request(REQ_SUBSCRIBE, *req_id, subject, opt_str, &result_str, NULL);
+       g_free(opt_str);
+
+       if (request_result) {
+               *request_result = result_str;
+       }
+
+       _D("Error: %#x", error);
+       _SD("Result: %s", result_str.c_str());
+
+       return error;
+}
+
+int ctx::request_handler::unsubscribe(const char* subject, int req_id)
+{
+       ASSERT_NOT_NULL(subject);
+       IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
+       _I("[Unsubscribe] ReqId: %d, Subject: %s", req_id, subject);
+       return dbus_handle->request(REQ_UNSUBSCRIBE, req_id, subject, NULL, NULL, NULL);
+}
+
+int ctx::request_handler::read(const char* subject, ctx::json* option, int* req_id, ctx::json* request_result)
+{
+       ASSERT_NOT_NULL(subject);
+       ASSERT_NOT_NULL(req_id);
+       IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
+
+       *req_id = generate_req_id();
+
+       char *opt_str = NULL;
+       if (option) {
+               opt_str = option->dup_cstr();
+               IF_FAIL_RETURN_TAG(opt_str, ERR_OPERATION_FAILED, _E, "Json string creation failed");
+       }
+
+       _I("[Read] ReqId: %d, Subject: %s", *req_id, subject);
+
+       std::string result_str;
+       int error = dbus_handle->request(REQ_READ, *req_id, subject, opt_str, &result_str, NULL);
+       g_free(opt_str);
+
+       if (request_result) {
+               *request_result = result_str;
+       }
+
+       _D("Error: %#x", error);
+       _SD("Result: %s", result_str.c_str());
+
+       return error;
+}
+
+int ctx::request_handler::read_sync(const char* subject, ctx::json* option, int* req_id, ctx::json* data_read)
+{
+       ASSERT_NOT_NULL(subject);
+       ASSERT_NOT_NULL(req_id);
+       ASSERT_NOT_NULL(data_read);
+       IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
+
+       *req_id = generate_req_id();
+
+       char *opt_str = NULL;
+       if (option) {
+               opt_str = option->dup_cstr();
+               IF_FAIL_RETURN_TAG(opt_str, ERR_OPERATION_FAILED, _E, "Json string creation failed");
+       }
+
+       _I("[ReadSync] ReqId: %d, Subject: %s", *req_id, subject);
+
+       std::string data_str;
+       int error = dbus_handle->request(REQ_READ_SYNC, *req_id, subject, opt_str, NULL, &data_str);
+       g_free(opt_str);
+
+       *data_read = data_str;
+
+       _D("Error: %#x", error);
+       _SD("Data: %s", data_str.c_str());
+
+       return error;
+}
+
+int ctx::request_handler::write(const char* subject, ctx::json* data)
+{
+       ASSERT_NOT_NULL(subject);
+       ASSERT_NOT_NULL(data);
+       IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
+
+       int req_id = generate_req_id();
+       char *data_str = data->dup_cstr();
+       IF_FAIL_RETURN_TAG(data_str, ERR_OPERATION_FAILED, _E, "Json string creation failed");
+
+       _I("[Write] ReqId: %d, Subject: %s", req_id, subject);
+       _SD("Data: %s", data_str);
+
+       int error = dbus_handle->request_with_no_reply(REQ_WRITE, req_id, subject, data_str);
+       g_free(data_str);
+
+       _D("Error: %#x", error);
+
+       return error;
+}
+
+int ctx::request_handler::write_with_reply(const char* subject, ctx::json* data, ctx::json* request_result)
+{
+       ASSERT_NOT_NULL(subject);
+       ASSERT_NOT_NULL(data);
+       IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
+
+       int req_id = generate_req_id();
+       char *data_str = data->dup_cstr();
+       IF_FAIL_RETURN_TAG(data_str, ERR_OPERATION_FAILED, _E, "Json string creation failed");
+
+       _I("[Write with reply] ReqId: %d, Subject: %s", req_id, subject);
+       _SD("Data: %s", data_str);
+
+       std::string result_str;
+       int error = dbus_handle->request(REQ_WRITE, req_id, subject, data_str, &result_str, NULL);
+       g_free(data_str);
+
+       if (request_result) {
+               *request_result = result_str;
+       }
+
+       _D("Error: %#x", error);
+       _SD("Result: %s", result_str.c_str());
+
+       return error;
+}
+
+int ctx::request_handler::is_supported(const char* subject)
+{
+       ASSERT_NOT_NULL(subject);
+       IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
+       return dbus_handle->request(REQ_SUPPORT, generate_req_id(), subject, NULL, NULL, NULL);
+}
+
+bool ctx::request_handler::register_callback(const char* subject, subject_response_cb callback)
+{
+       IF_FAIL_RETURN_TAG(subject && callback, false, _E, "Invalid parameter");
+       IF_FAIL_RETURN_TAG(initialize(), false, _E, "Connection failed");
+
+       _D("Registering callback for subject '%s'", subject);
+
+       static GMutex cb_list_mutex;
+       ctx::scope_mutex sm(&cb_list_mutex);
+
+       (*response_cb_map)[subject] = callback;
+
+       return true;
+}
+
+void ctx::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/response_handler.h b/src/response_handler.h
new file mode 100644 (file)
index 0000000..e512e48
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015 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 __CONTEXT_LIB_RESPONSE_HANDLER_H__
+#define __CONTEXT_LIB_RESPONSE_HANDLER_H__
+
+#include <json.h>
+
+namespace ctx { namespace response_handler {
+
+       void deliver(const char* subject, int req_id, int error, const char* data);
+
+} }    /* namespace ctx::response_handler */
+
+#endif // __CONTEXT_LIB_RESPONSE_HANDLER_H__
diff --git a/src/scope_mutex.cpp b/src/scope_mutex.cpp
new file mode 100644 (file)
index 0000000..d2bf245
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2015 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>
+
+ctx::scope_mutex::scope_mutex(GMutex *m) : mutex(m)
+{
+       g_mutex_lock(mutex);
+}
+
+ctx::scope_mutex::~scope_mutex()
+{
+       g_mutex_unlock(mutex);
+}
diff --git a/src/shared_vars.cpp b/src/shared_vars.cpp
new file mode 100644 (file)
index 0000000..7679e41
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2015 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 <shared_vars.h>
+
+std::string ctx::shared::wifi_bssid = "";
diff --git a/src/timer_mgr.cpp b/src/timer_mgr.cpp
new file mode 100644 (file)
index 0000000..cfb0f15
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015 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 <timer_listener_iface.h>
+#include <timer_mgr.h>
+#include <timer_mgr_iface.h>
+
+static ctx::timer_manager_iface *_instance = NULL;
+
+void ctx::timer_manager::set_instance(ctx::timer_manager_iface* mgr)
+{
+       _instance = mgr;
+}
+
+int ctx::timer_manager::set_for(int interval, timer_listener_iface* listener, void* user_data)
+{
+       IF_FAIL_RETURN_TAG(_instance, false, _E, "Not initialized");
+       return _instance->set_for(interval, listener, user_data);
+}
+
+int ctx::timer_manager::set_at(int hour, int min, int day_of_week, timer_listener_iface* listener, void* user_data)
+{
+       IF_FAIL_RETURN_TAG(_instance, false, _E, "Not initialized");
+       return _instance->set_at(hour, min, day_of_week, listener, user_data);
+}
+
+void ctx::timer_manager::remove(int timer_id)
+{
+       IF_FAIL_VOID_TAG(_instance, _E, "Not initialized");
+       _instance->remove(timer_id);
+}