Merge "sensord: delete batch latency/attribute when client is terminated unexpectedly...
[platform/core/system/sensord.git] / src / server / external_sensor_service.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 <external_sensor_service.h>
20 #include <external_sensor.h>
21 #include <external_client_manager.h>
22 #include <command_queue.h>
23 #include <thread>
24
25 using std::thread;
26 using std::pair;
27 using std::string;
28 using std::shared_ptr;
29
30 external_sensor_service::external_sensor_service()
31 {
32 }
33
34 external_sensor_service::~external_sensor_service()
35 {
36 }
37
38 external_sensor_service& external_sensor_service::get_instance(void)
39 {
40         static external_sensor_service instance;
41         return instance;
42 }
43
44 bool external_sensor_service::run(void)
45 {
46         thread dispatcher(&external_sensor_service::dispatch_command, this);
47         dispatcher.detach();
48
49         return true;
50 }
51
52 external_client_manager& external_sensor_service::get_client_manager(void)
53 {
54         return external_client_manager::get_instance();
55 }
56
57 void external_sensor_service::accept_command_channel(csocket client_socket)
58 {
59         thread th = thread([&, client_socket]() mutable {
60                 int client_id;
61                 channel_ready_t command_channel_ready;
62                 external_client_manager& client_manager = get_client_manager();
63
64                 client_socket.set_connection_mode();
65
66                 if (client_socket.recv(&client_id, sizeof(client_id)) <= 0) {
67                         _E("Failed to receive client id on socket fd[%d]", client_socket.get_socket_fd());
68                         return;
69                 }
70
71                 client_socket.set_transfer_mode();
72
73                 if (!client_manager.set_command_socket(client_id, client_socket)) {
74                         _E("Failed to store event socket[%d] for %s", client_socket.get_socket_fd(),
75                                 client_manager.get_client_info(client_id));
76                         return;
77                 }
78
79                 command_channel_ready.magic = CHANNEL_MAGIC_NUM;
80                 command_channel_ready.client_id = client_id;
81
82                 _I("Command channel is accepted for %s on socket[%d]",
83                         client_manager.get_client_info(client_id), client_socket.get_socket_fd());
84
85                 if (client_socket.send(&command_channel_ready, sizeof(command_channel_ready)) <= 0) {
86                         _E("Failed to send command channel_ready packet to %s on socket fd[%d]",
87                                 client_manager.get_client_info(client_id), client_socket.get_socket_fd());
88                         return;
89                 }
90         });
91
92         th.detach();
93 }
94
95 void external_sensor_service::dispatch_command(void)
96 {
97         while (true) {
98                 shared_ptr<external_command_t> command = command_queue::get_instance().pop();
99                 csocket client_sock;
100                 sensor_id_t sensor_id = command->header.sensor_id;
101                 bool ret;
102
103                 ret = external_client_manager::get_instance().get_listener_socket(sensor_id, client_sock);
104
105                 if (!ret) {
106                         _E("Failed to get listener socket for sensor[%d]", sensor_id);
107                         continue;
108                 }
109
110                 if (client_sock.send(&(command->header), sizeof(command->header)) <= 0) {
111                         _E("Failed to send command header to the client of sensor[%d]", sensor_id);
112                         continue;
113                 }
114
115                 if (client_sock.send(command->command.data(), command->header.command_len) <= 0) {
116                         _E("Failed to send command header to the client of sensor[%d]", sensor_id);
117                         continue;
118                 }
119         }
120 }
121
122 bool external_sensor_service::register_sensor(external_sensor *sensor)
123 {
124         if (!m_external_sensors.insert(pair<string, external_sensor*>(sensor->get_key(), sensor)).second) {
125                 _E("Failed to register sensor, key: %s", sensor->get_key().c_str());
126                 return false;
127         }
128
129         return true;
130 }
131
132 bool external_sensor_service::unregister_sensor(external_sensor *sensor)
133 {
134         if (!m_external_sensors.erase(sensor->get_key())) {
135                 _E("Failed to unregister sensor, key: %s", sensor->get_key().c_str());
136                 return false;
137         }
138
139         return true;
140 }
141
142 external_sensor* external_sensor_service::get_sensor(const string& key)
143 {
144         auto it_sensor = m_external_sensors.find(key);
145
146         if (it_sensor == m_external_sensors.end()) {
147                 _E("Sensor(key:%s) is not found", key.c_str());
148                 return NULL;
149         }
150
151         return it_sensor->second;
152 }