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