f61116216b8ba04b692ce4ca364e4dc6568b29d5
[platform/core/system/sensord.git] / src / geo / geo_sensor_hal.cpp
1 /*
2  * sensord
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 <fstream>
21 #include <fcntl.h>
22 #include <sys/stat.h>
23 #include <sys/ioctl.h>
24 #include <dirent.h>
25 #include <linux/input.h>
26 #include <cconfig.h>
27 #include <geo_sensor_hal.h>
28 #include <iio_common.h>
29
30 using std::ifstream;
31 using std::string;
32 using config::CConfig;
33
34 #define SENSOR_TYPE_MAGNETIC    "MAGNETIC"
35 #define ELEMENT_NAME                    "NAME"
36 #define ELEMENT_VENDOR                  "VENDOR"
37 #define ATTR_VALUE                              "value"
38
39 #define SENSOR_MIN_RANGE                -1200
40 #define SENSOR_MAX_RANGE                1200
41 #define INITIAL_TIME                    0
42 #define INITIAL_VALUE                   -1
43 #define GAUSS_TO_UTESLA(val)    ((val) * 100)
44
45 geo_sensor_hal::geo_sensor_hal()
46 : m_x(INITIAL_VALUE)
47 , m_y(INITIAL_VALUE)
48 , m_z(INITIAL_VALUE)
49 , m_polling_interval(POLL_1HZ_MS)
50 , m_fired_time(INITIAL_TIME)
51 , m_sensorhub_supported(false)
52 {
53         if (!check_hw_node())
54         {
55                 ERR("check_hw_node() fail");
56                 throw ENXIO;
57         }
58
59         CConfig &config = CConfig::get_instance();
60
61         if (!config.get(SENSOR_TYPE_MAGNETIC, m_model_id, ELEMENT_VENDOR, m_vendor))
62         {
63                 ERR("[VENDOR] is empty");
64                 throw ENXIO;
65         }
66
67         INFO("m_vendor = %s", m_vendor.c_str());
68
69         if (!config.get(SENSOR_TYPE_MAGNETIC, m_model_id, ELEMENT_NAME, m_chip_name))
70         {
71                 ERR("[NAME] is empty");
72                 throw ENXIO;
73         }
74
75         INFO("m_chip_name = %s", m_chip_name.c_str());
76
77         if (!init_resources())
78                 throw ENXIO;
79
80         INFO("geo_sensor_hal is created!");
81 }
82
83 geo_sensor_hal::~geo_sensor_hal()
84 {
85         INFO("geo_sensor_hal is destroyed!");
86 }
87
88 bool geo_sensor_hal::init_resources(void)
89 {
90         ifstream temp_handle;
91
92         if (!read_node_value<double>(m_x_scale_node, m_x_scale))
93                 return false;
94
95         if (!read_node_value<double>(m_y_scale_node, m_y_scale))
96                 return false;
97
98         if (!read_node_value<double>(m_z_scale_node, m_z_scale))
99                 return false;
100
101         INFO("Scale Values: %f, %f, %f", m_x_scale, m_y_scale, m_z_scale);
102         return true;
103 }
104
105 string geo_sensor_hal::get_model_id(void)
106 {
107         return m_model_id;
108 }
109
110 sensor_type_t geo_sensor_hal::get_type(void)
111 {
112         return GEOMAGNETIC_SENSOR;
113 }
114
115 bool geo_sensor_hal::enable(void)
116 {
117         INFO("Resource already enabled. Enable not supported.");
118         return true;
119 }
120
121 bool geo_sensor_hal::disable(void)
122 {
123         INFO("Disable not supported.");
124         return true;
125 }
126
127 bool geo_sensor_hal::set_interval(unsigned long val)
128 {
129         INFO("Polling interval cannot be changed.");
130         return true;
131 }
132
133 bool geo_sensor_hal::update_value(void)
134 {
135         int raw_values[3] = {0,};
136         ifstream temp_handle;
137
138         if (!read_node_value<int>(m_x_node, raw_values[0]))
139                 return false;
140
141         if (!read_node_value<int>(m_y_node, raw_values[1]))
142                 return false;
143
144         if (!read_node_value<int>(m_z_node, raw_values[2]))
145                 return false;
146
147         m_x = GAUSS_TO_UTESLA(raw_values[0] * m_x_scale);
148         m_y = GAUSS_TO_UTESLA(raw_values[1] * m_y_scale);
149         m_z = GAUSS_TO_UTESLA(raw_values[2] * m_z_scale);
150
151         m_fired_time = INITIAL_TIME;
152         INFO("x = %d, y = %d, z = %d, time = %lluus", raw_values[0], raw_values[0], raw_values[0], m_fired_time);
153
154         return true;
155 }
156
157 bool geo_sensor_hal::is_data_ready(bool wait)
158 {
159         bool ret;
160         ret = update_value();
161         return ret;
162 }
163
164 int geo_sensor_hal::get_sensor_data(sensor_data_t &data)
165 {
166         data.data_unit_idx = SENSOR_UNIT_MICRO_TESLA;
167         data.timestamp = m_fired_time;
168         data.values_num = 3;
169         data.values[0] = (float)m_x;
170         data.values[1] = (float)m_y;
171         data.values[2] = (float)m_z;
172         return 0;
173 }
174
175 bool geo_sensor_hal::get_properties(sensor_properties_t &properties)
176 {
177         properties.sensor_unit_idx = SENSOR_UNIT_MICRO_TESLA;
178         properties.sensor_min_range = SENSOR_MIN_RANGE;
179         properties.sensor_max_range = SENSOR_MAX_RANGE;
180         snprintf(properties.sensor_name, sizeof(properties.sensor_name), "%s", m_chip_name.c_str());
181         snprintf(properties.sensor_vendor, sizeof(properties.sensor_vendor), "%s", m_vendor.c_str());
182         properties.sensor_resolution = 1;
183         return true;
184 }
185
186 bool geo_sensor_hal::is_sensorhub_supported(void)
187 {
188         return false;
189 }
190
191 bool geo_sensor_hal::check_hw_node(void)
192 {
193         string hw_name;
194         string file_name;
195         DIR *main_dir = NULL;
196         struct dirent *dir_entry = NULL;
197         bool find_node = false;
198
199         INFO("======================start check_hw_node=============================");
200
201         m_sensorhub_supported = is_sensorhub_supported();
202         main_dir = opendir(IIO_DIR);
203
204         if (!main_dir)
205         {
206                 ERR("Could not open IIO directory\n");
207                 return false;
208         }
209
210         while (!find_node)
211         {
212                 dir_entry = readdir(main_dir);
213                 if(dir_entry == NULL)
214                         break;
215
216                 if ((strncasecmp(dir_entry->d_name , ".", 1 ) != 0) && (strncasecmp(dir_entry->d_name , "..", 2 ) != 0) && (dir_entry->d_ino != 0))
217                 {
218                         file_name = string(IIO_DIR) + string(dir_entry->d_name) + string(NAME_NODE);
219                         ifstream infile(file_name.c_str());
220
221                         if (!infile)
222                                 continue;
223
224                         infile >> hw_name;
225
226                         if (CConfig::get_instance().is_supported(SENSOR_TYPE_MAGNETIC, hw_name) == true)
227                         {
228                                 m_name = m_model_id = hw_name;
229                                 INFO("m_model_id = %s", m_model_id.c_str());
230
231                                 string temp = string(IIO_DIR) + string(dir_entry->d_name);
232
233                                 m_x_node = temp + string(X_RAW_VAL_NODE);
234                                 m_y_node = temp + string(Y_RAW_VAL_NODE);
235                                 m_z_node = temp + string(Z_RAW_VAL_NODE);
236                                 m_x_scale_node = temp + string(X_SCALE_NODE);
237                                 m_y_scale_node = temp + string(Y_SCALE_NODE);
238                                 m_z_scale_node = temp + string(Z_SCALE_NODE);
239
240                                 find_node = true;
241                                 break;
242                         }
243                 }
244         }
245
246         closedir(main_dir);
247         return find_node;
248 }
249
250 extern "C" void *create(void)
251 {
252         geo_sensor_hal *inst;
253
254         try
255         {
256                 inst = new geo_sensor_hal();
257         }
258         catch (int err)
259         {
260                 ERR("Failed to create geo_sensor_hal class, errno : %d, errstr : %s", err, strerror(err));
261                 return NULL;
262         }
263
264         return (void *)inst;
265 }
266
267 extern "C" void destroy(void *inst)
268 {
269         delete (geo_sensor_hal *)inst;
270 }