Synchronizing geo sensor plugin with addition of IIO interface support
[platform/core/system/sensord.git] / src / geo / geo_sensor_hal.cpp
1 /*
2  * geo_sensor_hal
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 #include <fcntl.h>
20 #include <sys/stat.h>
21 #include <dirent.h>
22
23 #include <linux/input.h>
24 #include <cconfig.h>
25
26 #include <geo_sensor_hal.h>
27 #include <sys/ioctl.h>
28 #include <fstream>
29 #include <cconfig.h>
30 #include <iio_common.h>
31
32 using std::ifstream;
33 using config::CConfig;
34
35 #define SENSOR_TYPE_MAGNETIC    "MAGNETIC"
36 #define ELEMENT_NAME                    "NAME"
37 #define ELEMENT_VENDOR                  "VENDOR"
38 #define ELEMENT_RAW_DATA_UNIT   "RAW_DATA_UNIT"
39 #define ELEMENT_MIN_RANGE               "MIN_RANGE"
40 #define ELEMENT_MAX_RANGE               "MAX_RANGE"
41 #define ATTR_VALUE                              "value"
42
43 #define INITIAL_TIME                    -1
44 #define GAUSS_TO_UTESLA(val)    ((val) * 100.0f)
45
46 geo_sensor_hal::geo_sensor_hal()
47 : m_x(0)
48 , m_y(0)
49 , m_z(0)
50 , m_hdst(0)
51 , m_node_handle(-1)
52 , m_polling_interval(POLL_1HZ_MS)
53 , m_fired_time(INITIAL_TIME)
54 {
55         const string sensorhub_interval_node_name = "mag_poll_delay";
56         CConfig &config = CConfig::get_instance();
57
58         node_path_info_query query;
59         node_path_info info;
60         int input_method = IIO_METHOD;
61
62         if (!get_model_properties(SENSOR_TYPE_MAGNETIC, m_model_id, input_method)) {
63                 ERR("Failed to find model_properties");
64                 throw ENXIO;
65
66         }
67
68         query.input_method = input_method;
69         query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name);
70         query.sensor_type = SENSOR_TYPE_MAGNETIC;
71         query.input_event_key = "geomagnetic_sensor";
72         query.iio_enable_node_name = "geomagnetic_enable";
73         query.sensorhub_interval_node_name = sensorhub_interval_node_name;
74
75         if (!get_node_path_info(query, info)) {
76                 ERR("Failed to get node info");
77                 throw ENXIO;
78         }
79
80         show_node_path_info(info);
81
82         m_data_node = info.data_node_path;
83         m_enable_node = info.enable_node_path;
84         m_interval_node = info.interval_node_path;
85
86         if (input_method == IIO_METHOD) {
87                 m_geo_dir = info.base_dir;
88                 m_x_node = m_geo_dir + string(X_RAW_VAL_NODE);
89                 m_y_node = m_geo_dir + string(Y_RAW_VAL_NODE);
90                 m_z_node = m_geo_dir + string(Z_RAW_VAL_NODE);
91                 m_x_scale_node = m_geo_dir + string(X_SCALE_NODE);
92                 m_y_scale_node = m_geo_dir + string(Y_SCALE_NODE);
93                 m_z_scale_node = m_geo_dir + string(Z_SCALE_NODE);
94                 INFO("Raw data node X: %s", m_x_node.c_str());
95                 INFO("Raw data node Y: %s", m_y_node.c_str());
96                 INFO("Raw data node Z: %s", m_z_node.c_str());
97                 INFO("scale node X: %s", m_x_scale_node.c_str());
98                 INFO("scale node Y: %s", m_y_scale_node.c_str());
99                 INFO("scale node Z: %s", m_z_scale_node.c_str());
100         }
101
102         if (!config.get(SENSOR_TYPE_MAGNETIC, m_model_id, ELEMENT_VENDOR, m_vendor)) {
103                 ERR("[VENDOR] is empty\n");
104                 throw ENXIO;
105         }
106
107         INFO("m_vendor = %s", m_vendor.c_str());
108
109         if (!config.get(SENSOR_TYPE_MAGNETIC, m_model_id, ELEMENT_NAME, m_chip_name)) {
110                 ERR("[NAME] is empty\n");
111                 throw ENXIO;
112         }
113
114         init_resources();
115
116         INFO("m_chip_name = %s\n",m_chip_name.c_str());
117         INFO("m_raw_data_unit = %f\n", m_raw_data_unit);
118         INFO("geo_sensor_hal is created!\n");
119
120 }
121
122 geo_sensor_hal::~geo_sensor_hal()
123 {
124         if (m_node_handle > 0)
125                 close(m_node_handle);
126         m_node_handle = -1;
127
128         INFO("geo_sensor is destroyed!\n");
129 }
130
131 string geo_sensor_hal::get_model_id(void)
132 {
133         return m_model_id;
134 }
135
136 sensor_type_t geo_sensor_hal::get_type(void)
137 {
138         return GEOMAGNETIC_SENSOR;
139 }
140
141 bool geo_sensor_hal::enable(void)
142 {
143         m_fired_time = INITIAL_TIME;
144         INFO("Geo sensor real starting");
145         return true;
146 }
147
148 bool geo_sensor_hal::disable(void)
149 {
150         INFO("Geo sensor real stopping");
151         return true;
152 }
153
154 bool geo_sensor_hal::set_interval(unsigned long val)
155 {
156         INFO("Polling interval cannot be changed.");
157         return true;
158
159 }
160
161 bool geo_sensor_hal::update_value(void)
162 {
163         int raw_values[3] = {0,};
164         ifstream temp_handle;
165
166         if (!read_node_value<int>(m_x_node, raw_values[0]))
167                 return false;
168         if (!read_node_value<int>(m_y_node, raw_values[1]))
169                 return false;
170         if (!read_node_value<int>(m_z_node, raw_values[2]))
171                 return false;
172
173         m_x = GAUSS_TO_UTESLA(raw_values[0] * m_x_scale);
174         m_y = GAUSS_TO_UTESLA(raw_values[1] * m_y_scale);
175         m_z = GAUSS_TO_UTESLA(raw_values[2] * m_z_scale);
176
177         m_fired_time = INITIAL_TIME;
178         INFO("x = %d, y = %d, z = %d, time = %lluus", raw_values[0], raw_values[1], raw_values[2], m_fired_time);
179         INFO("x = %f, y = %f, z = %f, time = %lluus", m_x, m_y, m_z, m_fired_time);
180
181         return true;
182 }
183
184 bool geo_sensor_hal::is_data_ready(bool wait)
185 {
186         bool ret;
187         ret = update_value();
188         return ret;
189 }
190
191 int geo_sensor_hal::get_sensor_data(sensor_data_t &data)
192 {
193         data.accuracy = SENSOR_ACCURACY_GOOD;
194         data.timestamp = m_fired_time;
195         data.value_count = 3;
196         data.values[0] = (float)m_x;
197         data.values[1] = (float)m_y;
198         data.values[2] = (float)m_z;
199         return 0;
200 }
201
202 bool geo_sensor_hal::get_properties(sensor_properties_t &properties)
203 {
204         properties.name = m_chip_name;
205         properties.vendor = m_vendor;
206         properties.min_range = m_min_range;
207         properties.max_range = m_max_range;
208         properties.min_interval = 1;
209         properties.resolution = m_raw_data_unit;
210         properties.fifo_count = 0;
211         properties.max_batch_count = 0;
212         return true;
213 }
214
215 bool geo_sensor_hal::init_resources(void)
216 {
217         ifstream temp_handle;
218
219         if (!read_node_value<double>(m_x_scale_node, m_x_scale)) {
220                 ERR("Failed to read x scale node");
221                 return false;
222         }
223         if (!read_node_value<double>(m_y_scale_node, m_y_scale)) {
224                 ERR("Failed to read y scale node");
225                 return false;
226         }
227         if (!read_node_value<double>(m_z_scale_node, m_z_scale)) {
228                 ERR("Failed to read y scale node");
229                 return false;
230         }
231         INFO("Scale Values: %f, %f, %f", m_x_scale, m_y_scale, m_z_scale);
232         return true;
233 }
234
235 extern "C" void *create(void)
236 {
237         geo_sensor_hal *inst;
238
239         try {
240                 inst = new geo_sensor_hal();
241         } catch (int err) {
242                 ERR("geo_sensor_hal class create fail , errno : %d , errstr : %s\n", err, strerror(err));
243                 return NULL;
244         }
245
246         return (void*)inst;
247 }
248
249 extern "C" void destroy(void *inst)
250 {
251         delete (geo_sensor_hal*)inst;
252 }