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