Add sensor handle attribute
[platform/core/system/sensord.git] / src / server / server_channel_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 "server_channel_handler.h"
21
22 #include <sensor_log.h>
23 #include <sensor_info.h>
24 #include <sensor_handler.h>
25 #include <sensor_utils.h>
26 #include <sensor_types_private.h>
27 #include <command_types.h>
28 #include <event_loop.h>
29
30 #include "permission_checker.h"
31 #include "application_sensor_handler.h"
32
33 #define CONVERT_ATTR_TYPE(attr) ((attr) >> 8)
34
35 using namespace sensor;
36 using namespace ipc;
37
38 /* TODO */
39 std::unordered_map<uint32_t, sensor_listener_proxy *> server_channel_handler::m_listeners;
40 std::unordered_map<ipc::channel *, uint32_t> server_channel_handler::m_listener_ids;
41 std::unordered_map<ipc::channel *, application_sensor_handler *> server_channel_handler::m_app_sensors;
42
43 server_channel_handler::server_channel_handler(sensor_manager *manager)
44 : m_manager(manager)
45 {
46         _I("Create[%p]", this);
47 }
48
49 server_channel_handler::~server_channel_handler()
50 {
51         _I("Destroy[%p]", this);
52 }
53
54 void server_channel_handler::connected(channel *ch)
55 {
56 }
57
58 void server_channel_handler::disconnected(channel *ch)
59 {
60         _I("Disconnect[%p] using channel[%p]", this, ch);
61         m_manager->deregister_channel(ch);
62
63         auto it_asensor = m_app_sensors.find(ch);
64         if (it_asensor != m_app_sensors.end()) {
65                 sensor_info info = it_asensor->second->get_sensor_info();
66
67                 _I("Disconnected provider[%s]", info.get_uri().c_str());
68
69                 m_manager->deregister_sensor(info.get_uri());
70                 m_app_sensors.erase(ch);
71         }
72
73         auto it_listener = m_listener_ids.find(ch);
74         if (it_listener != m_listener_ids.end()) {
75                 _I("Disconnected listener[%u]", it_listener->second);
76
77                 delete m_listeners[it_listener->second];
78                 m_listeners.erase(it_listener->second);
79                 m_listener_ids.erase(ch);
80         }
81
82         if (!ch->loop())
83                 _D("Should not be here : channel[%p]", ch);
84 }
85
86 void server_channel_handler::read(channel *ch, message &msg)
87 {
88         int err = -EINVAL;
89
90         switch (msg.type()) {
91         case CMD_MANAGER_CONNECT:
92                 err = manager_connect(ch, msg); break;
93         case CMD_MANAGER_SENSOR_LIST:
94                 err = manager_get_sensor_list(ch, msg); break;
95         case CMD_MANAGER_SET_ATTR_INT:
96                 err = manager_set_attr_int(ch, msg); break;
97         case CMD_MANAGER_GET_ATTR_INT:
98                 err = manager_get_attr_int(ch, msg); break;
99         case CMD_LISTENER_CONNECT:
100                 err = listener_connect(ch, msg); break;
101         case CMD_LISTENER_START:
102                 err = listener_start(ch, msg); break;
103         case CMD_LISTENER_STOP:
104                 err = listener_stop(ch, msg); break;
105         case CMD_LISTENER_SET_ATTR_INT:
106                 err = listener_set_attr_int(ch, msg); break;
107         case CMD_LISTENER_SET_ATTR_STR:
108                 err = listener_set_attr_str(ch, msg); break;
109         case CMD_LISTENER_GET_DATA:
110                 err = listener_get_data(ch, msg); break;
111         case CMD_LISTENER_GET_ATTR_INT:
112                 err = listener_get_attr_int(ch, msg); break;
113         case CMD_LISTENER_GET_ATTR_STR:
114                 err = listener_get_attr_str(ch, msg); break;
115         case CMD_LISTENER_GET_DATA_LIST:
116                 err = listener_get_data_list(ch, msg); break;
117         case CMD_PROVIDER_CONNECT:
118                 err = provider_connect(ch, msg); break;
119         case CMD_PROVIDER_PUBLISH:
120                 err = provider_publish(ch, msg); break;
121         case CMD_HAS_PRIVILEGE:
122                 err = has_privileges(ch, msg); break;
123         default: break;
124         }
125
126         if (err != 0) {
127                 message reply(err);
128                 ch->send_sync(reply);
129         }
130 }
131
132 int server_channel_handler::manager_connect(channel *ch, message &msg)
133 {
134         m_manager->register_channel(ch);
135         return OP_SUCCESS;
136 }
137
138 int server_channel_handler::manager_get_sensor_list(channel *ch, message &msg)
139 {
140         ipc::message reply;
141         char *bytes;
142         int size;
143
144         size = m_manager->serialize(ch->get_fd(), &bytes);
145         retv_if(size < 0, size);
146
147         reply.enclose((const char *)bytes, size);
148         reply.header()->err = OP_SUCCESS;
149         ch->send_sync(reply);
150
151         delete [] bytes;
152
153         return OP_SUCCESS;
154 }
155
156 int server_channel_handler::manager_preprocess_attr(channel *ch, cmd_manager_attr_int_t &buf, sensor_handler **sensor)
157 {
158         if (!ch || !sensor)
159                 return -EINVAL;
160
161         sensor_handler *find_sensor = m_manager->get_sensor(buf.sensor);
162         if (!find_sensor) {
163                 _E("Failed to find sensor");
164                 return OP_ERROR;
165         }
166
167         sensor_info info = find_sensor->get_sensor_info();
168         sensor_type_t type = (sensor_type_t) CONVERT_ATTR_TYPE(buf.attribute);
169         if (type != info.get_type()) {
170                 _E("Invalid attribute with sensor type");
171                 return -EINVAL;
172         }
173
174         std::string privilege = info.get_privilege();
175         int ret = has_privileges(ch->get_fd(), privilege);
176         if (!ret) {
177                 _E("Permission denied[%s]", privilege.c_str());
178                 return -EPERM;
179         }
180         *sensor = find_sensor;
181
182         return OP_SUCCESS;
183 }
184
185 int server_channel_handler::manager_set_attr_int(channel *ch, message &msg)
186 {
187         cmd_manager_attr_int_t buf;
188         msg.disclose((char *)&buf, sizeof(buf));
189
190         sensor_handler *sensor;
191         int ret = manager_preprocess_attr(ch, buf, &sensor);
192         if (ret < 0)
193                 return ret;
194
195         ret = sensor->set_attribute(NULL, buf.attribute, buf.value);
196         if (ret < 0) {
197                 _E("Failed to set attribute");
198                 return ret;
199         }
200
201         return send_reply(ch, OP_SUCCESS);
202 }
203
204 int server_channel_handler::manager_get_attr_int(channel *ch, message &msg)
205 {
206         cmd_manager_attr_int_t buf;
207         msg.disclose((char *)&buf, sizeof(buf));
208
209         sensor_handler *sensor;
210         int ret = manager_preprocess_attr(ch, buf, &sensor);
211         if (ret < 0)
212                 return ret;
213
214         int value;
215         ret = sensor->get_attribute(buf.attribute, &value);
216         if (ret < 0) {
217                 _E("Failed to get attribute");
218                 return ret;
219         }
220
221         message reply;
222         cmd_manager_attr_int_t ret_buf;
223
224         ret_buf.attribute = buf.attribute;
225         ret_buf.value = value;
226
227         reply.enclose((char *)&ret_buf, sizeof(ret_buf));
228         reply.header()->err = OP_SUCCESS;
229         reply.set_type(CMD_MANAGER_GET_ATTR_INT);
230         ret = ch->send_sync(reply);
231         if (!ret)
232                 return OP_ERROR;
233
234         return OP_SUCCESS;
235 }
236
237 int server_channel_handler::listener_connect(channel *ch, message &msg)
238 {
239         static uint32_t listener_id = 1;
240         cmd_listener_connect_t buf;
241
242         msg.disclose((char *)&buf, sizeof(buf));
243
244         sensor_listener_proxy *listener;
245         listener = new(std::nothrow) sensor_listener_proxy(listener_id,
246                                 buf.sensor, m_manager, ch);
247         retvm_if(!listener, OP_ERROR, "Failed to allocate memory");
248         retvm_if(!has_privileges(ch->get_fd(), listener->get_required_privileges()),
249                         -EACCES, "Permission denied[%d, %s]",
250                         listener_id, m_listeners[listener_id]->get_required_privileges().c_str());
251
252         buf.listener_id = listener_id;
253
254         message reply;
255         reply.set_type(CMD_LISTENER_CONNECTED);
256         reply.enclose((const char *)&buf, sizeof(buf));
257         reply.header()->err = OP_SUCCESS;
258
259         if (!ch->send_sync(reply))
260                 return OP_ERROR;
261
262         _I("Connected sensor_listener[fd(%d) -> id(%u)]", ch->get_fd(), listener_id);
263         m_listeners[listener_id] = listener;
264         m_listener_ids[ch] = listener_id;
265         listener_id++;
266
267         return OP_SUCCESS;
268 }
269
270 int server_channel_handler::listener_start(channel *ch, message &msg)
271 {
272         cmd_listener_start_t buf;
273         msg.disclose((char *)&buf, sizeof(buf));
274         uint32_t id = buf.listener_id;
275
276         auto it = m_listeners.find(id);
277         retv_if(it == m_listeners.end(), -EINVAL);
278         retvm_if(!has_privileges(ch->get_fd(), m_listeners[id]->get_required_privileges()),
279                         -EACCES, "Permission denied[%d, %s]",
280                         id, m_listeners[id]->get_required_privileges().c_str());
281
282         int ret = m_listeners[id]->start();
283         retvm_if(ret < 0, ret, "Failed to start listener[%d]", id);
284
285         return send_reply(ch, OP_SUCCESS);
286 }
287
288 int server_channel_handler::listener_stop(channel *ch, message &msg)
289 {
290         cmd_listener_stop_t buf;
291         msg.disclose((char *)&buf, sizeof(buf));
292         uint32_t id = buf.listener_id;
293
294         auto it = m_listeners.find(id);
295         retv_if(it == m_listeners.end(), -EINVAL);
296         retvm_if(!has_privileges(ch->get_fd(), m_listeners[id]->get_required_privileges()),
297                         -EACCES, "Permission denied[%d, %s]",
298                         id, m_listeners[id]->get_required_privileges().c_str());
299
300         int ret = m_listeners[id]->stop();
301         retvm_if(ret < 0, ret, "Failed to stop listener[%d]", id);
302
303         return send_reply(ch, OP_SUCCESS);
304 }
305
306 int server_channel_handler::listener_set_attr_int(channel *ch, message &msg)
307 {
308         cmd_listener_attr_int_t buf;
309         msg.disclose((char *)&buf, sizeof(buf));
310         uint32_t id = buf.listener_id;
311
312         int ret = OP_SUCCESS;
313
314         auto it = m_listeners.find(id);
315         retv_if(it == m_listeners.end(), -EINVAL);
316         retvm_if(!has_privileges(ch->get_fd(), m_listeners[id]->get_required_privileges()),
317                         -EACCES, "Permission denied[%d, %s]",
318                         id, m_listeners[id]->get_required_privileges().c_str());
319
320         switch (buf.attribute) {
321         case SENSORD_ATTRIBUTE_INTERVAL:
322                 ret = m_listeners[id]->set_interval(buf.value); break;
323         case SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY:
324                 ret = m_listeners[id]->set_max_batch_latency(buf.value); break;
325         case SENSORD_ATTRIBUTE_PASSIVE_MODE:
326                 ret = m_listeners[id]->set_passive_mode(buf.value); break;
327         case SENSORD_ATTRIBUTE_PAUSE_POLICY:
328         case SENSORD_ATTRIBUTE_AXIS_ORIENTATION:
329         default:
330                 ret = m_listeners[id]->set_attribute(buf.attribute, buf.value);
331         }
332         /* TODO : check return value */
333         if (ret < 0)
334                 _D("Return : %d", ret);
335
336         ret = send_reply(ch, OP_SUCCESS);
337
338         if (m_listeners[id]->need_to_notify_attribute_changed()) {
339                 m_listeners[id]->notify_attribute_changed(buf.attribute, buf.value);
340                 m_listeners[id]->set_need_to_notify_attribute_changed(false);
341         }
342
343         return ret;
344 }
345
346 int server_channel_handler::listener_set_attr_str(channel *ch, message &msg)
347 {
348         uint32_t id;
349         cmd_listener_attr_str_t *buf;
350
351         buf = (cmd_listener_attr_str_t *) new(std::nothrow) char[msg.size()];
352         retvm_if(!buf, -ENOMEM, "Failed to allocate memory");
353
354         msg.disclose((char *)buf, msg.size());
355
356         id = buf->listener_id;
357         auto it = m_listeners.find(id);
358         if (it == m_listeners.end()) {
359                 delete [] buf;
360                 return -EINVAL;
361         }
362
363         if (!has_privileges(ch->get_fd(), m_listeners[id]->get_required_privileges())) {
364                 _E("Permission denied[%d, %s]", id, m_listeners[id]->get_required_privileges().c_str());
365                 delete [] buf;
366                 return -EACCES;
367         }
368
369         int ret = m_listeners[id]->set_attribute(buf->attribute, buf->value, buf->len);
370         if (ret < 0) {
371                 delete [] buf;
372                 return ret;
373         }
374
375         ret = send_reply(ch, OP_SUCCESS);
376
377         if (m_listeners[id]->need_to_notify_attribute_changed()) {
378                 m_listeners[id]->notify_attribute_changed(buf->attribute, buf->value, buf->len);
379                 m_listeners[id]->set_need_to_notify_attribute_changed(false);
380         }
381
382         delete [] buf;
383         return ret;
384 }
385
386 int server_channel_handler::listener_get_attr_int(ipc::channel *ch, ipc::message &msg)
387 {
388         cmd_listener_attr_int_t buf;
389         msg.disclose((char *)&buf, sizeof(buf));
390         uint32_t id = buf.listener_id;
391         int attr = buf.attribute;
392         int value = 0;
393         int ret = OP_SUCCESS;
394
395         auto it = m_listeners.find(id);
396         retv_if(it == m_listeners.end(), -EINVAL);
397         retvm_if(!has_privileges(ch->get_fd(), m_listeners[id]->get_required_privileges()),
398                         -EACCES, "Permission denied[%d, %s]",
399                         id, m_listeners[id]->get_required_privileges().c_str());
400
401         switch (attr) {
402         case SENSORD_ATTRIBUTE_INTERVAL:
403                 ret = m_listeners[id]->get_interval(value); break;
404         case SENSORD_ATTRIBUTE_MAX_BATCH_LATENCY:
405                 ret = m_listeners[id]->get_max_batch_latency(value); break;
406         case SENSORD_ATTRIBUTE_PASSIVE_MODE:
407                 // TODO : Are these features required?
408                 ret = OP_ERROR;
409                 break;
410         case SENSORD_ATTRIBUTE_PAUSE_POLICY:
411         case SENSORD_ATTRIBUTE_AXIS_ORIENTATION:
412         default:
413                 ret = m_listeners[id]->get_attribute(attr, &value);
414         }
415
416         if (ret != OP_SUCCESS) {
417                 _E("Failed to listener_get_attr_int");
418                 return ret;
419         }
420         message reply;
421         cmd_listener_attr_int_t ret_buf;
422
423         ret_buf.listener_id = id;
424         ret_buf.attribute = attr;
425         ret_buf.value = value;
426
427         reply.enclose((char *)&ret_buf, sizeof(ret_buf));
428         reply.header()->err = OP_SUCCESS;
429         reply.set_type(CMD_LISTENER_GET_ATTR_INT);
430         ret = ch->send_sync(reply);
431
432         return OP_SUCCESS;
433 }
434
435 int server_channel_handler::listener_get_attr_str(ipc::channel *ch, ipc::message &msg)
436 {
437         uint32_t id;
438         cmd_listener_attr_str_t *buf;
439
440         buf = (cmd_listener_attr_str_t *) new(std::nothrow) char[msg.size()];
441         retvm_if(!buf, -ENOMEM, "Failed to allocate memory");
442
443         msg.disclose((char *)buf, msg.size());
444
445         id = buf->listener_id;
446         auto it = m_listeners.find(id);
447         auto attr = buf->attribute;
448         delete [] buf;
449
450         if (it == m_listeners.end()) {
451                 return -EINVAL;
452         }
453
454         if (!has_privileges(ch->get_fd(), m_listeners[id]->get_required_privileges())) {
455                 _E("Permission denied[%d, %s]", id, m_listeners[id]->get_required_privileges().c_str());
456                 return -EACCES;
457         }
458
459         char *value = NULL;
460         int len = 0;
461         int ret = m_listeners[id]->get_attribute(attr, &value, &len);
462
463         if (ret != OP_SUCCESS) {
464                 _E("Failed to listener_get_attr_str");
465                 return ret;
466         }
467
468         cmd_listener_attr_str_t *reply_buf;
469         size_t size = sizeof(cmd_listener_attr_str_t) + len;
470         reply_buf = (cmd_listener_attr_str_t *) new(std::nothrow) char[size];
471         retvm_if(!reply_buf, -ENOMEM, "Failed to allocate memory");
472
473         reply_buf->attribute = attr;
474         memcpy(reply_buf->value, value, len);
475         reply_buf->len = len;
476         delete [] value;
477
478         ipc::message reply;
479         reply.enclose((char *)reply_buf, size);
480         reply.set_type(CMD_LISTENER_GET_ATTR_STR);
481
482         ret = ch->send_sync(reply);
483         delete [] reply_buf;
484
485         return OP_SUCCESS;
486 }
487
488 int server_channel_handler::listener_get_data(channel *ch, message &msg)
489 {
490         ipc::message reply;
491         cmd_listener_get_data_t buf;
492         sensor_data_t *data;
493         int len;
494         uint32_t id;
495
496         msg.disclose((char *)&buf, sizeof(buf));
497         id = buf.listener_id;
498
499         auto it = m_listeners.find(id);
500         retv_if(it == m_listeners.end(), -EINVAL);
501         retvm_if(!has_privileges(ch->get_fd(), m_listeners[id]->get_required_privileges()),
502                         -EACCES, "Permission denied[%d, %s]",
503                         id, m_listeners[id]->get_required_privileges().c_str());
504
505         int ret = m_listeners[id]->get_data(&data, &len);
506         retv_if(ret < 0, ret);
507
508         memcpy(&buf.data, data, sizeof(sensor_data_t));
509         buf.len = sizeof(sensor_data_t);
510
511         reply.enclose((const char *)&buf, sizeof(cmd_listener_get_data_t));
512         reply.header()->err = OP_SUCCESS;
513         reply.header()->type = CMD_LISTENER_GET_DATA;
514
515         ch->send_sync(reply);
516
517         free(data);
518
519         return OP_SUCCESS;
520 }
521
522 int server_channel_handler::listener_get_data_list(ipc::channel *ch, ipc::message &msg)
523 {
524         ipc::message reply;
525         cmd_listener_get_data_list_t buf;
526         sensor_data_t *data;
527         int len;
528         uint32_t id;
529
530         msg.disclose((char *)&buf, sizeof(buf));
531         id = buf.listener_id;
532
533         auto it = m_listeners.find(id);
534         retv_if(it == m_listeners.end(), -EINVAL);
535         retvm_if(!has_privileges(ch->get_fd(), m_listeners[id]->get_required_privileges()),
536                         -EACCES, "Permission denied[%d, %s]",
537                         id, m_listeners[id]->get_required_privileges().c_str());
538
539         int ret = m_listeners[id]->get_data(&data, &len);
540         retv_if(ret < 0, ret);
541
542         size_t reply_size = sizeof(cmd_listener_get_data_list_t) + len;
543         cmd_listener_get_data_list_t* reply_buf = (cmd_listener_get_data_list_t *) malloc(reply_size);
544         if (!reply_buf) {
545                 _E("Failed to allocate memory");
546                 free(data);
547                 return -ENOMEM;
548         }
549
550         memcpy(reply_buf->data, data, len);
551         reply_buf->len = len;
552         reply_buf->data_count = len / sizeof(sensor_data_t);
553         reply.enclose((const char *)reply_buf, reply_size);
554         reply.header()->err = OP_SUCCESS;
555         reply.header()->type = CMD_LISTENER_GET_DATA_LIST;
556
557         ch->send_sync(reply);
558
559         free(data);
560         free(reply_buf);
561
562         return OP_SUCCESS;
563
564 }
565
566 int server_channel_handler::provider_connect(channel *ch, message &msg)
567 {
568         sensor_info info;
569         info.clear();
570         info.deserialize(msg.body(), msg.size());
571
572         info.show();
573
574         application_sensor_handler *sensor;
575         sensor = new(std::nothrow) application_sensor_handler(info, ch);
576         retvm_if(!sensor, -ENOMEM, "Failed to allocate memory");
577
578         if (!m_manager->register_sensor(sensor)) {
579                 delete sensor;
580                 return -EINVAL;
581         }
582
583         /* temporarily */
584         m_app_sensors[ch] = sensor;
585
586         return send_reply(ch, OP_SUCCESS);
587 }
588
589 int server_channel_handler::provider_publish(channel *ch, message &msg)
590 {
591         auto it = m_app_sensors.find(ch);
592         retv_if(it == m_app_sensors.end(), -EINVAL);
593
594         size_t size = msg.header()->length;
595         void *data = (void *)malloc(size);
596         retvm_if(!data, -ENOMEM, "Failed to allocate memory");
597
598         msg.disclose(data, size);
599
600         it->second->publish((sensor_data_t*)data, size);
601         return OP_SUCCESS;
602 }
603
604 int server_channel_handler::has_privileges(channel *ch, message &msg)
605 {
606         sensor_handler *sensor;
607         cmd_has_privilege_t buf;
608         msg.disclose((char *)&buf, sizeof(buf));
609
610         sensor = m_manager->get_sensor(buf.sensor);
611         retv_if(!sensor, OP_ERROR);
612
613         sensor_info info = sensor->get_sensor_info();
614
615         if (!has_privileges(ch->get_fd(), info.get_privilege()))
616                 return OP_ERROR;
617
618         return send_reply(ch, OP_SUCCESS);
619 }
620
621 int server_channel_handler::send_reply(channel *ch, int error)
622 {
623         message reply(error);
624         retvm_if(!ch->send_sync(reply), OP_ERROR, "Failed to send reply");
625         return OP_SUCCESS;
626 }
627
628 bool server_channel_handler::has_privilege(int fd, std::string &priv)
629 {
630         static permission_checker checker;
631         return checker.has_permission(fd, priv);
632 }
633
634 bool server_channel_handler::has_privileges(int fd, std::string priv)
635 {
636         std::vector<std::string> privileges;
637         privileges = utils::tokenize(priv, PRIV_DELIMITER);
638
639         for (auto it = privileges.begin(); it != privileges.end(); ++it) {
640                 if (!has_privilege(fd, *it))
641                         return false;
642         }
643
644         return true;
645 }