Fix spelling errata
[platform/core/uifw/voice-control.git] / client / vc_setting_dbus.c
1 /*
2 * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "vc_setting_dbus.h"
18 #include "vc_main.h"
19
20
21 static int g_s_waiting_time = 3000;
22
23 static Ecore_Fd_Handler* g_s_fd_handler = NULL;
24
25 static DBusConnection* g_s_conn_sender = NULL;
26 static DBusConnection* g_s_conn_listener = NULL;
27
28
29 static Eina_Bool listener_setting_event_callback(void* data, Ecore_Fd_Handler *fd_handler)
30 {
31         if (NULL == g_s_conn_listener)  return ECORE_CALLBACK_RENEW;
32
33         dbus_connection_read_write_dispatch(g_s_conn_listener, 50);
34
35         while (1) {
36                 DBusMessage* msg = NULL;
37                 msg = dbus_connection_pop_message(g_s_conn_listener);
38
39                 /* loop again if we haven't read a message */
40                 if (NULL == msg) {
41                         break;
42                 }
43
44                 DBusError err;
45                 dbus_error_init(&err);
46
47                 char if_name[64] = {0, };
48                 snprintf(if_name, 64, "%s", VC_SETTING_SERVICE_INTERFACE);
49
50                 if (dbus_message_is_method_call(msg, if_name, VCD_METHOD_HELLO)) {
51                         SLOG(LOG_DEBUG, TAG_VCS, "@@@ Get Hello");
52                         int pid = 0;
53                         int response = -1;
54
55                         dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
56
57                         if (dbus_error_is_set(&err)) {
58                                 SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Dbus Error (%s)", err.message);
59                                 dbus_error_free(&err);
60                         }
61
62                         if (pid > 0) {
63                                 SLOG(LOG_DEBUG, TAG_VCS, "@@ vc get hello : pid(%d) ", pid);
64                                 response = 1;
65                         } else {
66                                 SLOG(LOG_ERROR, TAG_VCS, "@@ vc get hello : invalid pid ");
67                         }
68
69                         DBusMessage* reply = NULL;
70                         reply = dbus_message_new_method_return(msg);
71
72                         if (NULL != reply) {
73                                 dbus_message_append_args(reply, DBUS_TYPE_INT32, &response, DBUS_TYPE_INVALID);
74
75                                 if (!dbus_connection_send(g_s_conn_listener, reply, NULL))
76                                         SLOG(LOG_ERROR, TAG_VCS, "@@ vc get hello : fail to send reply");
77                                 else
78                                         SLOG(LOG_DEBUG, TAG_VCS, "@@ vc get hello : result(%d)", response);
79
80                                 dbus_connection_flush(g_s_conn_listener);
81                                 dbus_message_unref(reply);
82                         } else {
83                                 SLOG(LOG_ERROR, TAG_VCS, "@@ vc get hello : fail to create reply message");
84                         }
85
86                         SLOG(LOG_DEBUG, TAG_VCS, "@@@");
87                 } /* VCD_METHOD_HELLO */
88
89                 else {
90                         SLOG(LOG_DEBUG, TAG_VCS, "Message is NOT valid");
91                         dbus_message_unref(msg);
92                         break;
93                 }
94
95                 /* free the message */
96                 dbus_message_unref(msg);
97         } /* while(1) */
98
99         return ECORE_CALLBACK_PASS_ON;
100 }
101
102 static void __vc_setting_dbus_connection_free()
103 {
104         if (NULL != g_s_conn_listener) {
105                 dbus_connection_close(g_s_conn_listener);
106                 g_s_conn_listener = NULL;
107         }
108         if (NULL != g_s_conn_sender) {
109                 dbus_connection_close(g_s_conn_sender);
110                 g_s_conn_sender = NULL;
111         }
112 }
113
114 int vc_setting_dbus_open_connection()
115 {
116         if (NULL != g_s_conn_sender && NULL != g_s_conn_listener) {
117                 SLOG(LOG_WARN, TAG_VCS, "already existed connection ");
118                 return 0;
119         }
120
121         DBusError err;
122         int ret;
123
124         /* initialize the error value */
125         dbus_error_init(&err);
126
127         /* connect to the DBUS system bus, and check for errors */
128         g_s_conn_sender = dbus_bus_get_private(DBUS_BUS_SESSION, &err);
129
130         if (dbus_error_is_set(&err)) {
131                 SLOG(LOG_ERROR, TAG_VCS, "Dbus Connection Error (%s)", err.message);
132                 dbus_error_free(&err);
133         }
134
135         if (NULL == g_s_conn_sender) {
136                 SLOG(LOG_ERROR, TAG_VCS, "Fail to get dbus connection ");
137                 return VC_ERROR_OPERATION_FAILED;
138         }
139
140         g_s_conn_listener = dbus_bus_get_private(DBUS_BUS_SESSION, &err);
141
142         if (dbus_error_is_set(&err)) {
143                 SLOG(LOG_ERROR, TAG_VCS, "Dbus Connection Error (%s)", err.message);
144                 dbus_error_free(&err);
145         }
146
147         if (NULL == g_s_conn_listener) {
148                 SLOG(LOG_ERROR, TAG_VCS, "Fail to get dbus connection ");
149                 __vc_setting_dbus_connection_free();
150                 return VC_ERROR_OPERATION_FAILED;
151         }
152
153         int pid = getpid();
154
155         char service_name[64];
156         memset(service_name, '\0', 64);
157         snprintf(service_name, 64, "%s%d", VC_SETTING_SERVICE_NAME, pid);
158
159         SLOG(LOG_DEBUG, TAG_VCS, "service name is %s", service_name);
160
161         /* register our name on the bus, and check for errors */
162         ret = dbus_bus_request_name(g_s_conn_listener, service_name, DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
163
164         if (dbus_error_is_set(&err)) {
165                 SLOG(LOG_ERROR, TAG_VCS, "Name Error (%s)", err.message);
166                 dbus_error_free(&err);
167         }
168
169         if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
170                 SLOG(LOG_ERROR, TAG_VCS, "fail dbus_bus_request_name()");
171                 __vc_setting_dbus_connection_free();
172                 return -2;
173         }
174
175         if (NULL != g_s_fd_handler) {
176                 SLOG(LOG_WARN, TAG_VCS, "The handler already exists.");
177                 __vc_setting_dbus_connection_free();
178                 return 0;
179         }
180
181         char rule[128] = {0, };
182         snprintf(rule, 128, "type='signal',interface='%s'", VC_SETTING_SERVICE_INTERFACE);
183
184         /* add a rule for which messages we want to see */
185         dbus_bus_add_match(g_s_conn_listener, rule, &err);
186
187         if (dbus_error_is_set(&err)) {
188                 SLOG(LOG_ERROR, TAG_VCS, "Match Error (%s)", err.message);
189                 dbus_error_free(&err);
190                 __vc_setting_dbus_connection_free();
191                 return VC_ERROR_OPERATION_FAILED;
192         }
193
194         int fd = 0;
195         if (1 != dbus_connection_get_unix_fd(g_s_conn_listener, &fd)) {
196                 SLOG(LOG_ERROR, TAG_VCS, "fail to get fd from dbus ");
197                 __vc_setting_dbus_connection_free();
198                 return VC_ERROR_OPERATION_FAILED;
199         } else {
200                 SLOG(LOG_DEBUG, TAG_VCS, "Get fd from dbus : %d", fd);
201         }
202
203         g_s_fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)listener_setting_event_callback, g_s_conn_listener, NULL, NULL);
204         if (NULL == g_s_fd_handler) {
205                 SLOG(LOG_ERROR, TAG_VCS, "fail to get fd handler from ecore ");
206                 __vc_setting_dbus_connection_free();
207                 return VC_ERROR_OPERATION_FAILED;
208         }
209
210         return 0;
211 }
212
213 int vc_setting_dbus_close_connection()
214 {
215         DBusError err;
216         dbus_error_init(&err);
217
218         if (NULL != g_s_fd_handler) {
219                 ecore_main_fd_handler_del(g_s_fd_handler);
220                 g_s_fd_handler = NULL;
221         }
222
223         int pid = getpid();
224
225         char service_name[64];
226         memset(service_name, '\0', 64);
227         snprintf(service_name, 64, "%s%d", VC_SETTING_SERVICE_NAME, pid);
228
229         dbus_bus_release_name(g_s_conn_listener, service_name, &err);
230
231         if (dbus_error_is_set(&err)) {
232                 SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Dbus Error (%s)", err.message);
233                 dbus_error_free(&err);
234         }
235
236         __vc_setting_dbus_connection_free();
237
238         return 0;
239 }
240
241 int vc_setting_dbus_reconnect()
242 {
243         if (!g_s_conn_sender || !g_s_conn_listener) {
244                 vc_setting_dbus_close_connection();
245
246                 if (0 != vc_setting_dbus_open_connection()) {
247                         SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Fail to reconnect");
248                         return -1;
249                 }
250
251                 SLOG(LOG_DEBUG, TAG_VCS, "[DBUS] Reconnect");
252                 return 0;
253         }
254
255         bool sender_connected = dbus_connection_get_is_connected(g_s_conn_sender);
256         bool listener_connected = dbus_connection_get_is_connected(g_s_conn_listener);
257         SLOG(LOG_WARN, TAG_VCS, "[DBUS] Sender(%s) Listener(%s)",
258                  sender_connected ? "Connected" : "Not connected", listener_connected ? "Connected" : "Not connected");
259
260         if (false == sender_connected || false == listener_connected) {
261                 vc_setting_dbus_close_connection();
262
263                 if (0 != vc_setting_dbus_open_connection()) {
264                         SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Fail to reconnect");
265                         return -1;
266                 }
267
268                 SLOG(LOG_DEBUG, TAG_VCS, "[DBUS] Reconnect");
269         }
270
271         return 0;
272 }
273
274 int vc_setting_dbus_request_hello()
275 {
276         if (NULL == g_s_conn_sender) {
277                 return VC_ERROR_OPERATION_FAILED;
278         }
279
280         DBusMessage* msg;
281
282         msg = dbus_message_new_method_call(
283                           VC_SERVER_SERVICE_NAME,
284                           VC_SERVER_SERVICE_OBJECT_PATH,
285                           VC_SERVER_SERVICE_INTERFACE,
286                           VC_METHOD_HELLO);
287
288         if (NULL == msg) {
289                 SLOG(LOG_ERROR, TAG_VCS, "@@ Request vc hello : Fail to make message");
290                 return VC_ERROR_OPERATION_FAILED;
291         }
292
293         DBusError err;
294         dbus_error_init(&err);
295
296         DBusMessage* result_msg = NULL;
297         int result = 0;
298
299         result_msg = dbus_connection_send_with_reply_and_block(g_s_conn_sender, msg, 500, &err);
300
301         if (dbus_error_is_set(&err)) {
302                 dbus_error_free(&err);
303         }
304
305         dbus_message_unref(msg);
306
307         if (NULL != result_msg) {
308                 dbus_message_unref(result_msg);
309                 result = 0;
310         } else {
311                 result = VC_ERROR_TIMED_OUT;
312         }
313
314         return result;
315 }
316
317 int vc_setting_dbus_request_set_language(int pid, const char* language)
318 {
319         if (NULL == g_s_conn_sender) {
320                 SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Dbus does not open");
321                 return VC_ERROR_OPERATION_FAILED;
322         }
323
324         DBusMessage* msg;
325
326         msg = dbus_message_new_method_call(
327                           VC_SERVER_SERVICE_NAME,
328                           VC_SERVER_SERVICE_OBJECT_PATH,
329                           VC_SERVER_SERVICE_INTERFACE,
330                           VC_SETTING_METHOD_SET_LANGUAGE);
331
332         if (NULL == msg) {
333                 SLOG(LOG_ERROR, TAG_VCS, "@@ vc set language : Fail to make message");
334                 return VC_ERROR_OPERATION_FAILED;
335         } else {
336                 SLOG(LOG_DEBUG, TAG_VCS, "@@ vc set language : pid(%d)", pid);
337         }
338
339         dbus_message_append_args(msg,
340                                                          DBUS_TYPE_INT32, &pid,
341                                                          DBUS_TYPE_STRING, &language,
342                                                          DBUS_TYPE_INVALID);
343
344         DBusError err;
345         dbus_error_init(&err);
346
347         DBusMessage* result_msg;
348         int result = VC_ERROR_OPERATION_FAILED;
349
350         result_msg = dbus_connection_send_with_reply_and_block(g_s_conn_sender, msg, g_s_waiting_time, &err);
351         dbus_message_unref(msg);
352
353         if (dbus_error_is_set(&err)) {
354                 SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Dbus Error (%s)", err.message);
355                 dbus_error_free(&err);
356         }
357
358         if (NULL != result_msg) {
359                 dbus_message_get_args(result_msg, &err,
360                                                           DBUS_TYPE_INT32, &result,
361                                                           DBUS_TYPE_INVALID);
362
363                 if (dbus_error_is_set(&err)) {
364                         SLOG(LOG_ERROR, TAG_VCS, "@@ Get arguments error (%s)", err.message);
365                         dbus_error_free(&err);
366                         result = VC_ERROR_OPERATION_FAILED;
367                 }
368                 dbus_message_unref(result_msg);
369
370                 SLOG(LOG_DEBUG, TAG_VCS, "@@ vcd set language : result = %d", result);
371         } else {
372                 SLOG(LOG_ERROR, TAG_VCS, "@@ Result message is NULL");
373                 vc_setting_dbus_reconnect();
374                 result = VC_ERROR_TIMED_OUT;
375         }
376
377         return result;
378 }