4 * Copyright (c) 2015 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.
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>
32 external_sensor_manager::external_sensor_manager()
33 : m_client_id(CLIENT_ID_INVALID)
35 , m_thread_state(THREAD_STATE_TERMINATE)
36 , m_hup_observer(NULL)
40 external_sensor_manager::~external_sensor_manager()
42 stop_command_listener();
45 external_sensor_manager& external_sensor_manager::get_instance(void)
47 static external_sensor_manager inst;
51 int external_sensor_manager::create_handle(void)
53 sensor_ext_handle_info handle_info;
56 AUTOLOCK(m_handle_info_lock);
58 while (m_sensor_handle_infos.count(handle) > 0)
61 if (handle >= MAX_HANDLE) {
62 _E("Handles of client %s are full", get_client_name());
63 return MAX_HANDLE_REACHED;
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;
71 m_sensor_handle_infos.insert(pair<int, sensor_ext_handle_info>(handle, handle_info));
76 bool external_sensor_manager::delete_handle(int handle)
78 AUTOLOCK(m_handle_info_lock);
80 auto it_handle = m_sensor_handle_infos.find(handle);
82 if (it_handle == m_sensor_handle_infos.end()) {
83 _E("Handle[%d] is not found for client %s", handle, get_client_name());
87 m_sensor_handle_map.erase(it_handle->second.m_sensor);
88 m_sensor_handle_infos.erase(it_handle);
93 bool external_sensor_manager::set_handle(int handle, sensor_id_t sensor, const string& key, void* cb, void* user_data)
95 AUTOLOCK(m_handle_info_lock);
97 auto it_handle = m_sensor_handle_infos.find(handle);
99 if (it_handle == m_sensor_handle_infos.end()) {
100 _E("Handle[%d] is not found for client %s", handle, get_client_name());
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;
109 m_sensor_handle_map.insert(pair<sensor_id_t, int>(sensor, handle));
114 bool external_sensor_manager::get_sensor(int handle, sensor_id_t &sensor)
116 AUTOLOCK(m_handle_info_lock);
118 auto it_handle = m_sensor_handle_infos.find(handle);
120 if (it_handle == m_sensor_handle_infos.end()) {
121 _E("Handle[%d] is not found for client %s", handle, get_client_name());
125 sensor = it_handle->second.m_sensor;
130 int external_sensor_manager::get_handle(sensor_id_t sensor)
132 AUTOLOCK(m_handle_info_lock);
134 auto it_handle = m_sensor_handle_map.find(sensor);
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);
141 return it_handle->second;
144 bool external_sensor_manager::get_handle_info(int handle, const sensor_ext_handle_info*& handle_info)
146 AUTOLOCK(m_handle_info_lock);
148 auto it_handle = m_sensor_handle_infos.find(handle);
150 if (it_handle == m_sensor_handle_infos.end()) {
151 _E("Handle[%d] is not found for client %s", handle, get_client_name());
155 handle_info = &(it_handle->second);
159 string external_sensor_manager::get_key(int handle)
161 AUTOLOCK(m_handle_info_lock);
163 auto it_handle = m_sensor_handle_infos.find(handle);
165 if (it_handle == m_sensor_handle_infos.end()) {
166 return string("INVALID_KEY");
169 return it_handle->second.m_key;
172 bool external_sensor_manager::has_client_id(void)
174 return (m_client_id != CLIENT_ID_INVALID);
177 int external_sensor_manager::get_client_id(void)
182 void external_sensor_manager::set_client_id(int client_id)
184 m_client_id = client_id;
187 bool external_sensor_manager::add_data_channel(int handle, external_data_channel *channel)
189 auto it_channel = m_data_channels.find(handle);
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());
196 m_data_channels.insert(pair<int, external_data_channel *>(handle, channel));
200 bool external_sensor_manager::get_data_channel(int handle, external_data_channel **channel)
202 auto it_channel = m_data_channels.find(handle);
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());
209 *channel = it_channel->second;
214 bool external_sensor_manager::close_data_channel(void)
216 auto it_channel = m_data_channels.begin();
218 if (it_channel != m_data_channels.end()) {
219 delete it_channel->second;
223 m_data_channels.clear();
228 bool external_sensor_manager::close_data_channel(int handle)
230 auto it_channel = m_data_channels.find(handle);
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());
237 delete it_channel->second;
239 m_data_channels.erase(it_channel);
244 bool external_sensor_manager::is_valid(int handle)
246 AUTOLOCK(m_handle_info_lock);
248 auto it_handle = m_sensor_handle_infos.find(handle);
250 if (it_handle == m_sensor_handle_infos.end())
256 bool external_sensor_manager::is_active(void)
258 AUTOLOCK(m_handle_info_lock);
260 return !m_sensor_handle_infos.empty();
263 void external_sensor_manager::get_all_handles(vector<int> &handles)
265 AUTOLOCK(m_handle_info_lock);
267 auto it_handle = m_sensor_handle_infos.begin();
269 while (it_handle != m_sensor_handle_infos.end()) {
270 handles.push_back(it_handle->first);
275 bool external_sensor_manager::create_command_channel(void)
277 const int client_type = CLIENT_TYPE_EXTERNAL_SOURCE;
279 channel_ready_t channel_ready;
281 if (!m_command_socket.create(SOCK_SEQPACKET))
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());
289 m_command_socket.set_connection_mode();
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());
296 client_id = get_client_id();
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());
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);
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);
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);
321 void external_sensor_manager::close_command_channel(void)
323 m_command_socket.close();
326 bool external_sensor_manager::start_command_listener(void)
328 if (!create_command_channel()) {
329 _E("Command channel is not established for %s", get_client_name());
333 m_command_socket.set_transfer_mode();
335 m_poller = new(std::nothrow) poller(m_command_socket.get_socket_fd());
336 retvm_if(!m_poller, false, "Failed to allocate memory");
338 set_thread_state(THREAD_STATE_START);
340 thread listener(&external_sensor_manager::listen_command, this);
346 void external_sensor_manager::stop_command_listener(void)
348 const int THREAD_TERMINATING_TIMEOUT = 2;
350 ulock u(m_thread_mutex);
352 if (m_thread_state != THREAD_STATE_TERMINATE) {
353 m_thread_state = THREAD_STATE_STOP;
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);
360 _D("Listener thread for %s is terminated", get_client_name());
364 void external_sensor_manager::set_thread_state(thread_state state)
366 lock l(m_thread_mutex);
367 m_thread_state = state;
370 bool external_sensor_manager::get_cb_info(sensor_id_t sensor, char* data, int data_cnt, command_cb_info &cb_info)
373 const sensor_ext_handle_info *handle_info;
375 AUTOLOCK(m_handle_info_lock);
377 handle = get_handle(sensor);
382 get_handle_info(handle, handle_info);
384 cb_info.handle = handle_info->m_handle;
385 cb_info.sensor = handle_info->m_sensor;
386 cb_info.cb = handle_info->m_cb;
388 cb_info.data_cnt = data_cnt;
389 cb_info.user_data = handle_info->m_user_data;
394 bool external_sensor_manager::sensor_command_poll(void* buffer, int buffer_len, struct epoll_event &event)
398 len = m_command_socket.recv(buffer, buffer_len);
401 if (!m_poller->poll(event))
403 len = m_command_socket.recv(buffer, buffer_len);
406 _I("%s failed to read after poll!", get_client_name());
409 } else if (len < 0) {
410 _I("%s failed to recv command from command socket", get_client_name());
417 void external_sensor_manager::post_callback_to_main_loop(command_cb_info* cb_info)
419 g_idle_add_full(G_PRIORITY_DEFAULT, callback_dispatcher, cb_info, NULL);
422 void external_sensor_manager::handle_command(sensor_id_t sensor, char* data, int data_cnt)
424 command_cb_info *cb_info = NULL;
426 { /* scope for the lock */
427 AUTOLOCK(m_handle_info_lock);
429 cb_info = new(std::nothrow) command_cb_info;
431 _E("Failed to allocate memory");
436 if (!get_cb_info(sensor, data, data_cnt, *cb_info)) {
439 _E("Sensor %d is not connected, so command is discarded", sensor);
445 post_callback_to_main_loop(cb_info);
448 void external_sensor_manager::listen_command(void)
450 external_command_header_t command_header;
451 struct epoll_event event;
452 event.events = EPOLLIN | EPOLLPRI;
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");
462 char *command = new(std::nothrow) char[command_header.command_len];
464 _E("Failed to allocated memory");
468 if (!sensor_command_poll(command, command_header.command_len, event)) {
469 _I("Failed to poll command data");
474 handle_command(command_header.sensor_id, command, command_header.command_len);
480 if (m_poller != NULL) {
485 close_command_channel();
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();
493 _I("Command listener thread is terminated.");
495 if (has_client_id() && (event.events & EPOLLHUP)) {
501 bool external_sensor_manager::is_valid_callback(const command_cb_info *cb_info)
505 if (!external_sensor_manager::get_instance().get_sensor(cb_info->handle, sensor))
508 return (cb_info->sensor == sensor);
511 gboolean external_sensor_manager::callback_dispatcher(gpointer data)
513 const command_cb_info *cb_info = reinterpret_cast<const command_cb_info*>(data);
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);
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);
522 delete[] cb_info->data;
526 * To be called only once, it returns false
531 void external_sensor_manager::clear(void)
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);
540 void external_sensor_manager::set_hup_observer(hup_observer_t observer)
542 m_hup_observer = observer;