sensord: check the range of values provided from the client
[platform/core/system/sensord.git] / src / client / sensor_provider.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_provider.h"
21
22 #include <message.h>
23 #include <channel.h>
24 #include <sensor_log.h>
25 #include <sensor_types.h>
26 #include <sensor_utils.h>
27 #include <ipc_client.h>
28 #include <command_types.h>
29 #include <cfloat>
30
31 #include "sensor_provider_channel_handler.h"
32
33 #define DEFAULT_RESOLUTION 0.1
34
35 using namespace sensor;
36
37 sensor_provider::sensor_provider(const char *uri)
38 : m_client(NULL)
39 , m_channel(NULL)
40 , m_handler(NULL)
41 , m_connected(false)
42 {
43         init(uri);
44 }
45
46 sensor_provider::~sensor_provider()
47 {
48         deinit();
49 }
50
51 bool sensor_provider::init(const char *uri)
52 {
53         m_client = new(std::nothrow) ipc::ipc_client(SENSOR_CHANNEL_PATH);
54         retvm_if(!m_client, false, "Failed to allocate memory");
55
56         m_handler = new(std::nothrow) channel_handler(this);
57         if (!m_handler) {
58                 delete m_client;
59                 return false;
60         }
61
62         m_sensor.set_uri(uri);
63         m_sensor.set_min_range(-FLT_MAX);
64         m_sensor.set_max_range(FLT_MAX);
65         m_sensor.set_resolution(DEFAULT_RESOLUTION);
66         /* TODO: temporary walkaround */
67         const char *priv = sensor::utils::get_privilege(uri);
68         m_sensor.set_privilege(priv);
69
70         return true;
71 }
72
73 void sensor_provider::deinit(void)
74 {
75         disconnect();
76
77         delete m_handler;
78         m_handler = NULL;
79
80         delete m_client;
81         m_client = NULL;
82 }
83
84 const char *sensor_provider::get_uri(void)
85 {
86         return m_sensor.get_uri().c_str();
87 }
88
89 sensor_info *sensor_provider::get_sensor_info(void)
90 {
91         return &m_sensor;
92 }
93
94 int sensor_provider::serialize(sensor_info *info, char **bytes)
95 {
96         int size;
97         raw_data_t *raw = new(std::nothrow) raw_data_t;
98         retvm_if(!raw, -ENOMEM, "Failed to allocated memory");
99
100         info->serialize(*raw);
101
102         *bytes = new(std::nothrow) char[raw->size()];
103         retvm_if(!*bytes, -ENOMEM, "Failed to allocate memory");
104
105         std::copy(raw->begin(), raw->end(), *bytes);
106
107         size = raw->size();
108         delete raw;
109
110         return size;
111 }
112
113 int sensor_provider::send_sensor_info(sensor_info *info)
114 {
115         char *bytes;
116         int size;
117
118         size = serialize(info, &bytes);
119
120         ipc::message msg((const char *)bytes, size);
121         msg.set_type(CMD_PROVIDER_CONNECT);
122
123         m_channel->send_sync(&msg);
124
125         return OP_SUCCESS;
126 }
127
128 int sensor_provider::connect(void)
129 {
130         m_channel = m_client->connect(m_handler, &m_loop);
131         retvm_if(!m_channel, -EIO, "Failed to connect to server");
132
133         /* serialize and send sensor info */
134         send_sensor_info(get_sensor_info());
135
136         /* check error */
137         ipc::message reply;
138         m_channel->read_sync(reply);
139         retv_if(reply.header()->err < 0, reply.header()->err);
140
141         m_connected.store(true);
142
143         _I("Provider URI[%s]", get_uri());
144
145         return OP_SUCCESS;
146 }
147
148 bool sensor_provider::disconnect(void)
149 {
150         retv_if(!is_connected(), false);
151         m_connected.store(false);
152
153         m_channel->disconnect();
154         delete m_channel;
155         m_channel = NULL;
156
157         _I("Disconnected[%s]", get_uri());
158
159         return true;
160 }
161
162 void sensor_provider::restore(void)
163 {
164         ret_if(!is_connected());
165         retm_if(!connect(), "Failed to restore provider");
166
167         _D("Restored provider[%s]", get_uri());
168 }
169
170 int sensor_provider::publish(sensor_data_t *data, int len)
171 {
172         for (int i = 0; i < data->value_count; ++i) {
173                 if (data->values[i] < m_sensor.get_min_range() ||
174                     data->values[i] > m_sensor.get_max_range()) {
175                         _E("Out of range");
176                         return OP_ERROR;
177                 }
178         }
179
180         ipc::message msg;
181         msg.set_type(CMD_PROVIDER_PUBLISH);
182         msg.enclose((const char *)data, len);
183
184         m_channel->send_sync(&msg);
185
186         return OP_SUCCESS;
187 }
188
189 bool sensor_provider::is_connected(void)
190 {
191         return m_connected.load();
192 }
193
194 void sensor_provider::set_start_cb(sensord_provider_start_cb cb, void *user_data)
195 {
196         m_handler->set_start_cb(cb, user_data);
197 }
198
199 void sensor_provider::set_stop_cb(sensord_provider_stop_cb cb, void *user_data)
200 {
201         m_handler->set_stop_cb(cb, user_data);
202 }
203
204 void sensor_provider::set_interval_cb(sensord_provider_interval_changed_cb cb, void *user_data)
205 {
206         m_handler->set_interval_cb(cb, user_data);
207 }
208