Use vector<char> to cache sensor_data_t in sensor_handler
[platform/core/system/sensord.git] / src / server / sensor_handler.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_handler.h"
21
22 #include <message.h>
23 #include <sensor_log.h>
24 #include <sensor_utils.h>
25 #include <sensor_types_private.h>
26 #include <command_types.h>
27 #include <sensor_listener_proxy.h>
28
29 using namespace sensor;
30
31 sensor_handler::sensor_handler(const sensor_info &info)
32 : m_info(info)
33 {
34         const char *priv = sensor::utils::get_privilege(m_info.get_uri());
35         m_info.set_privilege(priv);
36
37         sensor_type_t type = sensor::utils::get_type(m_info.get_uri());
38         m_info.set_type(type);
39
40         /* TODO: temporary walkaround for sensors that require multiple privileges */
41         switch (m_info.get_type()) {
42         case EXTERNAL_EXERCISE_SENSOR:
43         case EXERCISE_STANDALONE_SENSOR:
44                 m_info.add_privilege(PRIVILEGE_LOCATION_URI);
45                 break;
46         case GPS_CTRL_SENSOR:
47                 m_info.add_privilege(PRIVILEGE_PLATFORM_URI);
48                 break;
49         default:
50                 break;
51         }
52 }
53
54 bool sensor_handler::has_observer(sensor_observer *ob)
55 {
56         for (auto it = m_observers.begin(); it != m_observers.end(); ++it) {
57                 if ((*it) == ob)
58                         return true;
59         }
60
61         return false;
62 }
63
64 bool sensor_handler::add_observer(sensor_observer *ob)
65 {
66         retv_if(has_observer(ob), false);
67
68         m_observers.push_back(ob);
69         return true;
70 }
71
72 void sensor_handler::remove_observer(sensor_observer *ob)
73 {
74         m_observers.remove(ob);
75 }
76
77 int sensor_handler::notify(const char *uri, sensor_data_t *data, int len)
78 {
79         if (observer_count() == 0)
80                 return OP_ERROR;
81
82         auto msg = ipc::message::create((char *)data, len);
83
84         retvm_if(!msg, OP_ERROR, "Failed to allocate memory");
85
86         for (auto it = m_observers.begin(); it != m_observers.end(); ++it)
87                 (*it)->update(uri, msg);
88
89         set_cache(data, len);
90
91         return OP_SUCCESS;
92 }
93
94 uint32_t sensor_handler::observer_count(void)
95 {
96         return m_observers.size();
97 }
98
99 void sensor_handler::set_cache(sensor_data_t *data, int size)
100 {
101         char* p = (char*) data;
102
103         try {
104                 m_sensor_data_cache.reserve(size);
105         } catch (...) {
106                 _E("Memory allocation failed");
107                 return;
108         }
109         m_sensor_data_cache.clear();
110         m_sensor_data_cache.insert(m_sensor_data_cache.begin(), p, p + size);
111 }
112
113 int sensor_handler::get_cache(sensor_data_t **data, int *len)
114 {
115         auto size = m_sensor_data_cache.size();
116         retv_if(size == 0, -ENODATA);
117
118         char* temp = (char *)malloc(size);
119         retvm_if(temp == NULL, -ENOMEM, "Memory allocation failed");
120         std::copy(m_sensor_data_cache.begin(), m_sensor_data_cache.end(), temp);
121
122         *len = size;
123         *data = (sensor_data_t *)temp;
124
125         return 0;
126 }
127
128 bool sensor_handler::notify_attribute_changed(uint32_t id, int attribute, int value)
129 {
130         if (observer_count() == 0)
131                 return OP_ERROR;
132
133         cmd_listener_attr_int_t buf;
134         buf.listener_id = id;
135         buf.attribute = attribute;
136         buf.value = value;
137
138         auto msg = ipc::message::create();
139
140         retvm_if(!msg, OP_ERROR, "Failed to allocate memory");
141
142         msg->set_type(CMD_LISTENER_SET_ATTR_INT);
143         msg->enclose((char *)&buf, sizeof(buf));
144
145         sensor_listener_proxy *proxy = NULL;
146         for (auto it = m_observers.begin(); it != m_observers.end(); ++it) {
147                 proxy = dynamic_cast<sensor_listener_proxy *>(*it);
148                 if (proxy && proxy->get_id() != id) {
149                         proxy->on_attribute_changed(msg);
150                 }
151         }
152
153         return OP_SUCCESS;
154 }
155
156 bool sensor_handler::notify_attribute_changed(uint32_t id, int attribute, const char *value, int len)
157 {
158         if (observer_count() == 0)
159                 return OP_ERROR;
160
161         cmd_listener_attr_str_t *buf;
162         size_t size;
163         size = sizeof(cmd_listener_attr_str_t) + len;
164         buf = (cmd_listener_attr_str_t *) new(std::nothrow) char[size];
165         retvm_if(!buf, -ENOMEM, "Failed to allocate memory");
166
167         auto msg = ipc::message::create();
168         retvm_if(!msg, OP_ERROR, "Failed to allocate memory");
169
170         buf->listener_id = id;
171         buf->attribute = attribute;
172         memcpy(buf->value, value, len);
173         buf->len = len;
174
175         msg->set_type(CMD_LISTENER_SET_ATTR_STR);
176         msg->enclose((char *)buf, size);
177
178         _I("notify attribute changed by listener[%zu]\n", id);
179         sensor_listener_proxy *proxy = NULL;
180         for (auto it = m_observers.begin(); it != m_observers.end(); ++it) {
181                 proxy = dynamic_cast<sensor_listener_proxy *>(*it);
182                 if (proxy && proxy->get_id() != id) {
183                         proxy->on_attribute_changed(msg);
184                 }
185         }
186
187         delete[] buf;
188
189         return OP_SUCCESS;
190 }
191
192 int sensor_handler::delete_batch_latency(sensor_observer *ob)
193 {
194         return 0;
195 }
196
197 int sensor_handler::get_attribute(int32_t attr, int32_t* value)
198 {
199         auto it = m_attributes_int.find(attr);
200         retv_if(it == m_attributes_int.end(), OP_ERROR);
201
202         *value = it->second;
203         return OP_SUCCESS;
204 }
205
206 void sensor_handler::update_attribute(int32_t attr, int32_t value)
207 {
208         m_attributes_int[attr] = value;
209         _I("[%s] attributes(int) size : %d", m_info.get_uri().c_str(), m_attributes_int.size());
210 }
211
212 int sensor_handler::get_attribute(int32_t attr, char **value, int *len)
213 {
214         auto it = m_attributes_str.find(attr);
215         retv_if(it == m_attributes_str.end(), OP_ERROR);
216
217         *len = it->second.size();
218         *value = new(std::nothrow) char[*len];
219         std::copy(it->second.begin(), it->second.end(), *value);
220
221         return OP_SUCCESS;
222 }
223
224 void sensor_handler::update_attribute(int32_t attr, const char *value, int len)
225 {
226         m_attributes_str[attr].clear();
227         m_attributes_str[attr].insert(m_attributes_str[attr].begin(), value, value + len);
228         _I("[%s] attributes(int) size : %d", m_info.get_uri().c_str(), m_attributes_int.size());
229
230 }