Merge branch 'tizen_3.0' into devel/tizen
[platform/core/system/sensord.git] / src / client / external_data_channel.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 <command_common.h>
20 #include <sensor_types.h>
21 #include <external_data_channel.h>
22
23 using std::string;
24
25 external_data_channel::external_data_channel()
26 : m_client_id(CLIENT_ID_INVALID)
27 , m_sensor_id(UNKNOWN_SENSOR)
28 {
29 }
30
31 external_data_channel::~external_data_channel()
32 {
33         m_socket.close();
34 }
35
36 bool external_data_channel::command_handler(cpacket *packet, void **return_payload)
37 {
38         packet_header header;
39         char *buffer = NULL;
40
41         if (!m_socket.is_valid()) {
42                 _E("Socket(%d) is not valid for client %s", m_socket.get_socket_fd(), get_client_name());
43                 return false;
44         }
45
46         if (!packet->size()) {
47                 _E("Packet is not valid for client %s", get_client_name());
48                 return false;
49         }
50
51         if (m_socket.send(packet->packet(), packet->size()) <= 0) {
52                 m_socket.close();
53                 _E("Failed to send command in client %s", get_client_name());
54                 return false;
55         }
56
57         if (m_socket.recv(&header, sizeof(header)) <= 0) {
58                 m_socket.close();
59                 _E("Failed to receive header for command packet in client %s", get_client_name());
60                 return false;
61         }
62
63         buffer = new(std::nothrow) char[header.size];
64         retvm_if(!buffer, false, "Failed to allocate memory");
65
66         if (m_socket.recv(buffer, header.size) <= 0) {
67                 m_socket.close();
68                 _E("Failed to receive command packet in client %s", get_client_name());
69                 delete[] buffer;
70                 return false;
71         }
72
73         *return_payload = buffer;
74
75         return true;
76 }
77
78 bool external_data_channel::create_channel(void)
79 {
80         const int client_type = CLIENT_TYPE_EXTERNAL_SOURCE;
81
82         if (!m_socket.create(SOCK_STREAM)) {
83                 _E("Failed to create external data channel for client %s", get_client_name());
84                 return false;
85         }
86
87         if (!m_socket.connect(COMMAND_CHANNEL_PATH)) {
88                 _E("Failed to connect external data channel for client %s, command socket fd[%d]", get_client_name(), m_socket.get_socket_fd());
89                 return false;
90         }
91
92         m_socket.set_connection_mode();
93
94         if (m_socket.send(&client_type, sizeof(client_type)) <= 0) {
95                 _E("Failed to send client type in client %s, command socket fd[%d]", get_client_name(), m_socket.get_socket_fd());
96                 return false;
97         }
98
99         return true;
100 }
101
102 void external_data_channel::set_client_id(int client_id)
103 {
104         m_client_id = client_id;
105 }
106
107 bool external_data_channel::cmd_get_id(int &client_id)
108 {
109         cpacket *packet;
110         cmd_ext_get_id_t *cmd_ext_get_id;
111         cmd_ext_get_id_done_t *cmd_ext_get_id_done;
112
113         packet = new(std::nothrow) cpacket(sizeof(cmd_ext_get_id_t));
114         retvm_if(!packet, false, "Failed to allocate memory");
115
116         packet->set_cmd(CMD_EXT_GET_ID);
117
118         cmd_ext_get_id = (cmd_ext_get_id_t *)packet->data();
119
120         get_proc_name(getpid(), cmd_ext_get_id->name);
121
122         _I("%s send cmd_get_id()", get_client_name());
123
124         if (!command_handler(packet, (void **)&cmd_ext_get_id_done)) {
125                 _E("Client %s failed to send/receive command", get_client_name());
126                 delete packet;
127                 return false;
128         }
129
130         if (cmd_ext_get_id_done->client_id < 0) {
131                 _E("Client %s failed to get client_id[%d] from server",
132                         get_client_name(), cmd_ext_get_id_done->client_id);
133                 delete[] (char *)cmd_ext_get_id_done;
134                 delete packet;
135                 return false;
136         }
137
138         client_id = cmd_ext_get_id_done->client_id;
139
140         delete[] (char *)cmd_ext_get_id_done;
141         delete packet;
142
143         return true;
144 }
145
146 bool external_data_channel::cmd_connect(const string &key, sensor_id_t &sensor_id)
147 {
148         cpacket *packet;
149         cmd_ext_connect_t *cmd_ext_connect;
150         cmd_ext_connect_done_t *cmd_ext_connect_done;
151
152         int key_size = key.size();
153
154         if ((key_size == 0) || (key_size >= NAME_MAX)) {
155                 _I("Key(%s) is not valid", key.c_str());
156                 return false;
157         }
158
159         packet = new(std::nothrow) cpacket(sizeof(cmd_ext_connect_t));
160         retvm_if(!packet, false, "Failed to allocate memory");
161
162         packet->set_cmd(CMD_EXT_CONNECT);
163
164         cmd_ext_connect = (cmd_ext_connect_t *)packet->data();
165         cmd_ext_connect->client_id = m_client_id;
166         strncpy(cmd_ext_connect->key, key.c_str(), NAME_MAX-1);
167
168         _I("%s send cmd_get_connect(key = %s, client_id = %d)", get_client_name(), key.c_str(), m_client_id);
169
170         if (!command_handler(packet, (void **)&cmd_ext_connect_done)) {
171                 _E("Client %s failed to send/receive command", get_client_name());
172                 delete packet;
173                 return false;
174         }
175
176         if (cmd_ext_connect_done->sensor_id == UNKNOWN_SENSOR) {
177                 _E("Client %s failed to connect to external sensor", get_client_name());
178                 delete[] (char *)cmd_ext_connect_done;
179                 delete packet;
180                 return false;
181         }
182
183         m_sensor_id = sensor_id = cmd_ext_connect_done->sensor_id;
184
185         delete[] (char *)cmd_ext_connect_done;
186         delete packet;
187
188         return true;
189 }
190
191 bool external_data_channel::cmd_disconnect(void)
192 {
193         cpacket *packet;
194         cmd_ext_done_t *cmd_ext_done;
195
196         packet = new(std::nothrow) cpacket(sizeof(cmd_ext_disconnect_t));
197         retvm_if(!packet, false, "Failed to allocate memory");
198
199         packet->set_cmd(CMD_EXT_DISCONNECT);
200
201         _I("%s send cmd_disconnect(client_id=%d)", get_client_name(), m_client_id);
202
203         if (!command_handler(packet, (void **)&cmd_ext_done)) {
204                 _E("Client %s failed to send/receive command  with client_id [%d]",
205                         get_client_name(), m_client_id);
206                 delete packet;
207                 return false;
208         }
209
210         if (cmd_ext_done->value < 0) {
211                 _E("Client %s got error[%d] from server with client_id [%d]",
212                         get_client_name(), cmd_ext_done->value, m_client_id);
213
214                 delete[] (char *)cmd_ext_done;
215                 delete packet;
216                 return false;
217         }
218
219         delete[] (char *)cmd_ext_done;
220         delete packet;
221
222         m_socket.close();
223         m_client_id = CLIENT_ID_INVALID;
224         return true;
225 }
226
227 bool external_data_channel::cmd_post(unsigned long long timestamp, const float *data, int data_cnt)
228 {
229         cpacket *packet;
230         cmd_ext_post_t *cmd_ext_post;
231         cmd_done_t *cmd_done;
232
233         packet = new(std::nothrow) cpacket(sizeof(cmd_ext_post_t) + sizeof(float) * data_cnt);
234         retvm_if(!packet, false, "Failed to allocate memory");
235
236         packet->set_cmd(CMD_EXT_POST);
237
238         cmd_ext_post = (cmd_ext_post_t*)packet->data();
239         cmd_ext_post->timestamp = timestamp;
240         cmd_ext_post->data_cnt = data_cnt;
241         memcpy(cmd_ext_post->data, data, sizeof(float) * data_cnt);
242
243         _I("%s send cmd_post(client_id=%d, data = %#x, data_cnt = %d)",
244                 get_client_name(), m_client_id, data, data_cnt);
245
246         if (!command_handler(packet, (void **)&cmd_done)) {
247                 _E("%s failed to send/receive command with client_id [%d]",
248                         get_client_name(), m_client_id);
249                 delete packet;
250                 return false;
251         }
252
253         if (cmd_done->value < 0) {
254                 _E("%s got error[%d] from server with client_id [%d]",
255                         get_client_name(), cmd_done->value, m_client_id);
256
257                 delete[] (char *)cmd_done;
258                 delete packet;
259                 return false;
260         }
261
262         delete[] (char *)cmd_done;
263         delete packet;
264
265         return true;
266 }