4 * Copyright (c) 2014 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_common.h>
21 #include <command_common.h>
22 #include <sensor_loader.h>
23 #include <sensor_info.h>
24 #include <sensor_log.h>
29 #include <permission_checker.h>
30 #include <command_worker.h>
32 #define WAIT_TIME(X) ((1 << ((X) < 4 ? (X) : 4)) * 10000) /* 20, 40, 80, 160, 160ms, ... */
38 command_worker::cmd_handler_t command_worker::m_cmd_handlers[];
39 sensor_raw_data_map command_worker::m_sensor_raw_data_map;
40 cpacket command_worker::m_sensor_list;
41 cmutex command_worker::m_shared_mutex;
43 command_worker::command_worker(const csocket& socket)
44 : m_client_id(CLIENT_ID_INVALID)
45 , m_permission(SENSOR_PERMISSION_NONE)
48 , m_sensor_id(UNKNOWN_SENSOR)
50 static bool init = false;
52 AUTOLOCK(m_shared_mutex);
60 m_worker.set_context(this);
61 m_worker.set_working(working);
62 m_worker.set_stopped(stopped);
65 command_worker::~command_worker()
71 bool command_worker::start(void)
73 return m_worker.start();
76 void command_worker::init_cmd_handlers(void)
78 m_cmd_handlers[CMD_GET_ID] = &command_worker::cmd_get_id;
79 m_cmd_handlers[CMD_GET_SENSOR_LIST] = &command_worker::cmd_get_sensor_list;
80 m_cmd_handlers[CMD_HELLO] = &command_worker::cmd_hello;
81 m_cmd_handlers[CMD_BYEBYE] = &command_worker::cmd_byebye;
82 m_cmd_handlers[CMD_START] = &command_worker::cmd_start;
83 m_cmd_handlers[CMD_STOP] = &command_worker::cmd_stop;
84 m_cmd_handlers[CMD_REG] = &command_worker::cmd_register_event;
85 m_cmd_handlers[CMD_UNREG] = &command_worker::cmd_unregister_event;
86 m_cmd_handlers[CMD_SET_OPTION] = &command_worker::cmd_set_option;
87 m_cmd_handlers[CMD_SET_BATCH] = &command_worker::cmd_set_batch;
88 m_cmd_handlers[CMD_UNSET_BATCH] = &command_worker::cmd_unset_batch;
89 m_cmd_handlers[CMD_GET_DATA] = &command_worker::cmd_get_data;
90 m_cmd_handlers[CMD_SET_ATTRIBUTE_INT] = &command_worker::cmd_set_attribute_int;
91 m_cmd_handlers[CMD_SET_ATTRIBUTE_STR] = &command_worker::cmd_set_attribute_str;
92 m_cmd_handlers[CMD_FLUSH] = &command_worker::cmd_flush;
95 int command_worker::create_sensor_raw_list(int client_perms, std::vector<raw_data_t *> &raw_list)
97 size_t total_raw_data_size = 0;
98 vector<sensor_base *> sensors;
99 vector<sensor_type_t> types;
103 types = sensor_loader::get_instance().get_sensor_types();
105 for (auto it_type = types.begin(); it_type != types.end(); ++it_type) {
106 sensor_type_t type = *it_type;
107 sensors = sensor_loader::get_instance().get_sensors(type);
109 for (auto it_sensor = sensors.begin(); it_sensor != sensors.end(); ++it_sensor) {
110 (*it_sensor)->get_sensor_info(info);
111 permission = (*it_sensor)->get_permission();
112 permission = (client_perms & permission);
116 info.set_id((sensor_id_t)-EACCES);
120 raw_data_t *raw_data = new(std::nothrow) raw_data_t();
121 retvm_if(!raw_data, -1, "Failed to allocated memory");
122 info.get_raw_data(*raw_data);
124 total_raw_data_size += raw_data->size();
125 raw_list.push_back(raw_data);
131 return total_raw_data_size;
134 void command_worker::get_sensor_list(int client_perms, cpacket &sensor_list)
136 size_t total_raw_data_size = 0;
137 vector<raw_data_t *> raw_list;
141 total_raw_data_size = create_sensor_raw_list(client_perms, raw_list);
143 sensor_cnt = raw_list.size();
145 sensor_list.set_payload_size(sizeof(cmd_get_sensor_list_done_t) + (sizeof(size_t) * sensor_cnt) + total_raw_data_size);
146 sensor_list.set_cmd(CMD_GET_SENSOR_LIST);
148 cmd_get_sensor_list_done_t *cmd_get_sensor_list_done;
150 cmd_get_sensor_list_done = (cmd_get_sensor_list_done_t*)sensor_list.data();
151 cmd_get_sensor_list_done->sensor_cnt = sensor_cnt;
152 size_t* size_field = (size_t *) cmd_get_sensor_list_done->data;
154 for (int i = 0; i < sensor_cnt; ++i)
155 size_field[i] = raw_list[i]->size();
157 char* raw_data_field = cmd_get_sensor_list_done->data + (sizeof(size_t) * sensor_cnt);
159 for (int i = 0; i < sensor_cnt; ++i) {
160 copy(raw_list[i]->begin(), raw_list[i]->end(), raw_data_field + idx);
161 idx += raw_list[i]->size();
164 for (auto it = raw_list.begin(); it != raw_list.end(); ++it)
168 bool command_worker::working(void *ctx)
171 command_worker *inst = (command_worker *)ctx;
173 packet_header header;
176 if (inst->m_socket.recv(&header, sizeof(header)) <= 0) {
178 inst->get_info(info);
179 _D("%s failed to receive header", info.c_str());
183 if (header.size > 0) {
185 payload = new(std::nothrow) char[header.size];
186 retvm_if(!payload, false, "Failed to allocate memory");
188 if (inst->m_socket.recv(payload, header.size) <= 0) {
190 inst->get_info(info);
191 _D("%s failed to receive data of packet", info.c_str());
199 ret = inst->dispatch_command(header.cmd, payload);
208 bool command_worker::stopped(void *ctx)
211 command_worker *inst = (command_worker *)ctx;
213 inst->get_info(info);
214 _I("%s is stopped", info.c_str());
216 if ((inst->m_module) && (inst->m_client_id != CLIENT_ID_INVALID)) {
217 if (get_client_info_manager().is_started(inst->m_client_id, inst->m_sensor_id)) {
218 _W("Does not receive cmd_stop before connection broken for [%s]!!", inst->m_module->get_name());
219 inst->m_module->delete_interval(inst->m_client_id, false);
220 inst->m_module->stop();
223 if (inst->m_sensor_id) {
224 if (get_client_info_manager().has_sensor_record(inst->m_client_id, inst->m_sensor_id)) {
225 _I("Removing sensor[0x%llx] record for client_id[%d]", inst->m_sensor_id, inst->m_client_id);
226 get_client_info_manager().remove_sensor_record(inst->m_client_id, inst->m_sensor_id);
235 bool command_worker::dispatch_command(int cmd, void* payload)
239 if (!(cmd > 0 && cmd < CMD_CNT)) {
240 _E("Unknown command: %d", cmd);
242 cmd_handler_t cmd_handler;
243 cmd_handler = command_worker::m_cmd_handlers[cmd];
245 ret = (this->*cmd_handler)(payload);
251 bool command_worker::send_cmd_done(long value)
254 cmd_done_t *cmd_done;
256 ret_packet = new(std::nothrow) cpacket(sizeof(cmd_done_t));
257 retvm_if(!ret_packet, false, "Failed to allocate memory");
259 ret_packet->set_cmd(CMD_DONE);
261 cmd_done = (cmd_done_t*)ret_packet->data();
262 cmd_done->value = value;
264 if (m_socket.send(ret_packet->packet(), ret_packet->size()) <= 0) {
265 _E("Failed to send a cmd_done to client_id [%d] with value [%ld]", m_client_id, value);
276 bool command_worker::send_cmd_get_id_done(int client_id)
279 cmd_get_id_done_t *cmd_get_id_done;
281 ret_packet = new(std::nothrow) cpacket(sizeof(cmd_get_id_done_t));
282 retvm_if(!ret_packet, false, "Failed to allocate memory");
284 ret_packet->set_cmd(CMD_GET_ID);
286 cmd_get_id_done = (cmd_get_id_done_t*)ret_packet->data();
287 cmd_get_id_done->client_id = client_id;
289 if (m_socket.send(ret_packet->packet(), ret_packet->size()) <= 0) {
290 _E("Failed to send a cmd_get_id_done with client_id [%d]", client_id);
299 bool command_worker::send_cmd_get_data_done(int state, sensor_data_t *data)
302 cmd_get_data_done_t *cmd_get_data_done;
304 ret_packet = new(std::nothrow) cpacket(sizeof(cmd_get_data_done_t));
305 retvm_if(!ret_packet, false, "Failed to allocate memory");
307 ret_packet->set_cmd(CMD_GET_DATA);
309 cmd_get_data_done = (cmd_get_data_done_t*)ret_packet->data();
310 cmd_get_data_done->state = state;
312 memcpy(&cmd_get_data_done->base_data , data, sizeof(sensor_data_t));
314 if (m_socket.send(ret_packet->packet(), ret_packet->size()) <= 0) {
315 _E("Failed to send a cmd_get_data_done");
327 bool command_worker::send_cmd_get_sensor_list_done(void)
331 int permission = get_permission();
333 _I("permission = 0x%x", permission);
335 get_sensor_list(permission, sensor_list);
337 if (m_socket.send(sensor_list.packet(), sensor_list.size()) <= 0) {
338 _E("Failed to send a cmd_get_sensor_list_done");
345 bool command_worker::cmd_get_id(void *payload)
350 socklen_t opt_len = sizeof(cr);
352 _D("CMD_GET_ID Handler invoked\n");
353 cmd = (cmd_get_id_t*)payload;
355 if (getsockopt(m_socket.get_socket_fd(), SOL_SOCKET, SO_PEERCRED, &cr, &opt_len)) {
356 _E("Failed to get socket option with SO_PEERCRED");
360 client_id = get_client_info_manager().create_client_record();
362 get_client_info_manager().set_client_info(client_id, cr.pid, cmd->name);
364 m_permission = get_permission();
365 get_client_info_manager().set_permission(client_id, m_permission);
367 _I("New client id [%d] created", client_id);
369 if (!send_cmd_get_id_done(client_id))
370 _E("Failed to send cmd_done to a client");
376 bool command_worker::cmd_get_sensor_list(void *payload)
378 _D("CMD_GET_SENSOR_LIST Handler invoked\n");
380 if (!send_cmd_get_sensor_list_done())
381 _E("Failed to send cmd_get_sensor_list_done to a client");
386 bool command_worker::cmd_hello(void *payload)
389 long ret_value = OP_ERROR;
391 _D("CMD_HELLO Handler invoked\n");
392 cmd = (cmd_hello_t*)payload;
394 m_sensor_id = cmd->sensor;
395 m_client_id = cmd->client_id;
397 if (m_permission == SENSOR_PERMISSION_NONE)
398 get_client_info_manager().get_permission(m_client_id, m_permission);
400 m_module = (sensor_base *)sensor_loader::get_instance().get_sensor(cmd->sensor);
403 _E("Sensor type[%d] is not supported", cmd->sensor);
404 if (!get_client_info_manager().has_sensor_record(m_client_id))
405 get_client_info_manager().remove_client_record(m_client_id);
407 ret_value = OP_ERROR;
411 if (!is_permission_allowed()) {
412 _E("Permission denied to connect sensor[0x%llx] for client [%d]", m_sensor_id, m_client_id);
413 ret_value = OP_ERROR;
417 _D("Hello sensor [0x%llx], client id [%d]", m_sensor_id, m_client_id);
418 get_client_info_manager().create_sensor_record(m_client_id, m_sensor_id);
419 _I("New sensor record created for sensor [0x%llx], sensor name [%s] on client id [%d]\n", m_sensor_id, m_module->get_name(), m_client_id);
420 ret_value = OP_SUCCESS;
422 if (!send_cmd_done(ret_value))
423 _E("Failed to send cmd_done to a client");
428 bool command_worker::cmd_byebye(void *payload)
430 long ret_value = OP_ERROR;
432 if (!is_permission_allowed()) {
433 _E("Permission denied to stop sensor[0x%llx] for client [%d]", m_sensor_id, m_client_id);
434 ret_value = OP_ERROR;
438 _D("CMD_BYEBYE for client [%d], sensor [0x%llx]", m_client_id, m_sensor_id);
440 if (!get_client_info_manager().remove_sensor_record(m_client_id, m_sensor_id)) {
441 _E("Error removing sensor_record for client [%d]", m_client_id);
442 ret_value = OP_ERROR;
446 m_client_id = CLIENT_ID_INVALID;
447 ret_value = OP_SUCCESS;
450 if (!send_cmd_done(ret_value))
451 _E("Failed to send cmd_done to a client");
453 if (ret_value == OP_SUCCESS)
459 bool command_worker::cmd_start(void *payload)
461 long ret_value = OP_ERROR;
463 if (!is_permission_allowed()) {
464 _E("Permission denied to start sensor[0x%llx] for client [%d]", m_sensor_id, m_client_id);
465 ret_value = OP_ERROR;
469 _D("START Sensor [0x%llx], called from client [%d]", m_sensor_id, m_client_id);
471 if (m_module->start()) {
472 get_client_info_manager().set_start(m_client_id, m_sensor_id, true);
474 * Rotation could be changed even LCD is off by pop sync rotation
475 * and a client listening rotation event with always-on option.
476 * To reflect the last rotation state, request it to event dispatcher.
478 get_event_dispathcher().request_last_event(m_client_id, m_sensor_id);
479 ret_value = OP_SUCCESS;
481 _E("Failed to start sensor [0x%llx] for client [%d]", m_sensor_id, m_client_id);
482 ret_value = OP_ERROR;
486 if (!send_cmd_done(ret_value))
487 _E("Failed to send cmd_done to a client");
492 bool command_worker::cmd_stop(void *payload)
494 long ret_value = OP_ERROR;
496 if (!is_permission_allowed()) {
497 _E("Permission denied to stop sensor[0x%llx] for client [%d]", m_sensor_id, m_client_id);
498 ret_value = OP_ERROR;
502 _D("STOP Sensor [0x%llx], called from client [%d]", m_sensor_id, m_client_id);
504 if (m_module->stop()) {
505 get_client_info_manager().set_start(m_client_id, m_sensor_id, false);
506 ret_value = OP_SUCCESS;
508 _E("Failed to stop sensor [0x%llx] for client [%d]", m_sensor_id, m_client_id);
509 ret_value = OP_ERROR;
513 if (!send_cmd_done(ret_value))
514 _E("Failed to send cmd_done to a client");
519 bool command_worker::cmd_register_event(void *payload)
522 long ret_value = OP_ERROR;
524 cmd = (cmd_reg_t*)payload;
526 if (!is_permission_allowed()) {
527 _E("Permission denied to register event [0x%x] for client [%d] to client info manager",
528 cmd->event_type, m_client_id);
529 ret_value = OP_ERROR;
533 if (!get_client_info_manager().register_event(m_client_id, m_sensor_id, cmd->event_type)) {
534 _I("Failed to register event [0x%x] for client [%d] to client info manager",
535 cmd->event_type, m_client_id);
536 ret_value = OP_ERROR;
540 ret_value = OP_SUCCESS;
541 _D("Registering Event [0x%x] is done for client [%d]", cmd->event_type, m_client_id);
544 if (!send_cmd_done(ret_value))
545 _E("Failed to send cmd_done to a client");
550 bool command_worker::cmd_unregister_event(void *payload)
553 long ret_value = OP_ERROR;
555 cmd = (cmd_unreg_t*)payload;
557 if (!is_permission_allowed()) {
558 _E("Permission denied to unregister event [0x%x] for client [%d] to client info manager",
559 cmd->event_type, m_client_id);
560 ret_value = OP_ERROR;
564 if (!get_client_info_manager().unregister_event(m_client_id, m_sensor_id, cmd->event_type)) {
565 _E("Failed to unregister event [0x%x] for client [%d] from client info manager",
566 cmd->event_type, m_client_id);
567 ret_value = OP_ERROR;
571 ret_value = OP_SUCCESS;
572 _D("Unregistering Event [0x%x] is done for client [%d]",
573 cmd->event_type, m_client_id);
576 if (!send_cmd_done(ret_value))
577 _E("Failed to send cmd_done to a client");
582 bool command_worker::cmd_set_batch(void *payload)
584 cmd_set_batch_t *cmd;
585 long ret_value = OP_ERROR;
587 cmd = (cmd_set_batch_t*)payload;
589 if (!is_permission_allowed()) {
590 _E("Permission denied to set batch for client [%d], for sensor [0x%llx] with batch [%d, %d] to client info manager",
591 m_client_id, m_sensor_id, cmd->interval, cmd->latency);
592 ret_value = OP_ERROR;
596 if (!get_client_info_manager().set_batch(m_client_id, m_sensor_id, cmd->interval, cmd->latency)) {
597 _E("Failed to set batch for client [%d], for sensor [0x%llx] with batch [%d, %d] to client info manager",
598 m_client_id, m_sensor_id, cmd->interval, cmd->latency);
599 ret_value = OP_ERROR;
603 if (!m_module->add_interval(m_client_id, cmd->interval, false)) {
604 _E("Failed to set interval for client [%d], for sensor [0x%llx] with interval [%d]",
605 m_client_id, m_sensor_id, cmd->interval);
606 ret_value = OP_ERROR;
610 if (!m_module->add_batch(m_client_id, cmd->latency)) {
611 _E("Failed to set latency for client [%d], for sensor [0x%llx] with latency [%d]",
612 m_client_id, m_sensor_id, cmd->latency);
613 ret_value = OP_ERROR;
617 ret_value = OP_SUCCESS;
620 if (!send_cmd_done(ret_value))
621 _E("Failed to send cmd_done to a client");
626 bool command_worker::cmd_unset_batch(void *payload)
628 long ret_value = OP_ERROR;
630 if (!is_permission_allowed()) {
631 _E("Permission denied to unset batch for client [%d], for sensor [0x%llx] to client info manager",
632 m_client_id, m_sensor_id);
633 ret_value = OP_ERROR;
637 if (!get_client_info_manager().set_batch(m_client_id, m_sensor_id, 0, 0)) {
638 _E("Failed to unset batch for client [%d], for sensor [0x%llx] to client info manager",
639 m_client_id, m_sensor_id);
640 ret_value = OP_ERROR;
644 if (!m_module->delete_interval(m_client_id, false)) {
645 _E("Failed to delete interval for client [%d]", m_client_id);
646 ret_value = OP_ERROR;
650 if (!m_module->delete_batch(m_client_id)) {
651 _E("Failed to delete latency for client [%d]", m_client_id);
652 ret_value = OP_ERROR;
656 ret_value = OP_SUCCESS;
659 if (!send_cmd_done(ret_value))
660 _E("Failed to send cmd_done to a client");
665 bool command_worker::cmd_set_option(void *payload)
667 cmd_set_option_t *cmd;
668 long ret_value = OP_ERROR;
670 cmd = (cmd_set_option_t*)payload;
672 if (!is_permission_allowed()) {
673 _E("Permission denied to set interval for client [%d], for sensor [0x%llx] with option [%d] to client info manager",
674 m_client_id, m_sensor_id, cmd->option);
675 ret_value = OP_ERROR;
679 if (!get_client_info_manager().set_option(m_client_id, m_sensor_id, cmd->option)) {
680 _E("Failed to set option for client [%d], for sensor [0x%llx] with option [%d] to client info manager",
681 m_client_id, m_sensor_id, cmd->option);
682 ret_value = OP_ERROR;
686 ret_value = OP_SUCCESS;
688 if (!send_cmd_done(ret_value))
689 _E("Failed to send cmd_done to a client");
694 bool command_worker::cmd_get_data(void *payload)
696 const unsigned int GET_DATA_MIN_INTERVAL = 10;
697 int state = OP_ERROR;
699 bool adjusted = false;
704 _D("CMD_GET_VALUE Handler invoked\n");
706 if (!is_permission_allowed()) {
707 _E("Permission denied to get data for client [%d], for sensor [0x%llx]",
708 m_client_id, m_sensor_id);
713 remain_count = m_module->get_data(&data, &length);
715 // In case of not getting sensor data, wait short time and retry again
716 // 1. changing interval to be less than 10ms
717 // 2. In case of first time, wait for INIT_WAIT_TIME
718 // 3. at another time, wait for WAIT_TIME
719 // 4. retrying to get data
720 // 5. repeat 2 ~ 4 operations RETRY_CNT times
721 // 6. reverting back to original interval
722 if ((remain_count >= 0) && !data->timestamp) {
723 const int RETRY_CNT = 10;
726 unsigned int interval = m_module->get_interval(m_client_id, false);
728 if (interval > GET_DATA_MIN_INTERVAL) {
729 m_module->add_interval(m_client_id, GET_DATA_MIN_INTERVAL, false);
733 while ((remain_count >= 0) && !data->timestamp && (retry++ < RETRY_CNT)) {
734 _I("Wait sensor[0x%llx] data updated for client [%d] #%d", m_sensor_id, m_client_id, retry);
735 usleep(WAIT_TIME(retry));
736 remain_count = m_module->get_data(&data, &length);
740 m_module->add_interval(m_client_id, interval, false);
747 _E("Failed to get data for client [%d], for sensor [0x%llx]",
748 m_client_id, m_sensor_id);
752 send_cmd_get_data_done(state, data);
757 bool command_worker::cmd_set_attribute_int(void *payload)
759 cmd_set_attribute_int_t *cmd;
760 long ret_value = OP_ERROR;
762 _D("CMD_SET_COMMAND Handler invoked\n");
764 cmd = (cmd_set_attribute_int_t*)payload;
766 if (!is_permission_allowed()) {
767 _E("Permission denied to set attribute for client [%d], for sensor [0x%llx] with attribute [%d]",
768 m_client_id, m_sensor_id, cmd->attribute);
769 ret_value = OP_ERROR;
773 ret_value = m_module->set_attribute(cmd->attribute, cmd->value);
776 if (!send_cmd_done(ret_value))
777 _E("Failed to send cmd_done to a client");
782 bool command_worker::cmd_set_attribute_str(void *payload)
784 cmd_set_attribute_str_t *cmd;
785 long ret_value = OP_ERROR;
787 _D("CMD_SEND_SENSORHUB_DATA Handler invoked");
789 cmd = (cmd_set_attribute_str_t*)payload;
791 if (!is_permission_allowed()) {
792 _E("Permission denied to set attribute for client [%d], for sensor [0x%llx]",
793 m_client_id, m_sensor_id);
794 ret_value = OP_ERROR;
798 ret_value = m_module->set_attribute(cmd->attribute, cmd->value, cmd->value_len);
801 if (!send_cmd_done(ret_value))
802 _E("Failed to send cmd_done to a client");
807 bool command_worker::cmd_flush(void *payload)
809 long ret_value = OP_ERROR;
811 _D("CMD_FLUSH Handler invoked");
813 if (!is_permission_allowed()) {
814 _E("Permission denied to flush sensor data for client [%d], for sensor [0x%llx]",
815 m_client_id, m_sensor_id);
816 ret_value = OP_ERROR;
820 if (!m_module->flush()) {
821 _E("Failed to flush sensor_data [%d]", m_client_id);
822 ret_value = OP_ERROR;
826 ret_value = OP_SUCCESS;
829 if (!send_cmd_done(ret_value))
830 _E("Failed to send cmd_done to a client");
835 void command_worker::get_info(string &info)
837 const char *client_info = NULL;
838 const char *sensor_info = NULL;
840 if (m_client_id != CLIENT_ID_INVALID)
841 client_info = get_client_info_manager().get_client_info(m_client_id);
844 sensor_info = m_module->get_name();
846 info = string("Command worker for ") + (client_info ? client_info : "Unknown") + "'s "
847 + (sensor_info ? sensor_info : "Unknown");
850 int command_worker::get_permission(void)
852 return permission_checker::get_instance().get_permission(m_socket.get_socket_fd());
855 bool command_worker::is_permission_allowed(void)
860 if (m_module->get_permission() & m_permission)
867 client_info_manager& command_worker::get_client_info_manager(void)
869 return client_info_manager::get_instance();
872 sensor_event_dispatcher& command_worker::get_event_dispathcher(void)
874 return sensor_event_dispatcher::get_instance();