Merge branch 'tizen_3.0' into devel/tizen
[platform/core/system/sensord.git] / src / client / external_sensor_manager.cpp
1 /*
2  * sensord
3  *
4  * Copyright (c) 2015 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 #include <sensor_internal.h>
20 #include <sensor_common.h>
21 #include <command_common.h>
22 #include <external_sensor_manager.h>
23 #include <external_data_channel.h>
24 #include <poller.h>
25 #include <thread>
26
27 using std::pair;
28 using std::vector;
29 using std::thread;
30 using std::string;
31
32 external_sensor_manager::external_sensor_manager()
33 : m_client_id(CLIENT_ID_INVALID)
34 , m_poller(NULL)
35 , m_thread_state(THREAD_STATE_TERMINATE)
36 , m_hup_observer(NULL)
37 {
38 }
39
40 external_sensor_manager::~external_sensor_manager()
41 {
42         stop_command_listener();
43 }
44
45 external_sensor_manager& external_sensor_manager::get_instance(void)
46 {
47         static external_sensor_manager inst;
48         return inst;
49 }
50
51 int external_sensor_manager::create_handle(void)
52 {
53         sensor_ext_handle_info handle_info;
54         int handle = 0;
55
56         AUTOLOCK(m_handle_info_lock);
57
58         while (m_sensor_handle_infos.count(handle) > 0)
59                 handle++;
60
61         if (handle >= MAX_HANDLE) {
62                 _E("Handles of client %s are full", get_client_name());
63                 return MAX_HANDLE_REACHED;
64         }
65
66         handle_info.m_handle = handle;
67         handle_info.m_sensor = UNKNOWN_SENSOR;
68         handle_info.m_cb = NULL;
69         handle_info.m_user_data = NULL;
70
71         m_sensor_handle_infos.insert(pair<int, sensor_ext_handle_info>(handle, handle_info));
72
73         return handle;
74 }
75
76 bool external_sensor_manager::delete_handle(int handle)
77 {
78         AUTOLOCK(m_handle_info_lock);
79
80         auto it_handle = m_sensor_handle_infos.find(handle);
81
82         if (it_handle == m_sensor_handle_infos.end()) {
83                 _E("Handle[%d] is not found for client %s", handle, get_client_name());
84                 return false;
85         }
86
87         m_sensor_handle_map.erase(it_handle->second.m_sensor);
88         m_sensor_handle_infos.erase(it_handle);
89
90         return true;
91 }
92
93 bool external_sensor_manager::set_handle(int handle, sensor_id_t sensor, const string& key, void* cb, void* user_data)
94 {
95         AUTOLOCK(m_handle_info_lock);
96
97         auto it_handle = m_sensor_handle_infos.find(handle);
98
99         if (it_handle == m_sensor_handle_infos.end()) {
100                 _E("Handle[%d] is not found for client %s", handle, get_client_name());
101                 return false;
102         }
103
104         it_handle->second.m_sensor = sensor;
105         it_handle->second.m_key = key;
106         it_handle->second.m_cb = cb;
107         it_handle->second.m_user_data = user_data;
108
109         m_sensor_handle_map.insert(pair<sensor_id_t, int>(sensor, handle));
110
111         return true;
112 }
113
114 bool external_sensor_manager::get_sensor(int handle, sensor_id_t &sensor)
115 {
116         AUTOLOCK(m_handle_info_lock);
117
118         auto it_handle = m_sensor_handle_infos.find(handle);
119
120         if (it_handle == m_sensor_handle_infos.end()) {
121                 _E("Handle[%d] is not found for client %s", handle, get_client_name());
122                 return false;
123         }
124
125         sensor = it_handle->second.m_sensor;
126
127         return true;
128 }
129
130 int external_sensor_manager::get_handle(sensor_id_t sensor)
131 {
132         AUTOLOCK(m_handle_info_lock);
133
134         auto it_handle = m_sensor_handle_map.find(sensor);
135
136         if (it_handle == m_sensor_handle_map.end()) {
137                 _E("Handle is not found for client %s with sensor: %d", get_client_name(), sensor);
138                 return -1;
139         }
140
141         return it_handle->second;
142 }
143
144 bool external_sensor_manager::get_handle_info(int handle, const sensor_ext_handle_info*& handle_info)
145 {
146         AUTOLOCK(m_handle_info_lock);
147
148         auto it_handle = m_sensor_handle_infos.find(handle);
149
150         if (it_handle == m_sensor_handle_infos.end()) {
151                 _E("Handle[%d] is not found for client %s", handle, get_client_name());
152                 return false;
153         }
154
155         handle_info = &(it_handle->second);
156         return true;
157 }
158
159 string external_sensor_manager::get_key(int handle)
160 {
161         AUTOLOCK(m_handle_info_lock);
162
163         auto it_handle = m_sensor_handle_infos.find(handle);
164
165         if (it_handle == m_sensor_handle_infos.end()) {
166                 return string("INVALID_KEY");
167         }
168
169         return it_handle->second.m_key;
170 }
171
172 bool external_sensor_manager::has_client_id(void)
173 {
174         return (m_client_id != CLIENT_ID_INVALID);
175 }
176
177 int external_sensor_manager::get_client_id(void)
178 {
179         return m_client_id;
180 }
181
182 void external_sensor_manager::set_client_id(int client_id)
183 {
184         m_client_id = client_id;
185 }
186
187 bool external_sensor_manager::add_data_channel(int handle, external_data_channel *channel)
188 {
189         auto it_channel = m_data_channels.find(handle);
190
191         if (it_channel != m_data_channels.end()) {
192                 _E("%s alreay has data_channel for %s", get_client_name(), get_key(handle).c_str());
193                 return false;
194         }
195
196         m_data_channels.insert(pair<int, external_data_channel *>(handle, channel));
197         return true;
198 }
199
200 bool external_sensor_manager::get_data_channel(int handle, external_data_channel **channel)
201 {
202         auto it_channel = m_data_channels.find(handle);
203
204         if (it_channel == m_data_channels.end()) {
205                 _E("%s doesn't have data_channel for %s", get_client_name(), get_key(handle).c_str());
206                 return false;
207         }
208
209         *channel = it_channel->second;
210
211         return true;
212 }
213
214 bool external_sensor_manager::close_data_channel(void)
215 {
216         auto it_channel = m_data_channels.begin();
217
218         if (it_channel != m_data_channels.end()) {
219                 delete it_channel->second;
220                 ++it_channel;
221         }
222
223         m_data_channels.clear();
224
225         return true;
226 }
227
228 bool external_sensor_manager::close_data_channel(int handle)
229 {
230         auto it_channel = m_data_channels.find(handle);
231
232         if (it_channel == m_data_channels.end()) {
233                 _E("%s doesn't have data_channel for %s", get_client_name(), get_key(handle).c_str());
234                 return false;
235         }
236
237         delete it_channel->second;
238
239         m_data_channels.erase(it_channel);
240
241         return true;
242 }
243
244 bool external_sensor_manager::is_valid(int handle)
245 {
246         AUTOLOCK(m_handle_info_lock);
247
248         auto it_handle = m_sensor_handle_infos.find(handle);
249
250         if (it_handle == m_sensor_handle_infos.end())
251                 return false;
252
253         return true;
254 }
255
256 bool external_sensor_manager::is_active(void)
257 {
258         AUTOLOCK(m_handle_info_lock);
259
260         return !m_sensor_handle_infos.empty();
261 }
262
263 void external_sensor_manager::get_all_handles(vector<int> &handles)
264 {
265         AUTOLOCK(m_handle_info_lock);
266
267         auto it_handle = m_sensor_handle_infos.begin();
268
269         while (it_handle != m_sensor_handle_infos.end()) {
270                 handles.push_back(it_handle->first);
271                 ++it_handle;
272         }
273 }
274
275 bool external_sensor_manager::create_command_channel(void)
276 {
277         const int client_type = CLIENT_TYPE_EXTERNAL_SOURCE;
278         int client_id;
279         channel_ready_t channel_ready;
280
281         if (!m_command_socket.create(SOCK_SEQPACKET))
282                 return false;
283
284         if (!m_command_socket.connect(EVENT_CHANNEL_PATH)) {
285                 _E("Failed to connect command channel for client %s, command socket fd[%d]", get_client_name(), m_command_socket.get_socket_fd());
286                 return false;
287         }
288
289         m_command_socket.set_connection_mode();
290
291         if (m_command_socket.send(&client_type, sizeof(client_type)) <= 0) {
292                 _E("Failed to send client type in client %s, event socket fd[%d]", get_client_name(), m_command_socket.get_socket_fd());
293                 return false;
294         }
295
296         client_id = get_client_id();
297
298         if (m_command_socket.send(&client_id, sizeof(client_id)) <= 0) {
299                 _E("Failed to send client id for client %s on command socket[%d]", get_client_name(), m_command_socket.get_socket_fd());
300                 return false;
301         }
302
303         if (m_command_socket.recv(&channel_ready, sizeof(channel_ready)) <= 0) {
304                 _E("%s failed to recv command channel ready packet on command socket[%d] with client id [%d]",
305                         get_client_name(), m_command_socket.get_socket_fd(), client_id);
306                 return false;
307         }
308
309         if ((channel_ready.magic != CHANNEL_MAGIC_NUM) || (channel_ready.client_id != client_id)) {
310                 _E("Command channel ready packet is wrong, magic = %#x, client id = %d",
311                         channel_ready.magic, channel_ready.client_id);
312                 return false;
313         }
314
315         _I("Command channel is established for client %s on socket[%d] with client id : %d",
316                 get_client_name(), m_command_socket.get_socket_fd(), client_id);
317
318         return true;
319 }
320
321 void external_sensor_manager::close_command_channel(void)
322 {
323         m_command_socket.close();
324 }
325
326 bool external_sensor_manager::start_command_listener(void)
327 {
328         if (!create_command_channel()) {
329                 _E("Command channel is not established for %s", get_client_name());
330                 return false;
331         }
332
333         m_command_socket.set_transfer_mode();
334
335         m_poller = new(std::nothrow) poller(m_command_socket.get_socket_fd());
336         retvm_if(!m_poller, false, "Failed to allocate memory");
337
338         set_thread_state(THREAD_STATE_START);
339
340         thread listener(&external_sensor_manager::listen_command, this);
341         listener.detach();
342
343         return true;
344 }
345
346 void external_sensor_manager::stop_command_listener(void)
347 {
348         const int THREAD_TERMINATING_TIMEOUT = 2;
349
350         ulock u(m_thread_mutex);
351
352         if (m_thread_state != THREAD_STATE_TERMINATE) {
353                 m_thread_state = THREAD_STATE_STOP;
354
355                 _D("%s is waiting listener thread[state: %d] to be terminated", get_client_name(), m_thread_state);
356                 if (m_thread_cond.wait_for(u, std::chrono::seconds(THREAD_TERMINATING_TIMEOUT))
357                         == std::cv_status::timeout)
358                         _E("Fail to stop listener thread after waiting %d seconds", THREAD_TERMINATING_TIMEOUT);
359                 else
360                         _D("Listener thread for %s is terminated", get_client_name());
361         }
362 }
363
364 void external_sensor_manager::set_thread_state(thread_state state)
365 {
366         lock l(m_thread_mutex);
367         m_thread_state = state;
368 }
369
370 bool external_sensor_manager::get_cb_info(sensor_id_t sensor, char* data, int data_cnt, command_cb_info &cb_info)
371 {
372         int handle;
373         const sensor_ext_handle_info *handle_info;
374
375         AUTOLOCK(m_handle_info_lock);
376
377         handle = get_handle(sensor);
378
379         if (handle < 0)
380                 return false;
381
382         get_handle_info(handle, handle_info);
383
384         cb_info.handle = handle_info->m_handle;
385         cb_info.sensor = handle_info->m_sensor;
386         cb_info.cb = handle_info->m_cb;
387         cb_info.data = data;
388         cb_info.data_cnt = data_cnt;
389         cb_info.user_data = handle_info->m_user_data;
390
391         return true;
392 }
393
394 bool external_sensor_manager::sensor_command_poll(void* buffer, int buffer_len, struct epoll_event &event)
395 {
396         ssize_t len;
397
398         len = m_command_socket.recv(buffer, buffer_len);
399
400         if (!len) {
401                 if (!m_poller->poll(event))
402                         return false;
403                 len = m_command_socket.recv(buffer, buffer_len);
404
405                 if (len <= 0) {
406                         _I("%s failed to read after poll!", get_client_name());
407                         return false;
408                 }
409         } else if (len < 0) {
410                 _I("%s failed to recv command from command socket", get_client_name());
411                 return false;
412         }
413
414         return true;
415 }
416
417 void external_sensor_manager::post_callback_to_main_loop(command_cb_info* cb_info)
418 {
419         g_idle_add_full(G_PRIORITY_DEFAULT, callback_dispatcher, cb_info, NULL);
420 }
421
422 void external_sensor_manager::handle_command(sensor_id_t sensor, char* data, int data_cnt)
423 {
424         command_cb_info *cb_info = NULL;
425
426         {       /* scope for the lock */
427                 AUTOLOCK(m_handle_info_lock);
428
429                 cb_info = new(std::nothrow) command_cb_info;
430                 if (!cb_info) {
431                         _E("Failed to allocate memory");
432                         delete[] data;
433                         return;
434                 }
435
436                 if (!get_cb_info(sensor, data, data_cnt, *cb_info)) {
437                         delete[] data;
438                         delete cb_info;
439                         _E("Sensor %d is not connected, so command is discarded", sensor);
440                         return;
441                 }
442         }
443
444         if (cb_info)
445                 post_callback_to_main_loop(cb_info);
446 }
447
448 void external_sensor_manager::listen_command(void)
449 {
450         external_command_header_t command_header;
451         struct epoll_event event;
452         event.events = EPOLLIN | EPOLLPRI;
453
454         do {
455                 lock l(m_thread_mutex);
456                 if (m_thread_state == THREAD_STATE_START) {
457                         if (!sensor_command_poll(&command_header, sizeof(command_header), event)) {
458                                 _I("Failed to poll command header");
459                                 break;
460                         }
461
462                         char *command = new(std::nothrow) char[command_header.command_len];
463                         if (!command) {
464                                 _E("Failed to allocated memory");
465                                 break;
466                         }
467
468                         if (!sensor_command_poll(command, command_header.command_len, event)) {
469                                 _I("Failed to poll command data");
470                                 delete []command;
471                                 break;
472                         }
473
474                         handle_command(command_header.sensor_id, command, command_header.command_len);
475                 } else {
476                         break;
477                 }
478         } while (true);
479
480         if (m_poller != NULL) {
481                 delete m_poller;
482                 m_poller = NULL;
483         }
484
485         close_command_channel();
486
487         { /* the scope for the lock */
488                 lock l(m_thread_mutex);
489                 m_thread_state = THREAD_STATE_TERMINATE;
490                 m_thread_cond.notify_one();
491         }
492
493         _I("Command listener thread is terminated.");
494
495         if (has_client_id() && (event.events & EPOLLHUP)) {
496                 if (m_hup_observer)
497                         m_hup_observer();
498         }
499 }
500
501 bool external_sensor_manager::is_valid_callback(const command_cb_info *cb_info)
502 {
503         sensor_id_t sensor;
504
505         if (!external_sensor_manager::get_instance().get_sensor(cb_info->handle, sensor))
506                 return false;
507
508         return (cb_info->sensor == sensor);
509 }
510
511 gboolean external_sensor_manager::callback_dispatcher(gpointer data)
512 {
513         const command_cb_info *cb_info = reinterpret_cast<const command_cb_info*>(data);
514
515         if (external_sensor_manager::get_instance().is_valid_callback(cb_info)) {
516                 reinterpret_cast<sensor_external_command_cb_t>(cb_info->cb)(cb_info->handle, cb_info->data, cb_info->data_cnt, cb_info->user_data);
517         } else {
518                 _W("Discard invalid callback cb(%#x)(%d, %#x, %d, %#x)",
519                 cb_info->cb, cb_info->handle, cb_info->data, cb_info->data_cnt, cb_info->user_data);
520         }
521
522         delete[] cb_info->data;
523         delete cb_info;
524
525 /*
526 *       To be called only once, it returns false
527 */
528         return false;
529 }
530
531 void external_sensor_manager::clear(void)
532 {
533         close_command_channel();
534         stop_command_listener();
535         close_data_channel();
536         m_sensor_handle_infos.clear();
537         set_client_id(CLIENT_ID_INVALID);
538 }
539
540 void external_sensor_manager::set_hup_observer(hup_observer_t observer)
541 {
542         m_hup_observer = observer;
543 }