c50cdae050daf2517283ede2691f9ae198d41c44
[platform/core/system/sensord.git] / src / client / sensor_manager.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_manager.h"
21
22 #include <sensor_log.h>
23 #include <sensor_info.h>
24 #include <sensor_utils.h>
25 #include <command_types.h>
26 #include <ipc_client.h>
27 #include <message.h>
28 #include <channel.h>
29
30 #define SIZE_STR_SENSOR_ALL 27
31
32 using namespace sensor;
33
34 class manager_handler : public ipc::channel_handler
35 {
36 public:
37         manager_handler(sensor_manager *manager)
38         : m_manager(manager)
39         {}
40         void connected(ipc::channel *ch) {}
41         void disconnected(ipc::channel *ch)
42         {
43                 /* If channel->disconnect() is not explicitly called, it will be restored */
44                 m_manager->restore();
45         }
46
47         void read(ipc::channel *ch, ipc::message &msg)
48         {
49                 /* TODO: if dynamic sensor is loaded,
50                  * it will be called with the sensor information */
51         }
52
53         void read_complete(ipc::channel *ch) {}
54         void error_caught(ipc::channel *ch, int error) {}
55
56 private:
57         sensor_manager *m_manager;
58 };
59
60 sensor_manager::sensor_manager()
61 : m_client(NULL)
62 , m_handler(NULL)
63 , m_channel(NULL)
64 , m_connected(false)
65 {
66         init();
67 }
68
69 sensor_manager::~sensor_manager()
70 {
71         deinit();
72 }
73
74 int sensor_manager::get_sensor(sensor_type_t type, sensor_t *sensor)
75 {
76         return get_sensor(utils::get_uri(type), sensor);
77 }
78
79 int sensor_manager::get_sensors(sensor_type_t type, sensor_t **list, int *count)
80 {
81         return get_sensors(utils::get_uri(type), list, count);
82 }
83
84 int sensor_manager::get_sensor(const char *uri, sensor_t *sensor)
85 {
86         if (!is_supported(uri)) {
87                 *sensor = NULL;
88                 return -ENODATA;
89         }
90
91         sensor_info *info = get_info(uri);
92         retv_if(!info, -EACCES);
93
94         *sensor = (sensor_t)info;
95         return OP_SUCCESS;
96 }
97
98 int sensor_manager::get_sensors(const char *uri, sensor_t **list, int *count)
99 {
100         retv_if(!is_supported(uri), -ENODATA);
101
102         std::vector<sensor_info *> infos;
103         int size;
104
105         infos = get_infos(uri);
106         size = infos.size();
107
108         if (size == 0) {
109                 *count = 0;
110                 return -ENODATA;
111         }
112
113         *list = (sensor_t *)malloc(sizeof(sensor_info *) * size);
114         retvm_if(!*list, -ENOMEM, "Failed to allocate memory");
115
116         for (int i = 0; i < size; ++i)
117                 *(*list + i) = infos[i];
118
119         *count = size;
120         return OP_SUCCESS;
121 }
122
123 bool sensor_manager::is_supported(sensor_t sensor)
124 {
125         retvm_if(!sensor, false, "Invalid parameter[%#x]", sensor);
126
127         for (auto it = m_infos.begin(); it != m_infos.end(); ++it) {
128                 if (&*it == sensor)
129                         return true;
130         }
131
132         return false;
133 }
134
135 bool sensor_manager::is_supported(const char *uri)
136 {
137         if (strncmp(uri, utils::get_uri(ALL_SENSOR), SIZE_STR_SENSOR_ALL) == 0)
138                 return true;
139
140         for (auto it = m_infos.begin(); it != m_infos.end(); ++it) {
141                 std::size_t found = (*it).get_uri().rfind(uri);
142
143                 if (found != std::string::npos)
144                         return true;
145         }
146
147         return false;
148 }
149
150 bool sensor_manager::init(void)
151 {
152         m_client = new(std::nothrow) ipc::ipc_client(SENSOR_CHANNEL_PATH);
153         retvm_if(!m_client, false, "Failed to allocate memory");
154
155         m_handler = new(std::nothrow) manager_handler(this);
156         if (!m_handler) {
157                 delete m_client;
158                 m_client = NULL;
159                 return false;
160         }
161
162         return true;
163 }
164
165 void sensor_manager::deinit(void)
166 {
167         disconnect();
168
169         delete m_handler;
170         m_handler = NULL;
171
172         delete m_client;
173         m_client = NULL;
174 }
175
176 bool sensor_manager::connect_channel(void)
177 {
178         m_channel = m_client->connect(m_handler, &m_loop);
179         retvm_if(!m_channel, false, "Failed to connect to server");
180
181         m_connected.store(true);
182
183         _D("Connected");
184         return true;
185 }
186
187 bool sensor_manager::connect(void)
188 {
189         retv_if(is_connected(), true);
190         retv_if(!connect_channel(), false);
191
192         return get_sensors_internal();
193 }
194
195 void sensor_manager::disconnect(void)
196 {
197         ret_if(!is_connected());
198
199         m_connected.store(false);
200         m_channel->disconnect();
201
202         delete m_channel;
203         m_channel = NULL;
204
205         _D("Disconnected");
206 }
207
208 bool sensor_manager::is_connected(void)
209 {
210         return m_connected.load();
211 }
212
213 void sensor_manager::restore(void)
214 {
215         ret_if(!is_connected());
216
217         m_connected.store(false);
218         retm_if(!connect_channel(), "Failed to restore manager");
219
220         _D("Restored manager");
221 }
222
223 void sensor_manager::decode_sensors(const char *buf, std::vector<sensor_info> &infos)
224 {
225         int count = 0;
226         sensor_info info;
227         const size_t *size;
228         const char *data;
229         cmd_manager_sensor_list_t *raw;
230
231         raw = (cmd_manager_sensor_list_t *)buf;
232         count = raw->sensor_cnt;
233         size = (const size_t *)raw->data;
234         data = (const char *)raw->data + sizeof(size_t);
235
236         for (int i = 0; i < count; ++i) {
237                 info.clear();
238                 info.deserialize(data, size[0]);
239                 infos.push_back(info);
240
241                 size = (const size_t *)((const char *)data + size[0]);
242                 data = (const char *)size + sizeof(size_t);
243         }
244
245         _D("Sensor count : %d", count);
246 }
247
248 bool sensor_manager::get_sensors_internal(void)
249 {
250         retvm_if(!is_connected(), false, "Failed to get sensors");
251
252         bool ret;
253         ipc::message msg;
254         ipc::message reply;
255         char buf[MAX_BUF_SIZE];
256
257         msg.set_type(CMD_MANAGER_SENSOR_LIST);
258
259         ret = m_channel->send_sync(&msg);
260         retvm_if(!ret, false, "Failed to send message");
261
262         ret = m_channel->read_sync(reply);
263         retvm_if(!ret, false, "Failed to receive message");
264
265         reply.disclose(buf);
266
267         decode_sensors(buf, m_infos);
268
269         return true;
270 }
271
272 bool sensor_manager::has_privilege(std::string &uri)
273 {
274         retvm_if(!is_connected(), false, "Failed to get sensors");
275
276         bool ret;
277         ipc::message msg;
278         ipc::message reply;
279         cmd_has_privilege_t buf = {0, };
280
281         msg.set_type(CMD_HAS_PRIVILEGE);
282         memcpy(buf.sensor, uri.c_str(), uri.size());
283         msg.enclose((const char *)&buf, sizeof(buf));
284
285         ret = m_channel->send_sync(&msg);
286         retvm_if(!ret, false, "Failed to send message");
287
288         ret = m_channel->read_sync(reply);
289         retvm_if(!ret, false, "Failed to receive message");
290
291         if (reply.header()->err == OP_SUCCESS)
292                 return true;
293
294         return false;
295 }
296
297 sensor_info *sensor_manager::get_info(const char *uri)
298 {
299         if (strncmp(uri, utils::get_uri(ALL_SENSOR), SIZE_STR_SENSOR_ALL) == 0)
300                 return &m_infos[0];
301
302         for (auto it = m_infos.begin(); it != m_infos.end(); ++it) {
303                 std::size_t found = (*it).get_uri().rfind(uri);
304
305                 if (found == std::string::npos)
306                         continue;
307
308                 if ((*it).get_privilege().empty())
309                         return &*it;
310
311                 if (has_privilege((*it).get_uri()))
312                         return &*it;
313         }
314
315         return NULL;
316 }
317
318 std::vector<sensor_info *> sensor_manager::get_infos(const char *uri)
319 {
320         std::vector<sensor_info *> infos;
321         bool all = false;
322
323         if (strncmp(uri, utils::get_uri(ALL_SENSOR), SIZE_STR_SENSOR_ALL) == 0)
324                 all = true;
325
326 for (auto it = m_infos.begin(); it != m_infos.end(); ++it) {
327                 std::size_t found = (*it).get_uri().rfind(uri);
328
329                 if (!all && found == std::string::npos)
330                         continue;
331
332                 if ((*it).get_privilege().empty()) {
333                         infos.push_back(&*it);
334                         continue;
335                 }
336
337                 if (has_privilege((*it).get_uri()))
338                         infos.push_back(&*it);
339         }
340
341         return infos;
342 }
343