Migrate from 2.4 code repo
[platform/core/context/context-service.git] / src / context_trigger / clips_handler.cpp
1 /*
2  * context-service
3  *
4  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <types_internal.h>
21 #include <json.h>
22 #include <string>
23 #include <sstream>
24 #include <cstdlib>
25 #include "clips_handler.h"
26 #include "rule_manager.h"
27
28 extern "C"
29 {
30 #include <clips/clips.h>
31 }
32
33 static void* env = NULL;
34 static ctx::rule_manager* rule_mgr = NULL;
35 static int string_to_int(std::string str);
36
37 ctx::clips_handler::clips_handler()
38 {
39 }
40
41 ctx::clips_handler::~clips_handler()
42 {
43         if (env) {
44                 DestroyEnvironment(env);
45         }
46 }
47
48 bool ctx::clips_handler::init(ctx::rule_manager* rm)
49 {
50         rule_mgr = rm;
51
52         int error = init_environment(env);
53         IF_FAIL_RETURN(error == ERR_NONE, false);
54
55         bool ret = define_global_variable_string("zone", "");
56         IF_FAIL_RETURN(ret, false);
57
58         return true;
59 }
60
61 int ctx::clips_handler::init_environment(void* &environment)
62 {
63         environment = CreateEnvironment();
64         if (!environment) {
65                 _E("Create environment failed");
66                 return ERR_OPERATION_FAILED;
67         }
68
69         char* func_name = strdup("execute_action");
70         char* restrictions = strdup("1s");
71
72         if (func_name == NULL || restrictions == NULL) {
73                 _E("Memory allocation failed");
74                 free(func_name);
75                 free(restrictions);
76                 return ERR_OUT_OF_MEMORY;
77         }
78
79         EnvDefineFunction2(environment, func_name, 'i', PTIEF execute_action, func_name, restrictions);
80
81         free(func_name);
82         free(restrictions);
83
84         return ERR_NONE;
85 }
86
87 int ctx::clips_handler::define_template(std::string& script)
88 {
89         IF_FAIL_RETURN_TAG(env_build(script) == ERR_NONE, ERR_OPERATION_FAILED, _E, "Deftemplate failed");
90         return ERR_NONE;
91 }
92
93 int ctx::clips_handler::define_class(std::string& script)
94 {
95         IF_FAIL_RETURN_TAG(env_build(script) == ERR_NONE, ERR_OPERATION_FAILED, _E, "Defclass failed");
96         return ERR_NONE;
97 }
98
99 int ctx::clips_handler::define_rule(std::string& script)
100 {
101         IF_FAIL_RETURN_TAG(env_build(script) == ERR_NONE, ERR_OPERATION_FAILED, _E, "Defrule failed");
102         return ERR_NONE;
103 }
104
105 int ctx::clips_handler::env_build(std::string& script)
106 {
107         ASSERT_NOT_NULL(env);
108         if (script.length() == 0)
109                 return ERR_INVALID_PARAMETER;
110
111         _I("EnvBuild script (%s)", script.c_str());
112         int ret = EnvBuild(env, script.c_str());
113
114         return (ret == 1)? ERR_NONE : ERR_OPERATION_FAILED;
115 }
116
117 int ctx::clips_handler::run_environment()
118 {
119         ASSERT_NOT_NULL(env);
120
121         int fired_rule_num = EnvRun(env, -1);
122         IF_FAIL_RETURN(fired_rule_num >= 0, ERR_OPERATION_FAILED);
123
124         return ERR_NONE;
125 }
126
127 int ctx::clips_handler::add_fact(std::string& fact)
128 {
129         ASSERT_NOT_NULL(env);
130         if (fact.length() == 0)
131                 return ERR_INVALID_PARAMETER;
132
133         void* assert_fact = EnvAssertString(env, fact.c_str());
134         IF_FAIL_RETURN_TAG(assert_fact, ERR_OPERATION_FAILED, _E, "Fact assertion failed");
135
136         return ERR_NONE;
137 }
138
139 int ctx::clips_handler::route_string_command(std::string& script)
140 {
141         ASSERT_NOT_NULL(env);
142         if (script.length() == 0)
143                 return ERR_INVALID_PARAMETER;
144
145         int error;
146         if (RouteCommand(env, script.c_str(), TRUE)){
147                 _D("Route command succeeded(%s).", script.c_str());
148                 error = ERR_NONE;
149         } else {
150                 _E("Route command failed");
151                 error = ERR_OPERATION_FAILED;
152         }
153
154         return error;
155 }
156
157 int ctx::clips_handler::make_instance(std::string& script)
158 {
159         ASSERT_NOT_NULL(env);
160         if (script.length() == 0)
161                 return ERR_INVALID_PARAMETER;
162
163         int error;
164         if (EnvMakeInstance(env, script.c_str())){
165                 _D("Make instance succeeded - %s", script.c_str());
166                 error = ERR_NONE;
167         } else {
168                 _E("Make instance failed");
169                 error = ERR_OPERATION_FAILED;
170         }
171
172         return error;
173 }
174
175 int ctx::clips_handler::unmake_instance(std::string& instance_name)
176 {
177         ASSERT_NOT_NULL(env);
178         if (instance_name.length() == 0)
179                 return ERR_INVALID_PARAMETER;
180
181         void* instance = find_instance_internal(instance_name);
182         if (!instance) {
183                 _E("Cannot find instance(%s).", instance_name.c_str());
184                 return ERR_INVALID_PARAMETER;
185         }
186
187         if (!EnvUnmakeInstance(env, instance)){
188                 _E("Unmake instance failed");
189                 return ERR_OPERATION_FAILED;
190         }
191
192         _D("Unmake instance succeeded(%s).", instance_name.c_str());
193         return ERR_NONE;
194 }
195
196 int ctx::clips_handler::execute_action()
197 {
198         if (!env) {
199                 _E("Environment not created");
200                 return ERR_OPERATION_FAILED;
201         }
202
203         const char* result = EnvRtnLexeme(env, 1);
204         if (!result) {
205                 _E("Failed to get returned rule id");
206                 return ERR_OPERATION_FAILED;
207         }
208         std::string rule_id = result;
209         std::string id_str = rule_id.substr(4);
210
211         int id = string_to_int(id_str);
212         rule_mgr->on_rule_triggered(id);
213
214         return ERR_NONE;
215 }
216
217 bool ctx::clips_handler::find_instance(std::string& instance_name)
218 {
219         ASSERT_NOT_NULL(env);
220         if (find_instance_internal(instance_name)) {
221                 _D("[%s] already exists", instance_name.c_str());
222                 return true;
223         }
224
225         return false;
226 }
227
228 void* ctx::clips_handler::find_instance_internal(std::string& instance_name)
229 {
230         void* instance = EnvFindInstance(env, NULL, instance_name.c_str(), TRUE);
231         return instance;
232 }
233
234 int string_to_int(std::string str)
235 {
236         int i;
237         std::istringstream convert(str);
238
239         if (!(convert >> i))
240                 i = 0;
241
242         return i;
243 }
244
245 bool ctx::clips_handler::define_global_variable_string(std::string variable_name, std::string value)
246 {
247         std::string script = "(defglobal ?*";
248         script += variable_name;
249         script += "* = \"";
250         script += value;
251         script += "\")";
252
253         IF_FAIL_RETURN_TAG(env_build(script) == ERR_NONE, false, _E, "Defglobal failed");
254         return true;
255 }
256
257 bool ctx::clips_handler::set_global_variable_string(std::string variable_name, std::string value)
258 {
259         ASSERT_NOT_NULL(env);
260         if (variable_name.length() == 0)
261                 return false;
262
263         DATA_OBJECT data;
264         SetType(data, STRING);
265         SetValue(data, EnvAddSymbol(env, value.c_str())) ;
266
267         int ret = EnvSetDefglobalValue(env, variable_name.c_str(), &data);
268
269         IF_FAIL_RETURN_TAG(ret == 1, false, _E, "Set global variable(%s) failed", variable_name.c_str());
270         return true;
271 }