4 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 #include <csensor_event_dispatcher.h>
21 #include <sensor_plugin_loader.h>
23 #include <sf_common.h>
29 #define MAX_PENDING_CONNECTION 32
31 csensor_event_dispatcher::csensor_event_dispatcher()
34 m_sensor_fusion = sensor_plugin_loader::get_instance().get_fusion();
37 csensor_event_dispatcher::~csensor_event_dispatcher() { }
39 bool csensor_event_dispatcher::run(void)
41 INFO("Starting Event Dispatcher");
43 if (!m_accept_socket.create(SOCK_SEQPACKET)) {
44 ERR("Listener Socket Creation failed in Server");
48 if (!m_accept_socket.bind(EVENT_CHANNEL_PATH)) {
49 ERR("Listener Socket Binding failed in Server");
50 m_accept_socket.close();
54 if (!m_accept_socket.listen(MAX_PENDING_CONNECTION)) {
55 ERR("Socket Listen failed in Server");
59 thread accepter(&csensor_event_dispatcher::accept_connections, this);
62 thread dispatcher(&csensor_event_dispatcher::dispatch_event, this);
68 void csensor_event_dispatcher::accept_event_channel(csocket client_socket)
71 event_channel_ready_t event_channel_ready;
72 cclient_info_manager &client_info_manager = get_client_info_manager();
73 client_socket.set_connection_mode();
75 if (client_socket.recv(&client_id, sizeof(client_id)) <= 0) {
76 ERR("Failed to receive client id on socket fd[%d]", client_socket.get_socket_fd());
80 client_socket.set_transfer_mode();
83 if (!get_client_info_manager().set_event_socket(client_id, client_socket)) {
84 ERR("Failed to store event socket[%d] for %s", client_socket.get_socket_fd(),
85 client_info_manager.get_client_info(client_id));
89 event_channel_ready.magic = EVENT_CHANNEL_MAGIC;
90 event_channel_ready.client_id = client_id;
92 INFO("Event channel is accepted for %s on socket[%d]",
93 client_info_manager.get_client_info(client_id), client_socket.get_socket_fd());
95 if (client_socket.send(&event_channel_ready, sizeof(event_channel_ready)) <= 0) {
96 ERR("Failed to send event_channel_ready packet to %s on socket fd[%d]",
97 client_info_manager.get_client_info(client_id), client_socket.get_socket_fd());
102 void csensor_event_dispatcher::accept_connections(void)
104 INFO("Event channel acceptor is started.");
107 csocket client_socket;
109 if (!m_accept_socket.accept(client_socket)) {
110 ERR("Accepting socket failed in Server");
114 INFO("New client connected (socket_fd : %d)", client_socket.get_socket_fd());
115 thread event_channel_creator(&csensor_event_dispatcher::accept_event_channel, this, client_socket);
116 event_channel_creator.detach();
120 void csensor_event_dispatcher::dispatch_event(void)
122 const int MAX_EVENT_PER_SENSOR = 16;
123 const int MAX_SENSOR_EVENT = 1 + (sensor_plugin_loader::get_instance().get_virtual_sensors().size()
124 * MAX_EVENT_PER_SENSOR);
125 const int MAX_SYNTH_PER_SENSOR = 5;
126 INFO("Event Dispatcher started");
127 m_lcd_on = is_lcd_on();
129 if (vconf_notify_key_changed(VCONFKEY_PM_STATE, situation_watcher, this) != 0)
130 ERR("Fail to set notify callback for %s", VCONFKEY_PM_STATE);
133 bool is_hub_event = false;
134 event_situation situation;
135 void *seed_event = get_event_queue().pop();
136 unsigned int event_type = *((unsigned int *)(seed_event));
138 if (is_sensorhub_event(event_type))
142 situation = SITUATION_LCD_ON;
144 situation = SITUATION_LCD_OFF;
147 sensorhub_event_t *sensorhub_event = (sensorhub_event_t *)seed_event;
148 sensorhub_event->situation = situation;
149 send_sensor_events(sensorhub_event, 1, true, situation);
151 sensor_event_t sensor_events[MAX_SENSOR_EVENT];
152 unsigned int event_cnt = 0;
153 sensor_events[event_cnt++] = *((sensor_event_t *)seed_event);
155 if (m_sensor_fusion) {
156 if (m_sensor_fusion->is_started())
157 m_sensor_fusion->fuse(*((sensor_event_t *)seed_event));
160 virtual_sensors v_sensors = get_active_virtual_sensors();
161 virtual_sensors::iterator it_v_sensor;
162 it_v_sensor = v_sensors.begin();
163 vector<sensor_event_t> v_sensor_events;
164 v_sensor_events.reserve(MAX_SYNTH_PER_SENSOR);
166 while (it_v_sensor != v_sensors.end()) {
168 v_sensor_events.clear();
169 (*it_v_sensor)->synthesize(*((sensor_event_t *)seed_event), v_sensor_events);
170 synthesized_cnt = v_sensor_events.size();
172 for (int i = 0; i < synthesized_cnt; ++i)
173 sensor_events[event_cnt++] = v_sensor_events[i];
178 sort_sensor_events(sensor_events, event_cnt);
180 for (int i = 0; i < event_cnt; ++i) {
181 sensor_events[i].situation = situation;
183 if (is_record_event(sensor_events[i].event_type))
184 put_last_event(sensor_events[i].event_type, sensor_events[i]);
187 send_sensor_events(sensor_events, event_cnt, false, situation);
191 delete (sensorhub_event_t *)seed_event;
193 delete (sensor_event_t *)seed_event;
197 void csensor_event_dispatcher::send_sensor_events(void *events, int event_cnt, bool is_hub_event, event_situation situation)
199 sensor_event_t *sensor_events;
200 sensorhub_event_t *sensor_hub_events;
201 cclient_info_manager &client_info_manager = get_client_info_manager();
204 sensor_hub_events = (sensorhub_event_t *)events;
206 sensor_events = (sensor_event_t *)events;
208 for (int i = 0; i < event_cnt; ++i) {
209 client_id_vec id_vec;
210 unsigned int event_type;
213 event_type = sensor_hub_events[i].event_type;
215 event_type = sensor_events[i].event_type;
217 client_info_manager.get_listener_ids(event_type, situation, id_vec);
218 client_id_vec::iterator it_client_id;
219 it_client_id = id_vec.begin();
221 while (it_client_id != id_vec.end()) {
222 csocket client_socket;
223 client_info_manager.get_event_socket(*it_client_id, client_socket);
227 ret = (client_socket.send(sensor_hub_events + i, sizeof(sensorhub_event_t)) > 0);
229 ret = (client_socket.send(sensor_events + i, sizeof(sensor_event_t)) > 0);
232 DBG("Event[0x%x] sent to %s on socket[%d]", event_type, client_info_manager.get_client_info(*it_client_id), client_socket.get_socket_fd());
234 ERR("Failed to send event[0x%x] to %s on socket[%d]", event_type, client_info_manager.get_client_info(*it_client_id), client_socket.get_socket_fd());
241 bool csensor_event_dispatcher::is_lcd_on(void)
245 if (vconf_get_int(VCONFKEY_PM_STATE, &lcd_state) != 0) {
246 ERR("Can't get the value of VCONFKEY_PM_STATE");
250 if (lcd_state == VCONFKEY_PM_STATE_LCDOFF)
256 cclient_info_manager &csensor_event_dispatcher::get_client_info_manager(void)
258 return cclient_info_manager::get_instance();
261 csensor_event_queue &csensor_event_dispatcher::get_event_queue(void)
263 return csensor_event_queue::get_instance();
266 bool csensor_event_dispatcher::is_record_event(unsigned int event_type)
268 switch (event_type) {
269 case ACCELEROMETER_EVENT_ROTATION_CHECK:
279 void csensor_event_dispatcher::put_last_event(unsigned int event_type, const sensor_event_t &event)
281 AUTOLOCK(m_last_events_mutex);
282 m_last_events[event_type] = event;
285 bool csensor_event_dispatcher::get_last_event(unsigned int event_type, sensor_event_t &event)
287 AUTOLOCK(m_last_events_mutex);
288 event_type_last_event_map::iterator it_event;
289 it_event = m_last_events.find(event_type);
291 if (it_event == m_last_events.end())
294 event = it_event->second;
298 bool csensor_event_dispatcher::has_active_virtual_sensor(virtual_sensor *sensor)
300 AUTOLOCK(m_active_virtual_sensors_mutex);
301 virtual_sensors::iterator it_v_sensor;
302 it_v_sensor = find(m_active_virtual_sensors.begin(), m_active_virtual_sensors.end(), sensor);
303 return (it_v_sensor != m_active_virtual_sensors.end());
306 virtual_sensors csensor_event_dispatcher::get_active_virtual_sensors(void)
308 AUTOLOCK(m_active_virtual_sensors_mutex);
309 return m_active_virtual_sensors;
312 bool csensor_event_dispatcher::compare_by_timestamp(const sensor_event_t &a, const sensor_event_t &b)
314 return a.data.timestamp < b.data.timestamp;
317 void csensor_event_dispatcher::sort_sensor_events(sensor_event_t *events, unsigned int cnt)
319 std::sort(events, events + cnt, compare_by_timestamp);
322 void csensor_event_dispatcher::request_last_event(int client_id, const sensor_type_t sensor)
324 cclient_info_manager &client_info_manager = get_client_info_manager();
325 event_type_vector event_vec;
326 csocket client_socket;
328 if (client_info_manager.get_registered_events(client_id, sensor, event_vec)) {
329 client_info_manager.get_event_socket(client_id, client_socket);
330 event_type_vector::iterator it_event;
331 it_event = event_vec.begin();
333 while (it_event != event_vec.end()) {
334 sensor_event_t event;
336 if (is_record_event(*it_event) && get_last_event(*it_event, event)) {
337 if (client_socket.send(&event, sizeof(event)) > 0)
338 INFO("Send the last event[0x%x] to %s on socket[%d]", event.event_type,
339 client_info_manager.get_client_info(client_id), client_socket.get_socket_fd());
341 ERR("Failed to send event[0x%x] to %s on socket[%d]", event.event_type,
342 client_info_manager.get_client_info(client_id), client_socket.get_socket_fd());
350 bool csensor_event_dispatcher::add_active_virtual_sensor(virtual_sensor *sensor)
352 AUTOLOCK(m_active_virtual_sensors_mutex);
354 if (has_active_virtual_sensor(sensor)) {
355 ERR("[%s] sensor is already added on active virtual sensors", sensor->get_name());
359 m_active_virtual_sensors.push_back(sensor);
363 bool csensor_event_dispatcher::delete_active_virtual_sensor(virtual_sensor *sensor)
365 AUTOLOCK(m_active_virtual_sensors_mutex);
366 virtual_sensors::iterator it_v_sensor;
367 it_v_sensor = find(m_active_virtual_sensors.begin(), m_active_virtual_sensors.end(), sensor);
369 if (it_v_sensor == m_active_virtual_sensors.end()) {
370 ERR("Fail to delete non-existent [%s] sensor on active virtual sensors", sensor->get_name());
374 m_active_virtual_sensors.erase(it_v_sensor);
378 void csensor_event_dispatcher::situation_watcher(keynode_t *node, void *user_data)
380 csensor_event_dispatcher *dispatcher = (csensor_event_dispatcher *) user_data;
382 if (!strcmp(vconf_keynode_get_name(node), VCONFKEY_PM_STATE))
383 dispatcher->m_lcd_on = dispatcher->is_lcd_on();