Added custom provider 49/57549/8
authorSomin Kim <somin926.kim@samsung.com>
Thu, 21 Jan 2016 04:58:06 +0000 (13:58 +0900)
committerSomin Kim <somin926.kim@samsung.com>
Wed, 17 Feb 2016 01:57:35 +0000 (10:57 +0900)
Change-Id: I4fee414b0d952b02e0256bf71f6e4a7c05593167
Signed-off-by: Somin Kim <somin926.kim@samsung.com>
include/custom_context_provider.h [new file with mode: 0644]
src/CMakeLists.txt
src/custom/CMakeLists.txt [new file with mode: 0644]
src/custom/custom_base.cpp [new file with mode: 0644]
src/custom/custom_base.h [new file with mode: 0644]
src/custom/custom_context_provider.cpp [new file with mode: 0644]

diff --git a/include/custom_context_provider.h b/include/custom_context_provider.h
new file mode 100644 (file)
index 0000000..584cf3b
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016 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_CUSTOM_CONTEXT_PROVIDER_H__
+#define __CONTEXT_CUSTOM_CONTEXT_PROVIDER_H__
+
+namespace ctx {
+       bool init_custom_context_provider();
+
+       namespace custom_context_provider {
+       int add_item(std::string subject, std::string name, ctx::json tmpl, const char* owner);
+       int remove_item(std::string subject);
+       int publish_data(std::string subject, ctx::json fact);
+
+       context_provider_iface* create(void* data);
+       void destroy(void* data);
+       }
+}
+
+#endif //__CONTEXT_CUSTOM_CONTEXT_PROVIDER_H__
index ed81952..737a746 100644 (file)
@@ -11,6 +11,7 @@ ENDFUNCTION(add_provider)
 add_provider(device)
 add_provider(statistics)
 add_provider(place)
+add_provider(custom)
 
 SEPARATE_ARGUMENTS(deps_list)
 LIST(REMOVE_DUPLICATES deps_list)
diff --git a/src/custom/CMakeLists.txt b/src/custom/CMakeLists.txt
new file mode 100644 (file)
index 0000000..881c3a4
--- /dev/null
@@ -0,0 +1,25 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+SET(target "ctx-custom")
+
+# Common Profile
+FILE(GLOB srcs ./*.cpp)
+
+MESSAGE("Custom Provider Sources: ${srcs}")
+
+# Build
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(custom_pkgs REQUIRED ${deps_common})
+
+FOREACH(flag ${custom_pkgs_CFLAGS})
+       SET(extra_cflags "${extra_cflags} ${flag}")
+ENDFOREACH(flag)
+
+ADD_LIBRARY(${target} SHARED ${srcs})
+TARGET_LINK_LIBRARIES(${target} ${custom_pkgs_LDFLAGS})
+SET_TARGET_PROPERTIES(${target} PROPERTIES COMPILE_FLAGS ${extra_cflags})
+SET_TARGET_PROPERTIES(${target} PROPERTIES COMPILE_DEFINITIONS "LOG_TAG=\"CONTEXT-CUSTOM\"")
+SET_TARGET_PROPERTIES(${target} PROPERTIES SOVERSION ${MAJORVER})
+SET_TARGET_PROPERTIES(${target} PROPERTIES VERSION ${FULLVER})
+
+# Install
+INSTALL(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT RuntimeLibraries)
diff --git a/src/custom/custom_base.cpp b/src/custom/custom_base.cpp
new file mode 100644 (file)
index 0000000..59cbec9
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2016 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 <context_mgr.h>
+#include "custom_base.h"
+
+ctx::custom_base::custom_base(std::string subject, std::string name, ctx::json tmpl, std::string owner) :
+       _subject(subject),
+       _name(name),
+       _tmpl(tmpl),
+       _owner(owner)
+{
+}
+
+ctx::custom_base::~custom_base()
+{
+}
+
+bool ctx::custom_base::is_supported()
+{
+       return true;
+}
+
+void ctx::custom_base::submit_trigger_item()
+{
+       context_manager::register_trigger_item(_subject.c_str(), OPS_SUBSCRIBE | OPS_READ,
+                       _tmpl.str(), NULL, _owner.c_str());
+}
+
+void ctx::custom_base::unsubmit_trigger_item()
+{
+       context_manager::unregister_trigger_item(_subject.c_str());
+}
+
+int ctx::custom_base::subscribe(const char *subject, ctx::json option, ctx::json *request_result)
+{
+       return ERR_NONE;
+
+}
+
+int ctx::custom_base::unsubscribe(const char *subject, ctx::json option)
+{
+       return ERR_NONE;
+}
+
+int ctx::custom_base::read(const char *subject, ctx::json option, ctx::json *request_result)
+{
+       ctx::json data = latest.str();
+       ctx::context_manager::reply_to_read(_subject.c_str(), NULL, ERR_NONE, data);
+       return ERR_NONE;
+}
+
+int ctx::custom_base::write(const char *subject, ctx::json data, ctx::json *request_result)
+{
+       return ERR_NONE;
+}
+
+void ctx::custom_base::handle_update(ctx::json data)
+{
+       // Store latest state
+       latest = data.str();
+       ctx::context_manager::publish(_subject.c_str(), NULL, ERR_NONE, data);
+}
+
+const char* ctx::custom_base::get_subject()
+{
+       return _subject.c_str();
+}
+
+std::string ctx::custom_base::get_owner()
+{
+       return _owner;
+}
+
+ctx::json ctx::custom_base::get_template()
+{
+       return _tmpl;
+}
diff --git a/src/custom/custom_base.h b/src/custom/custom_base.h
new file mode 100644 (file)
index 0000000..e2e8bce
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 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 _CUSTOM_BASE_H_
+#define _CUSTOM_BASE_H_
+
+#include <json.h>
+#include <provider_iface.h>
+#include <types_internal.h>
+
+namespace ctx {
+
+       class custom_base : public context_provider_iface {
+       public:
+               custom_base(std::string subject, std::string name, ctx::json tmpl, std::string owner);
+               ~custom_base();
+
+               int subscribe(const char *subject, ctx::json option, ctx::json *request_result);
+               int unsubscribe(const char *subject, ctx::json option);
+               int read(const char *subject, ctx::json option, ctx::json *request_result);
+               int write(const char *subject, ctx::json data, ctx::json *request_result);
+
+               static bool is_supported();
+               void submit_trigger_item();
+               void unsubmit_trigger_item();
+
+               void handle_update(ctx::json data);
+
+               const char* get_subject();
+               std::string get_owner();
+               ctx::json get_template();
+
+       private:
+               std::string _subject;
+               std::string _name;
+               ctx::json _tmpl;
+               std::string _owner;
+               ctx::json latest;
+       };
+}
+
+#endif // _CUSTOM_BASE_H_
diff --git a/src/custom/custom_context_provider.cpp b/src/custom/custom_context_provider.cpp
new file mode 100644 (file)
index 0000000..923fa1a
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2016 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 <map>
+#include <types_internal.h>
+#include <context_mgr.h>
+#include <provider_iface.h>
+#include <custom_context_provider.h>
+#include "custom_base.h"
+
+std::map<std::string, ctx::custom_base*> custom_map;
+
+static bool is_valid_fact(std::string subject, ctx::json& fact);
+static bool check_value_int(ctx::json& tmpl, std::string key, int value);
+static bool check_value_string(ctx::json& tmpl, std::string key, std::string value);
+
+void register_provider(const char *subject, const char *privilege)
+{
+       ctx::context_provider_info provider_info(ctx::custom_context_provider::create,
+                                                                                       ctx::custom_context_provider::destroy,
+                                                                                       const_cast<char*>(subject), privilege);
+       ctx::context_manager::register_provider(subject, provider_info);
+       custom_map[subject]->submit_trigger_item();
+}
+
+void unregister_provider(const char* subject)
+{
+       custom_map[subject]->unsubmit_trigger_item();
+       ctx::context_manager::unregister_provider(subject);
+}
+
+EXTAPI ctx::context_provider_iface* ctx::custom_context_provider::create(void *data)
+{
+       // Already created in add_item() function. Return corresponding custom provider
+       return custom_map[static_cast<const char*>(data)];
+}
+
+EXTAPI void ctx::custom_context_provider::destroy(void *data)
+{
+       std::map<std::string, ctx::custom_base*>::iterator it = custom_map.find(static_cast<char*>(data));
+       if (it != custom_map.end()) {
+               delete it->second;
+               custom_map.erase(it);
+       }
+}
+
+EXTAPI bool ctx::init_custom_context_provider()
+{
+       return true;
+}
+
+EXTAPI int ctx::custom_context_provider::add_item(std::string subject, std::string name, ctx::json tmpl, const char* owner)
+{
+       std::map<std::string, ctx::custom_base*>::iterator it;
+       it = custom_map.find(subject);
+
+       if (it != custom_map.end()) {
+               if ((it->second)->get_template() != tmpl) {     // Same item name, but different template
+                       return ERR_DATA_EXIST;
+               }
+               // Same item name with same template
+               return ERR_NONE;
+       }
+
+       // Create custom base
+       ctx::custom_base* custom = new(std::nothrow) custom_base(subject, name, tmpl, owner);
+       IF_FAIL_RETURN_TAG(custom, ERR_OUT_OF_MEMORY, _E, "Memory allocation failed");
+       custom_map[subject] = custom;
+
+       register_provider(custom->get_subject(), NULL);
+
+       return ERR_NONE;
+}
+
+EXTAPI int ctx::custom_context_provider::remove_item(std::string subject)
+{
+       std::map<std::string, ctx::custom_base*>::iterator it;
+       it = custom_map.find(subject);
+       IF_FAIL_RETURN_TAG(it != custom_map.end(), ERR_NOT_SUPPORTED, _E, "%s not supported", subject.c_str());
+
+       unregister_provider(subject.c_str());
+
+       return ERR_NONE;
+}
+
+EXTAPI int ctx::custom_context_provider::publish_data(std::string subject, ctx::json fact)
+{
+       std::map<std::string, ctx::custom_base*>::iterator it;
+       it = custom_map.find(subject);
+       IF_FAIL_RETURN_TAG(it != custom_map.end(), ERR_NOT_SUPPORTED, _E, "%s not supported", subject.c_str());
+
+       bool ret = is_valid_fact(subject, fact);
+       IF_FAIL_RETURN_TAG(ret, ERR_INVALID_DATA, _E, "Invalid fact(%s)", subject.c_str());
+
+       custom_map[subject]->handle_update(fact);
+       return ERR_NONE;
+}
+
+bool is_valid_fact(std::string subject, ctx::json& fact)
+{
+       ctx::json tmpl = custom_map[subject]->get_template();
+       IF_FAIL_RETURN_TAG(tmpl != EMPTY_JSON_OBJECT, false, _E, "Failed to get template");
+
+       bool ret;
+       std::list<std::string> keys;
+       fact.get_keys(&keys);
+
+       for (std::list<std::string>::iterator it = keys.begin(); it != keys.end(); it++) {
+               std::string key = *it;
+
+               std::string type;
+               tmpl.get(key.c_str(), "type", &type);
+               if (type == "integer") {
+                       int val;
+                       ret = fact.get(NULL, key.c_str(), &val);
+                       IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid data type");
+
+                       ret = check_value_int(tmpl, key, val);
+                       IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid value");
+               } else if (type == "string") {
+                       std::string val_str;
+                       ret = fact.get(NULL, key.c_str(), &val_str);
+                       IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid data type");
+
+                       ret = check_value_string(tmpl, key, val_str);
+                       IF_FAIL_RETURN_TAG(ret, false, _E, "Custom fact: invalid value");
+               } else {
+                       _E("Custom fact: invalid data type");
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+bool check_value_int(ctx::json& tmpl, std::string key, int value)
+{
+       int min, max;
+
+       if (tmpl.get(key.c_str(), "min", &min)) {
+               IF_FAIL_RETURN(value >= min, false);
+       }
+
+       if (tmpl.get(key.c_str(), "max", &max)) {
+               IF_FAIL_RETURN(value <= max, false);
+       }
+
+       return true;
+}
+
+bool check_value_string(ctx::json& tmpl, std::string key, std::string value)
+{
+       // case1: any value is accepted
+       if (tmpl.array_get_size(key.c_str(), "values") <= 0)
+               return true;
+
+       // case2: check acceptable value
+       std::string t_val;
+       for (int i = 0; tmpl.get_array_elem(key.c_str(), "values", i, &t_val); i++) {
+               if (t_val == value)
+                       return true;
+       }
+
+       return false;
+}
+
+