sensord: change the HAL interface
[platform/core/system/sensord.git] / src / server / command_worker.cpp
1 /*
2  * sensord
3  *
4  * Copyright (c) 2014 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 <command_worker.h>
21 #include <sensor_loader.h>
22 #include <sensor_info.h>
23 #include <sensor_types.h>
24 #include <thread>
25 #include <string>
26 #include <vector>
27 #include <utility>
28 #include <permission_checker.h>
29 #include <set>
30
31 using std::string;
32 using std::vector;
33 using std::make_pair;
34
35 command_worker::cmd_handler_t command_worker::m_cmd_handlers[];
36 sensor_raw_data_map command_worker::m_sensor_raw_data_map;
37 cpacket command_worker::m_sensor_list;
38
39 std::set<unsigned int> priority_list;
40
41 command_worker::command_worker(const csocket& socket)
42 : m_client_id(CLIENT_ID_INVALID)
43 , m_permission(SENSOR_PERMISSION_NONE)
44 , m_socket(socket)
45 , m_module(NULL)
46 , m_sensor_id(UNKNOWN_SENSOR)
47 {
48         static bool init = false;
49
50         if (!init) {
51                 init_cmd_handlers();
52                 make_sensor_raw_data_map();
53
54                 init = true;
55         }
56
57         m_worker.set_context(this);
58         m_worker.set_working(working);
59         m_worker.set_stopped(stopped);
60 }
61
62 command_worker::~command_worker()
63 {
64         m_socket.close();
65 }
66
67
68 bool command_worker::start(void)
69 {
70         return m_worker.start();
71 }
72
73 void command_worker::init_cmd_handlers(void)
74 {
75         m_cmd_handlers[CMD_GET_ID]                              = &command_worker::cmd_get_id;
76         m_cmd_handlers[CMD_GET_SENSOR_LIST]             = &command_worker::cmd_get_sensor_list;
77         m_cmd_handlers[CMD_HELLO]                               = &command_worker::cmd_hello;
78         m_cmd_handlers[CMD_BYEBYE]                              = &command_worker::cmd_byebye;
79         m_cmd_handlers[CMD_START]                               = &command_worker::cmd_start;
80         m_cmd_handlers[CMD_STOP]                                = &command_worker::cmd_stop;
81         m_cmd_handlers[CMD_REG]                                 = &command_worker::cmd_register_event;
82         m_cmd_handlers[CMD_UNREG]                               = &command_worker::cmd_unregister_event;
83         m_cmd_handlers[CMD_SET_OPTION]                  = &command_worker::cmd_set_option;
84         m_cmd_handlers[CMD_SET_WAKEUP]                  = &command_worker::cmd_set_wakeup;
85         m_cmd_handlers[CMD_SET_BATCH]                   = &command_worker::cmd_set_batch;
86         m_cmd_handlers[CMD_UNSET_BATCH]                 = &command_worker::cmd_unset_batch;
87         m_cmd_handlers[CMD_SET_COMMAND]                 = &command_worker::cmd_set_command;
88         m_cmd_handlers[CMD_GET_DATA]                    = &command_worker::cmd_get_data;
89         m_cmd_handlers[CMD_SEND_SENSORHUB_DATA] = &command_worker::cmd_send_sensorhub_data;
90 }
91
92 void command_worker::get_sensor_list(int permissions, cpacket &sensor_list)
93 {
94         const int PERMISSION_COUNT = sizeof(permissions) * 8;
95         vector<raw_data_t *> sensor_raw_vec;
96         size_t total_raw_data_size = 0;
97
98         for (int i = 0; i < PERMISSION_COUNT; ++i) {
99                 int perm = (permissions & (1 << i));
100
101                 if (perm) {
102                         auto range = m_sensor_raw_data_map.equal_range(perm);
103
104                         sensor_raw_data_map::iterator it_raw_data;
105
106                         for (it_raw_data = range.first; it_raw_data != range.second; ++it_raw_data) {
107                                 total_raw_data_size += it_raw_data->second.size();
108                                 sensor_raw_vec.push_back(&(it_raw_data->second));
109                         }
110                 }
111         }
112
113         int sensor_cnt;
114
115         sensor_cnt = sensor_raw_vec.size();
116
117         sensor_list.set_payload_size(sizeof(cmd_get_sensor_list_done_t) + (sizeof(size_t) * sensor_cnt) + total_raw_data_size);
118         sensor_list.set_cmd(CMD_GET_SENSOR_LIST);
119
120         cmd_get_sensor_list_done_t *cmd_get_sensor_list_done;
121
122         cmd_get_sensor_list_done = (cmd_get_sensor_list_done_t*)sensor_list.data();
123         cmd_get_sensor_list_done->sensor_cnt = sensor_cnt;
124         size_t* size_field = (size_t *) cmd_get_sensor_list_done->data;
125
126
127         for (int i = 0; i < sensor_cnt; ++i)
128                 size_field[i] = sensor_raw_vec[i]->size();
129
130         char* raw_data_field = cmd_get_sensor_list_done->data + (sizeof(size_t) * sensor_cnt);
131
132         int idx = 0;
133         for (int i = 0; i < sensor_cnt; ++i) {
134                 copy(sensor_raw_vec[i]->begin(), sensor_raw_vec[i]->end(), raw_data_field + idx);
135                 idx += sensor_raw_vec[i]->size();
136         }
137
138 }
139
140 void command_worker::make_sensor_raw_data_map(void)
141 {
142         vector<sensor_base *> sensors;
143         vector<sensor_type_t> types;
144         std::vector<sensor_type_t>::iterator it_type;
145         std::vector<sensor_base *>::iterator it_sensor;
146         sensor_info info;
147         int permission;
148
149         types = sensor_loader::get_instance().get_sensor_types();
150
151         it_type = types.begin();
152         while (it_type != types.end()) {
153                 sensor_type_t type;
154                 type = *it_type;
155
156                 sensors = sensor_loader::get_instance().get_sensors(type);
157                 it_sensor = sensors.begin();
158
159                 while (it_sensor != sensors.end()) {
160                         (*it_sensor)->get_sensor_info(info);
161                         permission = (*it_sensor)->get_permission();
162
163                         sensor_raw_data_map::iterator it_sensor_raw_data;
164                         it_sensor_raw_data = m_sensor_raw_data_map.insert(std::make_pair(permission, raw_data_t()));
165
166                         info.get_raw_data(it_sensor_raw_data->second);
167                         info.clear();
168                         ++it_sensor;
169                 }
170                 ++it_type;
171         }
172 }
173
174 bool command_worker::working(void *ctx)
175 {
176         bool ret;
177         command_worker *inst = (command_worker *)ctx;
178
179         packet_header header;
180         char *payload;
181
182         if (inst->m_socket.recv(&header, sizeof(header)) <= 0) {
183                 string info;
184                 inst->get_info(info);
185                 DBG("%s failed to receive header", info.c_str());
186                 return false;
187         }
188
189         if (header.size > 0) {
190
191                 payload = new(std::nothrow) char[header.size];
192                 retvm_if(!payload, false, "Failed to allocate memory");
193
194                 if (inst->m_socket.recv(payload, header.size) <= 0) {
195                         string info;
196                         inst->get_info(info);
197                         DBG("%s failed to receive data of packet", info.c_str());
198                         delete[] payload;
199                         return false;
200                 }
201         } else {
202                 payload = NULL;
203         }
204
205         ret = inst->dispatch_command(header.cmd, payload);
206
207         if (payload)
208                 delete[] payload;
209
210         return ret;
211 }
212
213
214 bool command_worker::stopped(void *ctx)
215 {
216         string info;
217         command_worker *inst = (command_worker *)ctx;
218
219         inst->get_info(info);
220         INFO("%s is stopped", info.c_str());
221
222         if ((inst->m_module) && (inst->m_client_id != CLIENT_ID_INVALID)) {
223
224                 if (get_client_info_manager().is_started(inst->m_client_id, inst->m_sensor_id)) {
225                         WARN("Does not receive cmd_stop before connection broken for [%s]!!", inst->m_module->get_name());
226                         inst->m_module->delete_interval(inst->m_client_id, false);
227                         inst->m_module->stop();
228                 }
229
230                 if (inst->m_sensor_id) {
231                         if (get_client_info_manager().has_sensor_record(inst->m_client_id, inst->m_sensor_id)) {
232                                 INFO("Removing sensor[0x%llx] record for client_id[%d]", inst->m_sensor_id, inst->m_client_id);
233                                 get_client_info_manager().remove_sensor_record(inst->m_client_id, inst->m_sensor_id);
234                         }
235                 }
236         }
237
238         delete inst;
239         return true;
240 }
241
242 bool command_worker::dispatch_command(int cmd, void* payload)
243 {
244         int ret = false;
245
246         if (!(cmd > 0 && cmd < CMD_CNT)) {
247                 ERR("Unknown command: %d", cmd);
248         } else {
249                 cmd_handler_t cmd_handler;
250                 cmd_handler = command_worker::m_cmd_handlers[cmd];
251                 if (cmd_handler)
252                         ret = (this->*cmd_handler)(payload);
253         }
254
255         return ret;
256 }
257
258 bool command_worker::send_cmd_done(long value)
259 {
260         cpacket* ret_packet;
261         cmd_done_t *cmd_done;
262
263         ret_packet = new(std::nothrow) cpacket(sizeof(cmd_done_t));
264         retvm_if(!ret_packet, false, "Failed to allocate memory");
265
266         ret_packet->set_cmd(CMD_DONE);
267
268         cmd_done = (cmd_done_t*)ret_packet->data();
269         cmd_done->value = value;
270
271         if (m_socket.send(ret_packet->packet(), ret_packet->size()) <= 0) {
272                 ERR("Failed to send a cmd_done to client_id [%d] with value [%ld]", m_client_id, value);
273                 delete ret_packet;
274                 return false;
275         }
276
277         delete ret_packet;
278         return true;
279
280 }
281
282
283 bool command_worker::send_cmd_get_id_done(int client_id)
284 {
285         cpacket* ret_packet;
286         cmd_get_id_done_t *cmd_get_id_done;
287
288         ret_packet = new(std::nothrow) cpacket(sizeof(cmd_get_id_done_t));
289         retvm_if(!ret_packet, false, "Failed to allocate memory");
290
291         ret_packet->set_cmd(CMD_GET_ID);
292
293         cmd_get_id_done = (cmd_get_id_done_t*)ret_packet->data();
294         cmd_get_id_done->client_id = client_id;
295
296         if (m_socket.send(ret_packet->packet(), ret_packet->size()) <= 0) {
297                 ERR("Failed to send a cmd_get_id_done with client_id [%d]", client_id);
298                 delete ret_packet;
299                 return false;
300         }
301
302         delete ret_packet;
303         return true;
304 }
305
306 bool command_worker::send_cmd_get_data_done(int state, sensor_data_t *data)
307 {
308         cpacket* ret_packet;
309         cmd_get_data_done_t *cmd_get_data_done;
310
311         ret_packet = new(std::nothrow) cpacket(sizeof(cmd_get_data_done_t));
312         retvm_if(!ret_packet, false, "Failed to allocate memory");
313
314         ret_packet->set_cmd(CMD_GET_DATA);
315
316         cmd_get_data_done = (cmd_get_data_done_t*)ret_packet->data();
317         cmd_get_data_done->state = state;
318
319         memcpy(&cmd_get_data_done->base_data , data, sizeof(sensor_data_t));
320
321         if (m_socket.send(ret_packet->packet(), ret_packet->size()) <= 0) {
322                 ERR("Failed to send a cmd_get_data_done");
323                 delete ret_packet;
324                 return false;
325         }
326
327         delete ret_packet;
328         return true;
329 }
330
331
332 bool command_worker::send_cmd_get_sensor_list_done(void)
333 {
334         cpacket sensor_list;
335
336         int permission = get_permission();
337
338         INFO("permission = 0x%x", permission);
339
340         get_sensor_list(permission, sensor_list);
341
342         if (m_socket.send(sensor_list.packet(), sensor_list.size()) <= 0) {
343                 ERR("Failed to send a cmd_get_sensor_list_done");
344                 return false;
345         }
346
347         return true;
348 }
349
350 bool command_worker::cmd_get_id(void *payload)
351 {
352         cmd_get_id_t *cmd;
353         int client_id;
354         struct ucred cr;
355         socklen_t opt_len = sizeof(cr);
356
357         DBG("CMD_GET_ID Handler invoked\n");
358         cmd = (cmd_get_id_t*)payload;
359
360         if (getsockopt(m_socket.get_socket_fd(), SOL_SOCKET, SO_PEERCRED, &cr, &opt_len)) {
361                 ERR("Failed to get socket option with SO_PEERCRED");
362                 return false;
363         }
364
365         client_id = get_client_info_manager().create_client_record();
366
367         get_client_info_manager().set_client_info(client_id, cr.pid, cmd->name);
368
369         m_permission = get_permission();
370         get_client_info_manager().set_permission(client_id, m_permission);
371
372         INFO("New client id [%d] created", client_id);
373
374         if (!send_cmd_get_id_done(client_id))
375                 ERR("Failed to send cmd_done to a client");
376
377         return true;
378 }
379
380
381 bool command_worker::cmd_get_sensor_list(void *payload)
382 {
383         DBG("CMD_GET_SENSOR_LIST Handler invoked\n");
384
385         if (!send_cmd_get_sensor_list_done())
386                 ERR("Failed to send cmd_get_sensor_list_done to a client");
387
388         return true;
389 }
390
391 bool command_worker::cmd_hello(void *payload)
392 {
393         cmd_hello_t *cmd;
394         long ret_value = OP_ERROR;
395
396         DBG("CMD_HELLO Handler invoked\n");
397         cmd = (cmd_hello_t*)payload;
398
399         m_sensor_id = cmd->sensor;
400         m_client_id = cmd->client_id;
401
402         if (m_permission == SENSOR_PERMISSION_NONE)
403                 get_client_info_manager().get_permission(m_client_id, m_permission);
404
405         m_module = (sensor_base *)sensor_loader::get_instance().get_sensor(cmd->sensor);
406
407         if (!m_module) {
408                 ERR("Sensor type[%d] is not supported", cmd->sensor);
409                 if (!get_client_info_manager().has_sensor_record(m_client_id))
410                         get_client_info_manager().remove_client_record(m_client_id);
411
412                 ret_value = OP_ERROR;
413                 goto out;
414         }
415
416         if (!is_permission_allowed()) {
417                 ERR("Permission denied to connect sensor[0x%llx] for client [%d]", m_sensor_id, m_client_id);
418                 ret_value = OP_ERROR;
419                 goto out;
420         }
421
422         DBG("Hello sensor [0x%llx], client id [%d]", m_sensor_id, m_client_id);
423         get_client_info_manager().create_sensor_record(m_client_id, m_sensor_id);
424         INFO("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);
425         ret_value = OP_SUCCESS;
426 out:
427         if (!send_cmd_done(ret_value))
428                 ERR("Failed to send cmd_done to a client");
429
430         return true;
431 }
432
433 bool command_worker::cmd_byebye(void *payload)
434 {
435         long ret_value = OP_ERROR;
436
437         if (!is_permission_allowed()) {
438                 ERR("Permission denied to stop sensor[0x%llx] for client [%d]", m_sensor_id, m_client_id);
439                 ret_value = OP_ERROR;
440                 goto out;
441         }
442
443         DBG("CMD_BYEBYE for client [%d], sensor [0x%llx]", m_client_id, m_sensor_id);
444
445         if (!get_client_info_manager().remove_sensor_record(m_client_id, m_sensor_id)) {
446                 ERR("Error removing sensor_record for client [%d]", m_client_id);
447                 ret_value = OP_ERROR;
448                 goto out;
449         }
450
451         m_client_id = CLIENT_ID_INVALID;
452         ret_value = OP_SUCCESS;
453
454 out:
455         if (!send_cmd_done(ret_value))
456                 ERR("Failed to send cmd_done to a client");
457
458         if (ret_value == OP_SUCCESS)
459                 return false;
460
461         return true;
462 }
463
464 bool command_worker::cmd_start(void *payload)
465 {
466         long ret_value = OP_ERROR;
467
468         if (!is_permission_allowed()) {
469                 ERR("Permission denied to start sensor[0x%llx] for client [%d]", m_sensor_id, m_client_id);
470                 ret_value = OP_ERROR;
471                 goto out;
472         }
473
474         DBG("START Sensor [0x%llx], called from client [%d]", m_sensor_id, m_client_id);
475
476         if (m_module->start()) {
477                 get_client_info_manager().set_start(m_client_id, m_sensor_id, true);
478 /*
479  *      Rotation could be changed even LCD is off by pop sync rotation
480  *      and a client listening rotation event with always-on option.
481  *      To reflect the last rotation state, request it to event dispatcher.
482  */
483                 get_event_dispathcher().request_last_event(m_client_id, m_sensor_id);
484                 ret_value = OP_SUCCESS;
485         } else {
486                 ERR("Failed to start sensor [0x%llx] for client [%d]", m_sensor_id, m_client_id);
487                 ret_value = OP_ERROR;
488         }
489
490 out:
491         if (!send_cmd_done(ret_value))
492                 ERR("Failed to send cmd_done to a client");
493
494         return true;
495 }
496
497 bool command_worker::cmd_stop(void *payload)
498 {
499         long ret_value = OP_ERROR;
500
501         if (!is_permission_allowed()) {
502                 ERR("Permission denied to stop sensor[0x%llx] for client [%d]", m_sensor_id, m_client_id);
503                 ret_value = OP_ERROR;
504                 goto out;
505         }
506
507         DBG("STOP Sensor [0x%llx], called from client [%d]", m_sensor_id, m_client_id);
508
509         if (m_module->stop()) {
510                 get_client_info_manager().set_start(m_client_id, m_sensor_id, false);
511                 ret_value = OP_SUCCESS;
512         } else {
513                 ERR("Failed to stop sensor [0x%llx] for client [%d]", m_sensor_id, m_client_id);
514                 ret_value = OP_ERROR;
515         }
516
517 out:
518         if (!send_cmd_done(ret_value))
519                 ERR("Failed to send cmd_done to a client");
520
521         return true;
522 }
523
524 bool command_worker::cmd_register_event(void *payload)
525 {
526         cmd_reg_t *cmd;
527         long ret_value = OP_ERROR;
528
529         cmd = (cmd_reg_t*)payload;
530
531         if (!is_permission_allowed()) {
532                 ERR("Permission denied to register event [0x%x] for client [%d] to client info manager",
533                         cmd->event_type, m_client_id);
534                 ret_value = OP_ERROR;
535                 goto out;
536         }
537
538         if (!get_client_info_manager().register_event(m_client_id, m_sensor_id, cmd->event_type)) {
539                 INFO("Failed to register event [0x%x] for client [%d] to client info manager",
540                         cmd->event_type, m_client_id);
541                 ret_value = OP_ERROR;
542                 goto out;
543         }
544
545         insert_priority_list(cmd->event_type);
546
547         ret_value = OP_SUCCESS;
548         DBG("Registering Event [0x%x] is done for client [%d]", cmd->event_type, m_client_id);
549
550 out:
551         if (!send_cmd_done(ret_value))
552                 ERR("Failed to send cmd_done to a client");
553
554         return true;
555 }
556
557 bool command_worker::cmd_unregister_event(void *payload)
558 {
559         cmd_unreg_t *cmd;
560         long ret_value = OP_ERROR;
561
562         cmd = (cmd_unreg_t*)payload;
563
564         if (!is_permission_allowed()) {
565                 ERR("Permission denied to unregister event [0x%x] for client [%d] to client info manager",
566                         cmd->event_type, m_client_id);
567                 ret_value = OP_ERROR;
568                 goto out;
569         }
570
571         if (!get_client_info_manager().unregister_event(m_client_id, m_sensor_id, cmd->event_type)) {
572                 ERR("Failed to unregister event [0x%x] for client [%d] from client info manager",
573                         cmd->event_type, m_client_id);
574                 ret_value = OP_ERROR;
575                 goto out;
576         }
577
578         ret_value = OP_SUCCESS;
579         DBG("Unregistering Event [0x%x] is done for client [%d]",
580                 cmd->event_type, m_client_id);
581
582 out:
583         if (!send_cmd_done(ret_value))
584                 ERR("Failed to send cmd_done to a client");
585
586         return true;
587 }
588
589 bool command_worker::cmd_set_batch(void *payload)
590 {
591         cmd_set_batch_t *cmd;
592         long ret_value = OP_ERROR;
593
594         cmd = (cmd_set_batch_t*)payload;
595
596         if (!is_permission_allowed()) {
597                 ERR("Permission denied 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;
600                 goto out;
601         }
602
603         if (!get_client_info_manager().set_batch(m_client_id, m_sensor_id, cmd->interval, cmd->latency)) {
604                 ERR("Failed to set batch for client [%d], for sensor [0x%llx] with batch [%d, %d] to client info manager",
605                         m_client_id, m_sensor_id, cmd->interval, cmd->latency);
606                 ret_value = OP_ERROR;
607                 goto out;
608         }
609
610         if (!m_module->add_interval(m_client_id, cmd->interval, false)) {
611                 ERR("Failed to set interval for client [%d], for sensor [0x%llx] with interval [%d]",
612                         m_client_id, m_sensor_id, cmd->interval);
613                 ret_value = OP_ERROR;
614                 goto out;
615         }
616
617         if (!m_module->add_batch(m_client_id, cmd->latency)) {
618                 ERR("Failed to set latency for client [%d], for sensor [0x%llx] with latency [%d]",
619                         m_client_id, m_sensor_id, cmd->latency);
620                 ret_value = OP_ERROR;
621                 goto out;
622         }
623
624         ret_value = OP_SUCCESS;
625
626 out:
627         if (!send_cmd_done(ret_value))
628                 ERR("Failed to send cmd_done to a client");
629
630         return true;
631 }
632
633 bool command_worker::cmd_unset_batch(void *payload)
634 {
635         long ret_value = OP_ERROR;
636
637         if (!is_permission_allowed()) {
638                 ERR("Permission denied 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;
641                 goto out;
642         }
643
644         if (!get_client_info_manager().set_batch(m_client_id, m_sensor_id, 0, 0)) {
645                 ERR("Failed to unset batch for client [%d], for sensor [0x%llx] to client info manager",
646                         m_client_id, m_sensor_id);
647                 ret_value = OP_ERROR;
648                 goto out;
649         }
650
651         if (!m_module->delete_interval(m_client_id, false)) {
652                 ERR("Failed to delete interval for client [%d]", m_client_id);
653                 ret_value = OP_ERROR;
654                 goto out;
655         }
656
657         if (!m_module->delete_batch(m_client_id)) {
658                 ERR("Failed to delete latency for client [%d]", m_client_id);
659                 ret_value = OP_ERROR;
660                 goto out;
661         }
662
663         ret_value = OP_SUCCESS;
664
665 out:
666         if (!send_cmd_done(ret_value))
667                 ERR("Failed to send cmd_done to a client");
668
669         return true;
670 }
671
672 bool command_worker::cmd_set_option(void *payload)
673 {
674         cmd_set_option_t *cmd;
675         long ret_value = OP_ERROR;
676
677         cmd = (cmd_set_option_t*)payload;
678
679         if (!is_permission_allowed()) {
680                 ERR("Permission denied to set interval 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;
683                 goto out;
684         }
685
686         if (!get_client_info_manager().set_option(m_client_id, m_sensor_id, cmd->option)) {
687                 ERR("Failed to set option for client [%d], for sensor [0x%llx] with option [%d] to client info manager",
688                         m_client_id, m_sensor_id, cmd->option);
689                 ret_value = OP_ERROR;
690                 goto out;
691         }
692
693         ret_value = OP_SUCCESS;
694 out:
695         if (!send_cmd_done(ret_value))
696                 ERR("Failed to send cmd_done to a client");
697
698         return true;
699 }
700
701 bool command_worker::cmd_set_wakeup(void *payload)
702 {
703         cmd_set_wakeup_t *cmd;
704         long ret_value = OP_ERROR;
705
706         cmd = (cmd_set_wakeup_t*)payload;
707
708         if (!is_permission_allowed()) {
709                 ERR("Permission denied to set wakeup for client [%d], for sensor [0x%llx] with wakeup [%d] to client info manager",
710                         m_client_id, m_sensor_id, cmd->wakeup);
711                 ret_value = OP_ERROR;
712                 goto out;
713         }
714
715         if (!get_client_info_manager().set_wakeup(m_client_id, m_sensor_id, cmd->wakeup)) {
716                 ERR("Failed to set wakeup for client [%d], for sensor [0x%llx] with wakeup [%d] to client info manager",
717                         m_client_id, m_sensor_id, cmd->wakeup);
718                 ret_value = OP_ERROR;
719                 goto out;
720         }
721
722         ret_value = m_module->add_wakeup(m_client_id, cmd->wakeup);
723
724 out:
725         if (!send_cmd_done(ret_value))
726                 ERR("Failed to send cmd_done to a client");
727
728         return true;
729 }
730
731 bool command_worker::cmd_set_command(void *payload)
732 {
733         cmd_set_command_t *cmd;
734         long ret_value = OP_ERROR;
735
736         DBG("CMD_SET_COMMAND  Handler invoked\n");
737
738         cmd = (cmd_set_command_t*)payload;
739
740         if (!is_permission_allowed()) {
741                 ERR("Permission denied to set command for client [%d], for sensor [0x%llx] with cmd [%d]",
742                         m_client_id, m_sensor_id, cmd->cmd);
743                 ret_value = OP_ERROR;
744                 goto out;
745         }
746
747         ret_value = m_module->set_attribute(cmd->cmd, cmd->value);
748
749 out:
750         if (!send_cmd_done(ret_value))
751                 ERR("Failed to send cmd_done to a client");
752
753         return true;
754 }
755
756 bool command_worker::cmd_get_data(void *payload)
757 {
758         const unsigned int GET_DATA_MIN_INTERVAL = 10;
759         int state = OP_ERROR;
760         bool adjusted = false;
761         int length;
762
763         sensor_data_t *data;
764
765         DBG("CMD_GET_VALUE Handler invoked\n");
766
767         if (!is_permission_allowed()) {
768                 ERR("Permission denied to get data for client [%d], for sensor [0x%llx]",
769                         m_client_id, m_sensor_id);
770                 state = OP_ERROR;
771                 goto out;
772         }
773
774         state = m_module->get_data(&data, &length);
775
776         // In case of not getting sensor data, wait short time and retry again
777         // 1. changing interval to be less than 10ms
778         // 2. In case of first time, wait for INIT_WAIT_TIME
779         // 3. at another time, wait for WAIT_TIME
780         // 4. retrying to get data
781         // 5. repeat 2 ~ 4 operations RETRY_CNT times
782         // 6. reverting back to original interval
783         if ((state >= 0) && !data->timestamp) {
784                 const int RETRY_CNT     = 5;
785                 const unsigned long long INIT_WAIT_TIME = 20000; //20ms
786                 const unsigned long WAIT_TIME = 100000; //100ms
787                 int retry = 0;
788
789                 unsigned int interval = m_module->get_interval(m_client_id, false);
790
791                 if (interval > GET_DATA_MIN_INTERVAL) {
792                         m_module->add_interval(m_client_id, GET_DATA_MIN_INTERVAL, false);
793                         adjusted = true;
794                 }
795
796                 while ((state >= 0) && !data->timestamp && (retry++ < RETRY_CNT)) {
797                         INFO("Wait sensor[0x%llx] data updated for client [%d] #%d", m_sensor_id, m_client_id, retry);
798                         usleep((retry == 1) ? INIT_WAIT_TIME : WAIT_TIME);
799                         state = m_module->get_data(&data, &length);
800                 }
801
802                 if (adjusted)
803                         m_module->add_interval(m_client_id, interval, false);
804         }
805
806         if (!data->timestamp)
807                 state = OP_ERROR;
808
809         if (state <= 0) {
810                 ERR("Failed to get data for client [%d], for sensor [0x%llx]",
811                         m_client_id, m_sensor_id);
812         }
813
814 out:
815         send_cmd_get_data_done(state, data);
816
817         return true;
818 }
819
820 bool command_worker::cmd_send_sensorhub_data(void *payload)
821 {
822         cmd_send_sensorhub_data_t *cmd;
823         long ret_value = OP_ERROR;
824
825         DBG("CMD_SEND_SENSORHUB_DATA Handler invoked");
826
827         cmd = (cmd_send_sensorhub_data_t*)payload;
828
829         if (!is_permission_allowed()) {
830                 ERR("Permission denied to send sensorhub_data for client [%d], for sensor [0x%llx]",
831                         m_client_id, m_sensor_id);
832                 ret_value = OP_ERROR;
833                 goto out;
834         }
835
836         ret_value = m_module->set_attribute(cmd->data, cmd->data, cmd->data_len);
837
838 out:
839         if (!send_cmd_done(ret_value))
840                 ERR("Failed to send cmd_done to a client");
841
842         return true;
843 }
844
845 void command_worker::get_info(string &info)
846 {
847         const char *client_info = NULL;
848         const char *sensor_info = NULL;
849
850         if (m_client_id != CLIENT_ID_INVALID)
851                 client_info = get_client_info_manager().get_client_info(m_client_id);
852
853         if (m_module)
854                 sensor_info = m_module->get_name();
855
856         info = string("Command worker for ") + (client_info ? client_info : "Unknown") + "'s "
857                 + (sensor_info ? sensor_info : "Unknown");
858 }
859
860 int command_worker::get_permission(void)
861 {
862         return permission_checker::get_instance().get_permission(m_socket.get_socket_fd());
863 }
864
865 bool command_worker::is_permission_allowed(void)
866 {
867         if (!m_module)
868                 return false;
869
870         if (m_module->get_permission() & m_permission)
871                 return true;
872
873         return false;
874 }
875
876
877 client_info_manager& command_worker::get_client_info_manager(void)
878 {
879         return client_info_manager::get_instance();
880 }
881
882 sensor_event_dispatcher& command_worker::get_event_dispathcher(void)
883 {
884         return sensor_event_dispatcher::get_instance();
885 }
886
887 void insert_priority_list(unsigned int event_type)
888 {
889         if (event_type == ORIENTATION_RAW_DATA_EVENT ||
890                         event_type == LINEAR_ACCEL_RAW_DATA_EVENT ||
891                         event_type == GRAVITY_RAW_DATA_EVENT ||
892                         event_type == ROTATION_VECTOR_RAW_DATA_EVENT) {
893                 priority_list.insert(ACCELEROMETER_RAW_DATA_EVENT);
894                 priority_list.insert(GYROSCOPE_RAW_DATA_EVENT);
895                 priority_list.insert(GEOMAGNETIC_RAW_DATA_EVENT);
896         }
897
898         if (event_type == GEOMAGNETIC_RV_RAW_DATA_EVENT) {
899                 priority_list.insert(ACCELEROMETER_RAW_DATA_EVENT);
900                 priority_list.insert(GEOMAGNETIC_RAW_DATA_EVENT);
901         }
902
903         if (event_type == GAMING_RV_RAW_DATA_EVENT) {
904                 priority_list.insert(ACCELEROMETER_RAW_DATA_EVENT);
905                 priority_list.insert(GYROSCOPE_RAW_DATA_EVENT);
906         }
907 }