sensord: add loader to load sensor plugins 28/123628/2
authorkibak.yoon <kibak.yoon@samsung.com>
Thu, 6 Apr 2017 08:54:20 +0000 (17:54 +0900)
committerkibak.yoon <kibak.yoon@samsung.com>
Thu, 6 Apr 2017 09:41:20 +0000 (18:41 +0900)
- it loads sensor_device/physical_sensor/fusion_sensor/external_sensor

Change-Id: Ia340e4041900d9a69a0553acc34473cf218a0f95
Signed-off-by: kibak.yoon <kibak.yoon@samsung.com>
src/server/sensor_loader.cpp
src/server/sensor_loader.h

index 7676f401d6a6138f69eb6ae2a1f4b506fa6399ef..d46a5cf6d7e30a9fb141e47aeb711c42fc769ef0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * sensord
  *
- * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
 
 #include "sensor_loader.h"
 
+#include <dlfcn.h>
+#include <dirent.h>
+#include <sensor_log.h>
+#include <sensor_hal.h>
+#include <physical_sensor.h>
+#include <fusion_sensor.h>
+#include <memory>
+
+using namespace sensor;
+
 sensor_loader::sensor_loader()
 {
 }
@@ -26,3 +36,103 @@ sensor_loader::sensor_loader()
 sensor_loader::~sensor_loader()
 {
 }
+
+void sensor_loader::load_hal(const std::string &path, device_sensor_registry_t &devices)
+{
+       load<sensor_device>(path, devices);
+}
+
+void sensor_loader::load_physical_sensor(const std::string &path, physical_sensor_registry_t &sensors)
+{
+       load<physical_sensor>(path, sensors);
+}
+
+void sensor_loader::load_fusion_sensor(const std::string &path, fusion_sensor_registry_t &sensors)
+{
+       load<fusion_sensor>(path, sensors);
+}
+
+void sensor_loader::load_external_sensor(const std::string &path, external_sensor_registry_t &sensors)
+{
+       load<external_sensor>(path, sensors);
+}
+
+void sensor_loader::unload(void)
+{
+       for (auto it = m_modules.begin(); it != m_modules.end(); ++it)
+               dlclose(it->second);
+}
+
+template<typename T>
+bool sensor_loader::load(const std::string &dir_path, std::vector<std::shared_ptr<T>> &sensors)
+{
+       bool ret;
+       void *handle;
+       std::vector<std::string> module_paths;
+       void **results;
+       T *sensor;
+
+       ret = get_module_paths(dir_path, module_paths);
+       retv_if(!ret, false);
+
+       for (auto &path : module_paths) {
+               handle = dlopen(path.c_str(), RTLD_NOW);
+               retvm_if(!handle, false, "Failed to dlopen from %s because %s", path.c_str(), dlerror());
+
+               /* TODO: out-param of the create function should be const */
+               create_t create = reinterpret_cast<create_t>(dlsym(handle, "create"));
+               if (!create) {
+                       _E("Failed to find symbols from %s", path.c_str());
+                       dlclose(handle);
+                       return false;
+               }
+
+               int size = create(&results);
+               if (size <= 0 || !results) {
+                       _E("Failed to create sensors from %s", path.c_str());
+                       dlclose(handle);
+                       return false;
+               }
+
+               for (int i = 0; i < size; ++i) {
+                       sensor = static_cast<T *>(results[i]);
+                       std::shared_ptr<T> sensor_ptr(sensor);
+                       sensors.push_back(sensor_ptr);
+               }
+
+               m_modules[path.c_str()] = handle;
+       }
+
+       return true;
+}
+
+bool sensor_loader::get_module_paths(const std::string &dir_path, std::vector<std::string> &paths)
+{
+       int ret;
+       DIR *dir = NULL;
+       struct dirent entry;
+       struct dirent *result;
+       std::string filename;
+
+       dir = opendir(dir_path.c_str());
+       retvm_if(!dir, false, "Failed to open directory[%s]", dir_path.c_str());
+
+       while (true) {
+               ret = readdir_r(dir, &entry, &result);
+
+               if (ret != 0)
+                       continue;
+               if (!result)
+                       break;
+
+               filename = std::string(entry.d_name);
+
+               if (filename == "." || filename == "..")
+                       continue;
+
+               paths.push_back(dir_path + "/" + filename);
+       }
+       closedir(dir);
+
+       return true;
+}
index ab9b9b0ea046a9158afdec7a684d168de797dce8..6aee6fe58b5d2a20a21b336928f4c9ff4625dc09 100644 (file)
 #ifndef __SENSOR_LOADER_H__
 #define __SENSOR_LOADER_H__
 
+#include <sensor_hal.h>
+#include <physical_sensor.h>
+#include <fusion_sensor.h>
+#include <external_sensor.h>
+#include <string>
+#include <vector>
+#include <memory>
+#include <map>
+
+namespace sensor {
+
+typedef std::vector<std::shared_ptr<sensor_device>> device_sensor_registry_t;
+typedef std::vector<std::shared_ptr<physical_sensor>> physical_sensor_registry_t;
+typedef std::vector<std::shared_ptr<fusion_sensor>> fusion_sensor_registry_t;
+typedef std::vector<std::shared_ptr<external_sensor>> external_sensor_registry_t;
+
 class sensor_loader {
 public:
        sensor_loader();
        virtual ~sensor_loader();
+
+       void load_hal(const std::string &path, device_sensor_registry_t &devices);
+       void load_physical_sensor(const std::string &path, physical_sensor_registry_t &sensors);
+       void load_fusion_sensor(const std::string &path, fusion_sensor_registry_t &sensors);
+       void load_external_sensor(const std::string &path, external_sensor_registry_t &sensors);
+
+       void unload(void);
+
+private:
+       template<typename T>
+       bool load(const std::string &path, std::vector<std::shared_ptr<T>> &sensors);
+
+       bool get_module_paths(const std::string &dir_path, std::vector<std::string> &paths);
+
+       std::map<std::string, void *> m_modules;
 };
 
+}
+
 #endif /* __SENSOR_LOADER_H__ */