4 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
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>
28 #include <unordered_set>
33 using std::unordered_set;
35 #define ROOT_ELEMENT "PLUGIN"
36 #define TEXT_ELEMENT "text"
37 #define PATH_ATTR "path"
38 #define HAL_ELEMENT "HAL"
39 #define SENSOR_ELEMENT "SENSOR"
41 #define PLUGINS_CONFIG_PATH "/usr/etc/sensor_plugins.xml"
42 #define PLUGINS_DIR_PATH "/sensord"
44 #define SENSOR_INDEX_SHIFT 16
46 sensor_plugin_loader::sensor_plugin_loader()
50 sensor_plugin_loader& sensor_plugin_loader::get_instance()
52 static sensor_plugin_loader inst;
56 bool sensor_plugin_loader::load_module(const string &path, void** module, void** handle)
58 void *_handle = dlopen(path.c_str(), RTLD_NOW);
61 ERR("Failed with dlopen(%s), dlerror : %s", path.c_str(), dlerror());
67 typedef void* create_t(void);
68 typedef void destroy_t(void *);
70 create_t* init_module = (create_t*) dlsym(_handle, "create");
73 ERR("Failed to find \"create\" symbol");
78 destroy_t* exit_module = (destroy_t*) dlsym(_handle, "destroy");
81 ERR("Failed to find \"destroy\" symbol");
86 void *_module = init_module();
89 ERR("Failed to init the module, Target file is %s\n", path.c_str());
101 bool sensor_plugin_loader::insert_module(plugin_type type, const string &path)
103 if (type == PLUGIN_TYPE_HAL) {
104 DBG("insert sensor plugin [%s]", path.c_str());
108 if (!load_module(path, (void **)&module, &handle))
111 sensor_type_t sensor_type = module->get_type();
112 m_sensor_hals.insert(make_pair(sensor_type, module));
113 } else if (type == PLUGIN_TYPE_SENSOR) {
114 DBG("insert sensor plugin [%s]", path.c_str());
118 if (!load_module(path, (void**)&module, &handle))
121 if (!module->init()) {
122 ERR("Failed to init [%s] module\n", module->get_name());
127 DBG("init [%s] module", module->get_name());
129 sensor_type_t sensor_type = module->get_type();
132 idx = m_sensors.count(sensor_type);
133 module->set_id(idx << SENSOR_INDEX_SHIFT | sensor_type);
134 m_sensors.insert(make_pair(sensor_type, module));
136 ERR("Not supported type: %d", type);
143 bool sensor_plugin_loader::load_plugins(void)
145 vector<string> hal_paths, sensor_paths;
146 vector<string> unique_hal_paths, unique_sensor_paths;
148 get_paths_from_config(string(PLUGINS_CONFIG_PATH), hal_paths, sensor_paths);
149 get_paths_from_dir(string(LIBDIR) + string(PLUGINS_DIR_PATH), hal_paths, sensor_paths);
151 //remove duplicates while keeping the original ordering => unique_*_paths
152 unordered_set<string> s;
153 auto unique = [&s](vector<string> &paths, const string &path) {
154 if (s.insert(path).second)
155 paths.push_back(path);
158 for_each(hal_paths.begin(), hal_paths.end(),
159 [&](const string &path) {
160 unique(unique_hal_paths, path);
164 for_each(sensor_paths.begin(), sensor_paths.end(),
165 [&](const string &path) {
166 unique(unique_sensor_paths, path);
170 //load plugins specified by unique_*_paths
171 auto insert = [&](plugin_type type, const string &path) {
172 insert_module(type, path);
175 for_each(unique_hal_paths.begin(), unique_hal_paths.end(),
176 [&](const string &path) {
177 insert(PLUGIN_TYPE_HAL, path);
181 for_each(unique_sensor_paths.begin(), unique_sensor_paths.end(),
182 [&](const string &path) {
183 insert(PLUGIN_TYPE_SENSOR, path);
191 void sensor_plugin_loader::show_sensor_info(void)
193 INFO("========== Loaded sensor information ==========\n");
197 auto it = m_sensors.begin();
199 while (it != m_sensors.end()) {
200 sensor_base* sensor = it->second;
203 sensor->get_sensor_info(info);
204 INFO("No:%d [%s]\n", ++index, sensor->get_name());
209 INFO("===============================================\n");
213 bool sensor_plugin_loader::get_paths_from_dir(const string &dir_path, vector<string> &hal_paths, vector<string> &sensor_paths)
215 const string PLUGIN_POSTFIX = ".so";
216 const string HAL_POSTFIX = "_hal.so";
219 struct dirent *dir_entry = NULL;
221 dir = opendir(dir_path.c_str());
224 ERR("Failed to open dir: %s", dir_path.c_str());
230 while ((dir_entry = readdir(dir))) {
231 name = string(dir_entry->d_name);
233 if (equal(PLUGIN_POSTFIX.rbegin(), PLUGIN_POSTFIX.rend(), name.rbegin())) {
234 if (equal(HAL_POSTFIX.rbegin(), HAL_POSTFIX.rend(), name.rbegin()))
235 hal_paths.push_back(dir_path + "/" + name);
237 sensor_paths.push_back(dir_path + "/" + name);
245 bool sensor_plugin_loader::get_paths_from_config(const string &config_path, vector<string> &hal_paths, vector<string> &sensor_paths)
250 doc = xmlParseFile(config_path.c_str());
253 ERR("There is no %s\n", config_path.c_str());
257 cur = xmlDocGetRootElement(doc);
260 ERR("There is no root element in %s\n", config_path.c_str());
265 if (xmlStrcmp(cur->name, (const xmlChar *)ROOT_ELEMENT)) {
266 ERR("Wrong type document: there is no [%s] root element in %s\n", ROOT_ELEMENT, config_path.c_str());
271 xmlNodePtr plugin_list_node_ptr;
272 xmlNodePtr module_node_ptr;
274 string path, category;
276 plugin_list_node_ptr = cur->xmlChildrenNode;
278 while (plugin_list_node_ptr != NULL) {
279 //skip garbage element, [text]
280 if (!xmlStrcmp(plugin_list_node_ptr->name, (const xmlChar *)TEXT_ELEMENT)) {
281 plugin_list_node_ptr = plugin_list_node_ptr->next;
285 DBG("<%s>\n", (const char*)plugin_list_node_ptr->name);
287 module_node_ptr = plugin_list_node_ptr->xmlChildrenNode;
288 while (module_node_ptr != NULL) {
289 if (!xmlStrcmp(module_node_ptr->name, (const xmlChar *)TEXT_ELEMENT)) {
290 module_node_ptr = module_node_ptr->next;
294 prop = (char*)xmlGetProp(module_node_ptr, (const xmlChar*)PATH_ATTR);
298 DBG("<%s path=\"%s\">\n", (const char*) module_node_ptr->name, path.c_str());
300 category = (const char*) plugin_list_node_ptr->name;
302 if (category == string(HAL_ELEMENT))
303 hal_paths.push_back(path);
304 else if (category == string(SENSOR_ELEMENT))
305 sensor_paths.push_back(path);
308 module_node_ptr = module_node_ptr->next;
312 plugin_list_node_ptr = plugin_list_node_ptr->next;
321 sensor_hal* sensor_plugin_loader::get_sensor_hal(sensor_type_t type)
323 auto it_plugins = m_sensor_hals.find(type);
325 if (it_plugins == m_sensor_hals.end())
328 return it_plugins->second;
331 vector<sensor_hal *> sensor_plugin_loader::get_sensor_hals(sensor_type_t type)
333 vector<sensor_hal *> sensor_hal_list;
334 pair<sensor_hal_plugins::iterator, sensor_hal_plugins::iterator> ret;
335 ret = m_sensor_hals.equal_range(type);
337 for (auto it = ret.first; it != ret.second; ++it)
338 sensor_hal_list.push_back(it->second);
340 return sensor_hal_list;
343 sensor_base* sensor_plugin_loader::get_sensor(sensor_type_t type)
345 auto it_plugins = m_sensors.find(type);
347 if (it_plugins == m_sensors.end())
350 return it_plugins->second;
353 vector<sensor_base *> sensor_plugin_loader::get_sensors(sensor_type_t type)
355 vector<sensor_base *> sensor_list;
356 pair<sensor_plugins::iterator, sensor_plugins::iterator> ret;
358 if (type == ALL_SENSOR)
359 ret = std::make_pair(m_sensors.begin(), m_sensors.end());
361 ret = m_sensors.equal_range(type);
363 for (auto it = ret.first; it != ret.second; ++it)
364 sensor_list.push_back(it->second);
370 sensor_base* sensor_plugin_loader::get_sensor(sensor_id_t id)
372 const int SENSOR_TYPE_MASK = 0x0000FFFF;
373 vector<sensor_base *> sensors;
375 sensor_type_t type = (sensor_type_t) (id & SENSOR_TYPE_MASK);
376 unsigned int index = id >> SENSOR_INDEX_SHIFT;
378 sensors = get_sensors(type);
380 if (sensors.size() <= index)
383 return sensors[index];
387 vector<sensor_base *> sensor_plugin_loader::get_virtual_sensors(void)
389 vector<sensor_base *> virtual_list;
392 for (auto sensor_it = m_sensors.begin(); sensor_it != m_sensors.end(); ++sensor_it) {
393 module = sensor_it->second;
395 if (module && module->is_virtual() == true) {
396 virtual_list.push_back(module);
403 bool sensor_plugin_loader::destroy()
407 for (auto sensor_it = m_sensors.begin(); sensor_it != m_sensors.end(); ++sensor_it) {
408 sensor = sensor_it->second;
411 //unregister_module(module);
416 sensor_hal* sensor_hal;
418 for (auto sensor_hal_it = m_sensor_hals.begin(); sensor_hal_it != m_sensor_hals.end(); ++sensor_hal_it) {
419 sensor_hal = sensor_hal_it->second;
422 //unregister_module(module);
428 m_sensor_hals.clear();