Merge "Adding AK8975 geo-sensor info in sensors.xml.in required by geo-plugin" into...
[platform/core/system/sensord.git] / src / shared / sensor_plugin_loader.cpp
1 /*
2  * libsensord-share
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 <sensor_plugin_loader.h>
21 #include <libxml/xmlmemory.h>
22 #include <libxml/parser.h>
23 #include <sensor_hal.h>
24 #include <sensor_base.h>
25 #include <dlfcn.h>
26 #include <common.h>
27
28 using std::make_pair;
29
30 #define ROOT_ELEMENT "PLUGIN"
31 #define TEXT_ELEMENT "text"
32 #define PATH_ATTR "path"
33 #define HAL_ELEMENT "HAL"
34 #define SENSOR_ELEMENT "SENSOR"
35
36 sensor_plugin_loader::sensor_plugin_loader()
37 {
38 }
39
40 void *sensor_plugin_loader::load_module(const char *path)
41 {
42         void *handle = dlopen(path, RTLD_NOW);
43
44         if (!handle) {
45                 DBG("Target file is %s , dlerror : %s", path, dlerror());
46                 return NULL;
47         }
48
49         dlerror();
50
51         typedef void *create_t(void);
52         typedef void destroy_t(void *);
53         create_t *init_module = (create_t *) dlsym(handle, "create");
54         const char *dlsym_error = dlerror();
55
56         if (dlsym_error) {
57                 ERR("Failed to find \"create\" %s", dlsym_error);
58                 dlclose(handle);
59                 return NULL;
60         }
61
62         destroy_t *exit_module = (destroy_t *) dlsym(handle, "destroy");
63         dlsym_error = dlerror();
64
65         if (dlsym_error) {
66                 ERR("Failed to find \"destroy\" %s", dlsym_error);
67                 dlclose(handle);
68                 return NULL;
69         }
70
71         void *module = init_module();
72
73         if (!module) {
74                 ERR("Failed to init the module => dlerror : %s , Target file is %s", dlerror(), path);
75                 dlclose(handle);
76                 return NULL;
77         }
78
79         return module;
80 }
81
82 bool sensor_plugin_loader::insert_module(const char *node_name, const char *path)
83 {
84         if (strcmp(node_name, HAL_ELEMENT) == 0) {
85                 DBG("insert sensor plugin [%s]", path);
86                 sensor_hal *module;
87                 module = (sensor_hal *)load_module(path);
88
89                 if (!module)
90                         return false;
91
92                 sensor_type_t sensor_type = module->get_type();
93                 m_sensor_hals.insert(make_pair(sensor_type, module));
94         }
95
96         if (strcmp(node_name, SENSOR_ELEMENT) == 0) {
97                 DBG("insert sensor plugin [%s]", path);
98                 sensor_base *module;
99                 module = (sensor_base *)load_module(path);
100
101                 if (!module)
102                         return false;
103
104                 if (!module->init()) {
105                         ERR("Failed to init [%s] module", module->get_name());
106                         delete module;
107                         return false;
108                 }
109
110                 DBG("init [%s] module", module->get_name());
111                 sensor_type_t sensor_type = module->get_type();
112
113                 m_sensors.insert(make_pair(sensor_type, module));
114         }
115
116         return true;
117 }
118
119 bool sensor_plugin_loader::load_plugins(const string &plugins_path)
120 {
121         xmlDocPtr doc;
122         xmlNodePtr cur;
123
124         DBG("sensor_plugin_load::load_plugins(\"%s\") is called!", plugins_path.c_str());
125         doc = xmlParseFile(plugins_path.c_str());
126
127         if (doc == NULL) {
128                 ERR("There is no %s", plugins_path.c_str());
129                 return false;
130         }
131
132         cur = xmlDocGetRootElement(doc);
133
134         if (cur == NULL) {
135                 ERR("There is no root element in %s", plugins_path.c_str());
136                 xmlFreeDoc(doc);
137                 return false;
138         }
139
140         if (xmlStrcmp(cur->name, (const xmlChar *)ROOT_ELEMENT)) {
141                 ERR("Wrong type document: there is no [%s] root element in %s", ROOT_ELEMENT, plugins_path.c_str());
142                 xmlFreeDoc(doc);
143                 return false;
144         }
145
146         xmlNodePtr plugin_list_node_ptr;
147         xmlNodePtr module_node_ptr;
148         char *prop = NULL;
149         plugin_list_node_ptr = cur->xmlChildrenNode;
150
151         while (plugin_list_node_ptr != NULL) {
152                 //skip garbage element, [text]
153                 if (!xmlStrcmp(plugin_list_node_ptr->name, (const xmlChar *)TEXT_ELEMENT)) {
154                         plugin_list_node_ptr = plugin_list_node_ptr->next;
155                         continue;
156                 }
157
158                 DBG("<%s>", (const char *)plugin_list_node_ptr->name);
159
160                 module_node_ptr = plugin_list_node_ptr->xmlChildrenNode;
161
162                 while (module_node_ptr != NULL) {
163                         if (!xmlStrcmp(module_node_ptr->name, (const xmlChar *)TEXT_ELEMENT)) {
164                                 module_node_ptr = module_node_ptr->next;
165                                 continue;
166                         }
167
168                         string path;
169                         prop = (char *)xmlGetProp(module_node_ptr, (const xmlChar *)PATH_ATTR);
170                         path = prop;
171                         free(prop);
172                         DBG("<%s path=\"%s\">", (const char *) module_node_ptr->name, path.c_str());
173                         bool error = insert_module((const char *) plugin_list_node_ptr->name, path.c_str());
174
175                         if (!error) {
176                                 //ERR("Fail to insert module : [%s]", path.c_str()) ;
177                         }
178
179                         DBG("");
180                         module_node_ptr = module_node_ptr->next;
181                 }
182
183                 DBG("");
184                 plugin_list_node_ptr = plugin_list_node_ptr->next;
185         }
186
187         xmlFreeDoc(doc);
188         show_sensor_info();
189         return true;
190 }
191
192 void sensor_plugin_loader::show_sensor_info(void)
193 {
194         int index = 0;
195         sensor_plugins::iterator it = m_sensors.begin();
196
197         INFO("========== Loaded sensor information ==========");
198
199         while (it != m_sensors.end()) {
200                 sensor_base *sensor = it->second;
201                 sensor_properties_t properties;
202                 int default_type = sensor->get_type() << SENSOR_TYPE_SHIFT | 0x1;
203
204                 if (sensor->get_properties(default_type, properties)) {
205                         INFO("[%d] %s", ++index, sensor->get_name());
206                         INFO("name : %s", properties.sensor_name);
207                         INFO("vendor : %s", properties.sensor_vendor);
208                         INFO("unit_idx : %d", properties.sensor_unit_idx);
209                         INFO("min_range : %f", properties.sensor_min_range);
210                         INFO("max_range : %f", properties.sensor_max_range);
211                         INFO("resolution : %f", properties.sensor_resolution);
212                 }
213
214                 it++;
215         }
216
217         INFO("===============================================");
218 }
219
220 sensor_hal *sensor_plugin_loader::get_sensor_hal(sensor_type_t type)
221 {
222         sensor_hal_plugins::iterator it_plugins;
223         it_plugins = m_sensor_hals.find(type);
224
225         if (it_plugins == m_sensor_hals.end())
226                 return NULL;
227
228         return it_plugins->second;
229 }
230
231 vector<sensor_hal *> sensor_plugin_loader::get_sensor_hals(sensor_type_t type)
232 {
233         vector<sensor_hal *> sensor_hal_list;
234         pair<sensor_hal_plugins::iterator, sensor_hal_plugins::iterator> ret;
235         ret = m_sensor_hals.equal_range(type);
236         sensor_hal_plugins::iterator it;
237
238         for (it = ret.first; it != ret.second; ++it) {
239                 sensor_hal_list.push_back(it->second);
240         }
241
242         return sensor_hal_list;
243 }
244
245 sensor_base *sensor_plugin_loader::get_sensor(sensor_type_t type)
246 {
247         sensor_plugins::iterator it_plugins;
248         it_plugins = m_sensors.find(type);
249
250         if (it_plugins == m_sensors.end())
251                 return NULL;
252
253         return it_plugins->second;
254 }
255
256 vector<sensor_base *> sensor_plugin_loader::get_sensors(sensor_type_t type)
257 {
258         vector<sensor_base *> sensor_list;
259         pair<sensor_plugins::iterator, sensor_plugins::iterator> ret;
260         ret = m_sensors.equal_range(type);
261         sensor_plugins::iterator it;
262
263         for (it = ret.first; it != ret.second; ++it) {
264                 sensor_list.push_back(it->second);
265         }
266
267         return sensor_list;
268 }
269
270 vector<sensor_base *> sensor_plugin_loader::get_virtual_sensors(void)
271 {
272         vector<sensor_base *> virtual_list;
273         sensor_plugins::iterator sensor_it;
274         sensor_base *module;
275
276         for (sensor_it = m_sensors.begin(); sensor_it != m_sensors.end(); ++sensor_it) {
277                 module = sensor_it->second;
278
279                 if (module && module->is_virtual() == true) {
280                         virtual_list.push_back(module);
281                 }
282         }
283
284         return virtual_list;
285 }
286
287 bool sensor_plugin_loader::destroy()
288 {
289         sensor_base *sensor;
290         sensor_plugins::iterator sensor_it;
291
292         for (sensor_it = m_sensors.begin(); sensor_it != m_sensors.end(); ++sensor_it) {
293                 sensor = sensor_it->second;
294                 delete sensor;
295         }
296
297         sensor_hal *sensor_hal;
298         sensor_hal_plugins::iterator sensor_hal_it;
299
300         for (sensor_hal_it = m_sensor_hals.begin(); sensor_hal_it != m_sensor_hals.end(); ++sensor_hal_it) {
301                 sensor_hal = sensor_hal_it->second;
302                 delete sensor_hal;
303         }
304
305         m_sensors.clear();
306         m_sensor_hals.clear();
307         return true;
308 }
309