Add hrm_batch sensor type
[platform/core/system/sensord.git] / src / server / sensor_loader.cpp
1 /*
2  * sensord
3  *
4  * Copyright (c) 2017 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_loader.h"
21
22 #include <unistd.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <dlfcn.h>
26 #include <dirent.h>
27 #include <sensor_log.h>
28 #include <sensor_hal.h>
29 #include <physical_sensor.h>
30 #include <fusion_sensor.h>
31 #include <memory>
32
33 using namespace sensor;
34
35 sensor_loader::sensor_loader()
36 {
37 }
38
39 sensor_loader::~sensor_loader()
40 {
41 }
42
43 void sensor_loader::load_hal(const std::string &path, device_sensor_registry_t &devices)
44 {
45         load<sensor_device>(path, devices);
46 }
47
48 void sensor_loader::load_physical_sensor(const std::string &path, physical_sensor_registry_t &sensors)
49 {
50         load<physical_sensor>(path, sensors);
51 }
52
53 void sensor_loader::load_fusion_sensor(const std::string &path, fusion_sensor_registry_t &sensors)
54 {
55         load<fusion_sensor>(path, sensors);
56 }
57
58 void sensor_loader::load_external_sensor(const std::string &path, external_sensor_registry_t &sensors)
59 {
60         load<external_sensor>(path, sensors);
61 }
62
63 void sensor_loader::unload(void)
64 {
65         for (auto it = m_modules.begin(); it != m_modules.end(); ++it)
66                 dlclose(it->second);
67 }
68
69 template<typename T>
70 bool sensor_loader::load(const std::string &dir_path, std::vector<std::shared_ptr<T>> &sensors)
71 {
72         bool ret;
73         void *handle;
74         std::vector<std::string> module_paths;
75         void **results;
76
77         ret = get_module_paths(dir_path, module_paths);
78         retv_if(!ret, false);
79
80         for (auto &path : module_paths) {
81                 _I("Load sensor devices from %s", path.c_str());
82                 handle = dlopen(path.c_str(), RTLD_NOW);
83                 retvm_if(!handle, false, "Failed to dlopen from %s because %s", path.c_str(), dlerror());
84
85                 /* TODO: out-param of the create function should be const */
86                 create_t create = reinterpret_cast<create_t>(dlsym(handle, "create"));
87                 if (!create) {
88                         _E("Failed to find symbols from %s", path.c_str());
89                         dlclose(handle);
90                         return false;
91                 }
92
93                 int size = create(&results);
94                 if (size <= 0 || !results) {
95                         _E("Failed to create sensors from %s", path.c_str());
96                         dlclose(handle);
97                         return false;
98                 }
99
100                 for (int i = 0; i < size; ++i)
101                         sensors.emplace_back(static_cast<T *>(results[i]));
102
103                 m_modules[path.c_str()] = handle;
104                 _I("Success to load sensor devices from %s", path.c_str());
105         }
106
107         return true;
108 }
109
110 bool sensor_loader::get_module_paths(const std::string &dir_path, std::vector<std::string> &paths)
111 {
112         DIR *dir = NULL;
113         struct dirent *entry;
114         struct stat buf;
115         std::string filename;
116
117         dir = opendir(dir_path.c_str());
118         retvm_if(!dir, false, "Failed to open directory[%s]", dir_path.c_str());
119
120         while (true) {
121                 entry = readdir(dir);
122                 if (!entry) break;
123
124                 filename = std::string(entry->d_name);
125
126                 if (filename == "." || filename == "..")
127                         continue;
128
129                 std::string full_path = dir_path + "/" + filename;
130
131                 if (lstat(full_path.c_str(), &buf) != 0)
132                         break;
133
134                 if (S_ISDIR(buf.st_mode))
135                         continue;
136
137                 paths.push_back(full_path);
138         }
139         closedir(dir);
140
141         return true;
142 }