4 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include "sensor_manager.h"
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>
30 #define SIZE_STR_SENSOR_ALL 27
32 using namespace sensor;
34 class manager_handler : public ipc::channel_handler
37 manager_handler(sensor_manager *manager)
40 void connected(ipc::channel *ch) {}
41 void disconnected(ipc::channel *ch)
43 /* If channel->disconnect() is not explicitly called, it will be restored */
47 void read(ipc::channel *ch, ipc::message &msg)
49 /* TODO: if dynamic sensor is loaded,
50 * it will be called with the sensor information */
53 void read_complete(ipc::channel *ch) {}
54 void error_caught(ipc::channel *ch, int error) {}
57 sensor_manager *m_manager;
60 sensor_manager::sensor_manager()
69 sensor_manager::~sensor_manager()
74 int sensor_manager::get_sensor(sensor_type_t type, sensor_t *sensor)
76 return get_sensor(utils::get_uri(type), sensor);
79 int sensor_manager::get_sensors(sensor_type_t type, sensor_t **list, int *count)
81 return get_sensors(utils::get_uri(type), list, count);
84 int sensor_manager::get_sensor(const char *uri, sensor_t *sensor)
86 if (!is_supported(uri)) {
91 sensor_info *info = get_info(uri);
92 retv_if(!info, -EACCES);
94 *sensor = (sensor_t)info;
98 int sensor_manager::get_sensors(const char *uri, sensor_t **list, int *count)
100 retv_if(!is_supported(uri), -ENODATA);
102 std::vector<sensor_info *> infos;
105 infos = get_infos(uri);
113 *list = (sensor_t *)malloc(sizeof(sensor_info *) * size);
114 retvm_if(!*list, -ENOMEM, "Failed to allocate memory");
116 for (int i = 0; i < size; ++i)
117 *(*list + i) = infos[i];
123 bool sensor_manager::is_supported(sensor_t sensor)
125 retvm_if(!sensor, false, "Invalid parameter[%#x]", sensor);
127 for (auto it = m_infos.begin(); it != m_infos.end(); ++it) {
135 bool sensor_manager::is_supported(const char *uri)
137 if (strncmp(uri, utils::get_uri(ALL_SENSOR), SIZE_STR_SENSOR_ALL) == 0)
140 for (auto it = m_infos.begin(); it != m_infos.end(); ++it) {
141 std::size_t found = (*it).get_uri().rfind(uri);
143 if (found != std::string::npos)
150 bool sensor_manager::init(void)
152 m_client = new(std::nothrow) ipc::ipc_client(SENSOR_CHANNEL_PATH);
153 retvm_if(!m_client, false, "Failed to allocate memory");
155 m_handler = new(std::nothrow) manager_handler(this);
165 void sensor_manager::deinit(void)
176 bool sensor_manager::connect_channel(void)
178 m_channel = m_client->connect(m_handler, &m_loop);
179 retvm_if(!m_channel, false, "Failed to connect to server");
181 m_connected.store(true);
187 bool sensor_manager::connect(void)
189 retv_if(is_connected(), true);
190 retv_if(!connect_channel(), false);
192 return get_sensors_internal();
195 void sensor_manager::disconnect(void)
197 ret_if(!is_connected());
199 m_connected.store(false);
200 m_channel->disconnect();
208 bool sensor_manager::is_connected(void)
210 return m_connected.load();
213 void sensor_manager::restore(void)
215 ret_if(!is_connected());
217 m_connected.store(false);
218 retm_if(!connect_channel(), "Failed to restore manager");
220 _D("Restored manager");
223 void sensor_manager::decode_sensors(const char *buf, std::vector<sensor_info> &infos)
229 cmd_manager_sensor_list_t *raw;
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);
236 for (int i = 0; i < count; ++i) {
238 info.deserialize(data, size[0]);
239 infos.push_back(info);
241 size = (const size_t *)((const char *)data + size[0]);
242 data = (const char *)size + sizeof(size_t);
245 _D("Sensor count : %d", count);
248 bool sensor_manager::get_sensors_internal(void)
250 retvm_if(!is_connected(), false, "Failed to get sensors");
255 char buf[MAX_BUF_SIZE];
257 msg.set_type(CMD_MANAGER_SENSOR_LIST);
259 ret = m_channel->send_sync(&msg);
260 retvm_if(!ret, false, "Failed to send message");
262 ret = m_channel->read_sync(reply);
263 retvm_if(!ret, false, "Failed to receive message");
267 decode_sensors(buf, m_infos);
272 bool sensor_manager::has_privilege(std::string &uri)
274 retvm_if(!is_connected(), false, "Failed to get sensors");
279 cmd_has_privilege_t buf = {0, };
281 msg.set_type(CMD_HAS_PRIVILEGE);
282 memcpy(buf.sensor, uri.c_str(), uri.size());
283 msg.enclose((const char *)&buf, sizeof(buf));
285 ret = m_channel->send_sync(&msg);
286 retvm_if(!ret, false, "Failed to send message");
288 ret = m_channel->read_sync(reply);
289 retvm_if(!ret, false, "Failed to receive message");
291 if (reply.header()->err == OP_SUCCESS)
297 sensor_info *sensor_manager::get_info(const char *uri)
299 if (strncmp(uri, utils::get_uri(ALL_SENSOR), SIZE_STR_SENSOR_ALL) == 0)
302 for (auto it = m_infos.begin(); it != m_infos.end(); ++it) {
303 std::size_t found = (*it).get_uri().rfind(uri);
305 if (found == std::string::npos)
308 if ((*it).get_privilege().empty())
311 if (has_privilege((*it).get_uri()))
318 std::vector<sensor_info *> sensor_manager::get_infos(const char *uri)
320 std::vector<sensor_info *> infos;
323 if (strncmp(uri, utils::get_uri(ALL_SENSOR), SIZE_STR_SENSOR_ALL) == 0)
326 for (auto it = m_infos.begin(); it != m_infos.end(); ++it) {
327 std::size_t found = (*it).get_uri().rfind(uri);
329 if (!all && found == std::string::npos)
332 if ((*it).get_privilege().empty()) {
333 infos.push_back(&*it);
337 if (has_privilege((*it).get_uri()))
338 infos.push_back(&*it);