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-provider.h"
25 #include <sensor-log-private.h>
26 #include <sensor-types-private.h>
27 #include <sensor-utils.h>
28 #include <command-types.h>
34 #define DEFAULT_RESOLUTION 0.1
36 using namespace sensor;
38 static gboolean provider_handler(GIOChannel *ch, GIOCondition condition, gpointer data)
40 sensor_provider *p = (sensor_provider*) data;
41 unsigned int cond = (unsigned int)condition;
43 if (cond & (G_IO_HUP)) {
49 bool ret = p->read(msg);
58 sensor_provider::sensor_provider(const char *uri)
62 , m_interval_changed_cb(NULL)
63 , m_attribute_str_cb(NULL)
64 , m_start_user_data(NULL)
65 , m_stop_user_data(NULL)
66 , m_interval_changed_user_data(NULL)
67 , m_attribute_str_user_data(NULL)
71 m_loop = g_main_loop_new(NULL, FALSE);
74 sensor_provider::~sensor_provider()
79 g_main_loop_quit(m_loop);
80 g_main_loop_unref(m_loop);
85 bool sensor_provider::init(const char *uri)
87 m_sensor.set_uri(uri);
88 m_sensor.set_min_range(-FLT_MAX);
89 m_sensor.set_max_range(FLT_MAX);
90 m_sensor.set_resolution(DEFAULT_RESOLUTION);
91 /* TODO: temporary walkaround */
92 const char *priv = sensor::utils::get_privilege(uri);
93 m_sensor.set_privilege(priv);
98 void sensor_provider::deinit(void)
103 const char *sensor_provider::get_uri(void)
105 return m_sensor.get_uri().c_str();
108 sensor_info *sensor_provider::get_sensor_info(void)
113 int sensor_provider::serialize(sensor_info *info, char **bytes)
116 raw_data_t *raw = new(std::nothrow) raw_data_t;
117 retvm_if(!raw, -ENOMEM, "Failed to allocated memory");
119 info->serialize(*raw);
121 *bytes = (char *) malloc(raw->size());
125 _E("Failed to allocate memory");
129 std::copy(raw->begin(), raw->end(), *bytes);
137 int sensor_provider::send_sensor_info(sensor_info *info)
142 size = serialize(info, &bytes);
146 ipc::message msg((const char *)bytes, size);
147 msg.set_type(CMD_PROVIDER_CONNECT);
149 bool ret = send(msg);
155 int sensor_provider::connect(void)
157 m_socket = new(std::nothrow) ipc::socket();
158 retvm_if(!m_socket, NULL, "Failed to allocate memory");
160 if (!m_socket->create(SENSOR_CHANNEL_PATH)) {
165 if (!m_socket->connect())
168 GIOChannel *ch = NULL;
170 ch = g_io_channel_unix_new(m_socket->get_fd());
171 retvm_if(!ch, NULL, "Failed to create g_io_channel_unix_new");
173 g_src = g_io_create_watch(ch, (GIOCondition) (ipc::EVENT_IN | ipc::EVENT_HUP | ipc::EVENT_NVAL));
174 g_io_channel_unref(ch);
176 _E("Failed to create g_io_create_watch");
180 g_source_set_callback(g_src, (GSourceFunc) provider_handler, this, NULL);
181 g_source_attach(g_src, g_main_loop_get_context(m_loop));
182 g_source_unref(g_src);
184 /* serialize and send sensor info */
185 send_sensor_info(get_sensor_info());
190 bool ret = read(reply);
193 retv_if(reply.header()->err < 0, reply.header()->err);
195 m_connected.store(true);
197 _I("Provider URI[%s]", get_uri());
202 bool sensor_provider::disconnect(void)
205 retv_if(!is_connected(), false);
207 if (g_src && !g_source_is_destroyed(g_src)) {
208 g_source_destroy(g_src);
212 m_connected.store(false);
216 _I("Disconnected[%s]", get_uri());
220 bool sensor_provider::restore(void)
222 retv_if(!is_connected(), false);
223 retvm_if(connect(), false, "Failed to restore provider");
225 _D("Restored provider[%s]", get_uri());
229 int sensor_provider::publish(const sensor_data_t &data)
232 msg.set_type(CMD_PROVIDER_PUBLISH);
233 msg.enclose((const void *)(&data), sizeof(data));
235 bool ret = send(msg);
242 int sensor_provider::publish(const sensor_data_t data[], const int count)
245 msg.set_type(CMD_PROVIDER_PUBLISH);
246 msg.enclose((const void *)data, sizeof(sensor_data_t) * count);
253 bool sensor_provider::is_connected(void)
255 return m_connected.load();
258 void sensor_provider::set_start_cb(sensord_provider_start_cb cb, void *user_data)
261 m_start_user_data = user_data;
264 void sensor_provider::set_stop_cb(sensord_provider_stop_cb cb, void *user_data)
267 m_stop_user_data = user_data;
270 void sensor_provider::set_interval_cb(sensord_provider_interval_changed_cb cb, void *user_data)
272 m_interval_changed_cb = cb;
273 m_interval_changed_user_data = user_data;
276 void sensor_provider::set_attribute_str_cb(sensord_provider_attribute_str_cb cb, void *user_data)
278 m_attribute_str_cb = cb;
279 m_attribute_str_user_data = user_data;
282 bool sensor_provider::read(ipc::message &msg)
286 _E("Socket is not connected");
290 ipc::message_header header;
292 char buf[MAX_MSG_CAPACITY];
295 size = m_socket->recv(&header, sizeof(ipc::message_header), false);
299 // check error from header
300 if (header.err != 0) {
301 msg.header()->err = header.err;
306 if (header.length >= MAX_MSG_CAPACITY) {
307 _E("header.length error %u", header.length);
311 if (header.length > 0) {
312 size = m_socket->recv(&buf, header.length, false);
317 buf[header.length] = '\0';
318 msg.enclose(reinterpret_cast<const void *>(buf), header.length);
319 msg.set_type(header.type);
320 msg.header()->err = header.err;
325 void sensor_provider::handle(ipc::message &msg)
327 switch (msg.type()) {
328 case CMD_PROVIDER_START:
330 m_start_cb(this, m_start_user_data);
332 case CMD_PROVIDER_STOP:
334 m_stop_cb(this, m_stop_user_data);
336 case CMD_PROVIDER_ATTR_INT:
337 cmd_provider_attr_int_t buf;
338 msg.disclose((char *)&buf, sizeof(buf));
340 if (buf.attribute == SENSORD_ATTRIBUTE_INTERVAL && m_interval_changed_cb)
341 m_interval_changed_cb(this, buf.value, m_interval_changed_user_data);
343 case CMD_PROVIDER_ATTR_STR:
344 cmd_provider_attr_str_t *attr;
346 attr = (cmd_provider_attr_str_t *) new(std::nothrow) char[msg.size()];
347 retm_if(!attr, "Failed to allocate memory");
349 msg.disclose((char *)attr, msg.size());
351 if (m_attribute_str_cb)
352 m_attribute_str_cb(this, attr->attribute, attr->value, attr->len, m_attribute_str_user_data);
359 bool sensor_provider::send(ipc::message &msg)
363 _E("Socket is not connected");
367 retvm_if(msg.size() >= MAX_MSG_CAPACITY, true, "Invaild message size[%u]", msg.size());
370 char *buf = msg.body();
373 size = m_socket->send(reinterpret_cast<void *>(msg.header()),
374 sizeof(ipc::message_header), true);
375 retvm_if(size <= 0, false, "Failed to send header");
377 /* if body size is zero, skip to send body message */
378 retv_if(msg.size() == 0, true);
381 size = m_socket->send(buf, msg.size(), true);
382 retvm_if(size <= 0, false, "Failed to send body");