sensor-hal: re-organize build procedure
[platform/adaptation/tm1/sensor-hal-tm1.git] / src / sensor_device_base.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_device_base.h>
21 #include <dirent.h>
22 #include <string.h>
23 #include <fstream>
24
25 using std::ifstream;
26 using std::ofstream;
27 using std::fstream;
28 using std::string;
29
30 sensor_device_base::sensor_device_base()
31 {
32 }
33
34 sensor_device_base::~sensor_device_base()
35 {
36 }
37
38 unsigned long long sensor_device_base::get_timestamp(void)
39 {
40         struct timespec t;
41         clock_gettime(CLOCK_MONOTONIC, &t);
42         return ((unsigned long long)(t.tv_sec)*1000000000LL + t.tv_nsec) / 1000;
43 }
44
45 unsigned long long sensor_device_base::get_timestamp(timeval *t)
46 {
47         if (!t) {
48                 ERR("t is NULL");
49                 return 0;
50         }
51
52         return ((unsigned long long)(t->tv_sec)*1000000LL +t->tv_usec);
53 }
54
55 bool sensor_device_base::is_sensorhub_controlled(const string &key)
56 {
57         string key_node = string("/sys/class/sensors/ssp_sensor/") + key;
58
59         if (access(key_node.c_str(), F_OK) == 0)
60                 return true;
61
62         return false;
63 }
64
65 bool sensor_device_base::get_node_info(const node_info_query &query, node_info &info)
66 {
67         bool ret = false;
68         int method;
69         string device_num;
70
71         if (!get_input_method(query.key, method, device_num)) {
72                 ERR("Failed to get input method for %s", query.key.c_str());
73                 return false;
74         }
75
76         info.method = method;
77
78         if (method == IIO_METHOD) {
79                 if (query.sensorhub_controlled)
80                         ret = get_sensorhub_iio_node_info(query.sensorhub_interval_node_name, device_num, info);
81                 else
82                         ret = get_iio_node_info(query.iio_enable_node_name, device_num, info);
83         } else {
84                 if (query.sensorhub_controlled)
85                         ret = get_sensorhub_input_event_node_info(query.sensorhub_interval_node_name, device_num, info);
86                 else
87                         ret = get_input_event_node_info(device_num, info);
88         }
89
90         return ret;
91 }
92
93
94 void sensor_device_base::show_node_info(node_info &info)
95 {
96         if (info.data_node_path.size())
97                 INFO("Data node: %s", info.data_node_path.c_str());
98         if (info.enable_node_path.size())
99                 INFO("Enable node: %s", info.enable_node_path.c_str());
100         if (info.interval_node_path.size())
101                 INFO("Interval node: %s", info.interval_node_path.c_str());
102         if (info.buffer_enable_node_path.size())
103                 INFO("Buffer enable node: %s", info.buffer_enable_node_path.c_str());
104         if (info.buffer_length_node_path.size())
105                 INFO("Buffer length node: %s", info.buffer_length_node_path.c_str());
106         if (info.trigger_node_path.size())
107                 INFO("Trigger node: %s", info.trigger_node_path.c_str());
108 }
109
110 bool sensor_device_base::get_iio_node_info(const string& enable_node_name, const string& device_num, node_info &info)
111 {
112         const string base_dir = string("/sys/bus/iio/devices/iio:device") + device_num + string("/");
113
114         info.data_node_path = string("/dev/iio:device") + device_num;
115         info.enable_node_path = base_dir + enable_node_name;
116         info.interval_node_path = base_dir + string("sampling_frequency");
117         info.buffer_enable_node_path = base_dir + string("buffer/enable");
118         info.buffer_length_node_path = base_dir + string("buffer/length");
119         info.trigger_node_path = base_dir + string("trigger/current_trigger");
120
121         return true;
122 }
123
124 bool sensor_device_base::get_sensorhub_iio_node_info(const string &interval_node_name, const string& device_num, node_info &info)
125 {
126         const string base_dir = string("/sys/bus/iio/devices/iio:device") + device_num + string("/");
127         const string hub_dir = "/sys/class/sensors/ssp_sensor/";
128
129         info.data_node_path = string("/dev/iio:device") + device_num;
130         info.enable_node_path = hub_dir + string("enable");
131         info.interval_node_path = hub_dir + interval_node_name;
132         info.buffer_enable_node_path = base_dir + string("buffer/enable");
133         info.buffer_length_node_path = base_dir + string("buffer/length");
134         return true;
135 }
136
137 bool sensor_device_base::get_input_event_node_info(const string& device_num, node_info &info)
138 {
139         string base_dir;
140         string event_num;
141
142         base_dir = string("/sys/class/input/input") + device_num + string("/");
143
144         if (!get_event_num(base_dir, event_num))
145                 return false;
146
147         info.data_node_path = string("/dev/input/event") + event_num;
148
149         info.enable_node_path = base_dir + string("enable");
150         info.interval_node_path = base_dir + string("poll_delay");
151         return true;
152 }
153
154 bool sensor_device_base::get_sensorhub_input_event_node_info(const string &interval_node_name, const string& device_num, node_info &info)
155 {
156         const string base_dir = "/sys/class/sensors/ssp_sensor/";
157         string event_num;
158
159         string input_dir = string("/sys/class/input/input") + device_num + string("/");
160
161         if (!get_event_num(input_dir, event_num))
162                 return false;
163
164         info.data_node_path = string("/dev/input/event") + event_num;
165         info.enable_node_path = base_dir + string("enable");
166         info.interval_node_path = base_dir + interval_node_name;
167         return true;
168 }
169
170 bool sensor_device_base::set_node_value(const string &node_path, int value)
171 {
172         ofstream node(node_path, ofstream::binary);
173
174         if (!node)
175                 return false;
176
177         node << value;
178
179         return true;
180 }
181
182 bool sensor_device_base::set_node_value(const string &node_path, unsigned long long value)
183 {
184         ofstream node(node_path, ofstream::binary);
185
186         if (!node)
187                 return false;
188
189         node << value;
190
191         return true;
192 }
193
194
195 bool sensor_device_base::get_node_value(const string &node_path, int &value)
196 {
197         ifstream node(node_path, ifstream::binary);
198
199         if (!node)
200                 return false;
201
202         node >> value;
203
204         return true;
205 }
206
207 bool sensor_device_base::set_enable_node(const string &node_path, bool sensorhub_controlled, bool enable, int enable_bit)
208 {
209         int prev_status, status;
210
211         if (!get_node_value(node_path, prev_status)) {
212                 ERR("Failed to get node: %s", node_path.c_str());
213                 return false;
214         }
215
216         int _enable_bit = sensorhub_controlled ? enable_bit : 0;
217
218         if (enable)
219                 status = prev_status | (1 << _enable_bit);
220         else
221                 status = prev_status & (~(1 << _enable_bit));
222
223         if (!set_node_value(node_path, status)) {
224                 ERR("Failed to set node: %s", node_path.c_str());
225                 return false;
226         }
227
228         return true;
229 }
230
231 bool sensor_device_base::get_event_num(const string &input_path, string &event_num)
232 {
233         const string event_prefix = "event";
234         DIR *dir = NULL;
235         struct dirent *dir_entry = NULL;
236         string node_name;
237         bool find = false;
238
239         dir = opendir(input_path.c_str());
240         if (!dir) {
241                 ERR("Failed to open dir: %s", input_path.c_str());
242                 return false;
243         }
244
245         int prefix_size = event_prefix.size();
246
247         while (!find && (dir_entry = readdir(dir))) {
248                 node_name = dir_entry->d_name;
249
250                 if (node_name.compare(0, prefix_size, event_prefix) == 0) {
251                         event_num = node_name.substr(prefix_size, node_name.size() - prefix_size);
252                         find = true;
253                         break;
254                 }
255         }
256
257         closedir(dir);
258
259         return find;
260 }
261
262 bool sensor_device_base::get_input_method(const string &key, int &method, string &device_num)
263 {
264         input_method_info input_info[2] = {
265                 {INPUT_EVENT_METHOD, "/sys/class/input/", "input"},
266                 {IIO_METHOD, "/sys/bus/iio/devices/", "iio:device"}
267         };
268
269         const int input_info_len = sizeof(input_info)/sizeof(input_info[0]);
270         size_t prefix_size;
271         string name_node, name;
272         string d_name;
273         DIR *dir = NULL;
274         struct dirent *dir_entry = NULL;
275         bool find = false;
276
277         for (int i = 0; i < input_info_len; ++i) {
278
279                 prefix_size = input_info[i].prefix.size();
280
281                 dir = opendir(input_info[i].dir_path.c_str());
282                 if (!dir) {
283                         ERR("Failed to open dir: %s", input_info[i].dir_path.c_str());
284                         return false;
285                 }
286
287                 find = false;
288
289                 while (!find && (dir_entry = readdir(dir))) {
290                         d_name = string(dir_entry->d_name);
291
292                         if (d_name.compare(0, prefix_size, input_info[i].prefix) == 0) {
293                                 name_node = input_info[i].dir_path + d_name + string("/name");
294
295                                 ifstream infile(name_node.c_str());
296                                 if (!infile)
297                                         continue;
298
299                                 infile >> name;
300
301                                 if (name == key) {
302                                         device_num = d_name.substr(prefix_size, d_name.size() - prefix_size);
303                                         find = true;
304                                         method = input_info[i].method;
305                                         break;
306                                 }
307                         }
308                 }
309
310                 closedir(dir);
311
312                 if (find)
313                         break;
314         }
315
316         return find;
317 }