modify files according to coding rule
[platform/core/uifw/stt.git] / server / sttd_dbus.c
1 /*
2 * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd All Rights Reserved
3 *  Licensed under the Apache License, Version 2.0 (the "License");
4 *  you may not use this file except in compliance with the License.
5 *  You may obtain a copy of the License at
6 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14
15 #include <dbus/dbus.h>
16 #include <Ecore.h>
17
18 #include "sttd_main.h"
19 #include "sttd_dbus.h"
20 #include "sttd_client_data.h"
21 #include "sttd_dbus_server.h"
22 #include "stt_defs.h"
23
24 static DBusConnection* g_conn_sender = NULL;
25 static DBusConnection* g_conn_listener = NULL;
26
27 static Ecore_Fd_Handler* g_dbus_fd_handler = NULL;
28
29 static int g_waiting_time = 3000;
30
31
32 int sttdc_send_hello(int uid)
33 {
34         int pid = sttd_client_get_pid(uid);
35         if (0 > pid) {
36                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] pid is NOT valid");
37                 return STTD_ERROR_INVALID_PARAMETER;
38         }
39
40         char service_name[64];
41         memset(service_name, 0, 64);
42         snprintf(service_name, 64, "%s", STT_CLIENT_SERVICE_NAME);
43
44         char target_if_name[128];
45         snprintf(target_if_name, sizeof(target_if_name), "%s", STT_CLIENT_SERVICE_INTERFACE);
46
47         DBusMessage* msg = NULL;
48
49         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] Send hello message : uid(%d)", uid);
50
51         msg = dbus_message_new_method_call(
52                 service_name, 
53                 STT_CLIENT_SERVICE_OBJECT_PATH, 
54                 target_if_name, 
55                 STTD_METHOD_HELLO);
56
57         if (NULL == msg) {
58                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to create message");
59                 return STTD_ERROR_OUT_OF_MEMORY;
60         }
61
62         dbus_message_append_args(msg, DBUS_TYPE_INT32, &uid, DBUS_TYPE_INVALID);
63
64         DBusError err;
65         dbus_error_init(&err);
66         int result = -1;
67
68         DBusMessage* result_msg = NULL;
69         result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, g_waiting_time, &err);
70         dbus_message_unref(msg);
71         if (dbus_error_is_set(&err)) {
72                 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Send error (%s)", err.message);
73                 dbus_error_free(&err);
74         }
75
76         if (NULL != result_msg) {
77                 dbus_message_get_args(result_msg, &err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
78
79                 if (dbus_error_is_set(&err)) {
80                         SLOG(LOG_ERROR, TAG_STTD, "[Dbus] Get arguments error (%s)\n", err.message);
81                         dbus_error_free(&err);
82                         result = -1;
83                 }
84
85                 dbus_message_unref(result_msg);
86         } else {
87                 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] Result message is NULL. Client is not available");
88         }
89
90         return result;
91 }
92
93 int sttdc_send_set_state(int uid, int state)
94 {
95         int pid = sttd_client_get_pid(uid);
96
97         if (0 > pid) {
98                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] pid is NOT valid");
99                 return -1;
100         }
101
102         char service_name[64];
103         memset(service_name, 0, 64);
104         snprintf(service_name, 64, "%s", STT_CLIENT_SERVICE_NAME);
105
106         char target_if_name[128];
107         snprintf(target_if_name, sizeof(target_if_name), "%s", STT_CLIENT_SERVICE_INTERFACE);
108
109         DBusMessage* msg;
110
111         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] Send change state message : uid(%d), state(%d)", uid, state);
112
113         msg = dbus_message_new_method_call(
114                 service_name,
115                 STT_CLIENT_SERVICE_OBJECT_PATH,
116                 target_if_name,
117                 STTD_METHOD_SET_STATE);
118
119         if (NULL == msg) {
120                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to create message");
121                 return -1;
122         }
123
124         dbus_message_append_args(msg,
125                 DBUS_TYPE_INT32, &uid,
126                 DBUS_TYPE_INT32, &state,
127                 DBUS_TYPE_INVALID);
128
129         dbus_message_set_no_reply(msg, TRUE);
130
131         if (!dbus_connection_send(g_conn_sender, msg, NULL)) {
132                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to send message : Out Of Memory !");
133         } else {
134                 SLOG(LOG_DEBUG, TAG_STTD, "<<<< Send error message : uid(%d), state(%d)", uid, state);
135                 dbus_connection_flush(g_conn_sender);
136         }
137
138         dbus_connection_flush(g_conn_sender);
139         dbus_message_unref(msg);
140
141         return 0;
142 }
143 int sttdc_send_get_state(int uid, int* state)
144 {
145         int pid = sttd_client_get_pid(uid);
146
147         if (0 > pid) {
148                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] pid is NOT valid");
149                 return -1;
150         }
151
152         char service_name[64];
153         memset(service_name, 0, 64);
154         snprintf(service_name, 64, "%s", STT_CLIENT_SERVICE_NAME);
155
156         char target_if_name[128];
157         snprintf(target_if_name, sizeof(target_if_name), "%s", STT_CLIENT_SERVICE_INTERFACE);
158
159         DBusMessage* msg;
160
161         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] Send get state message : uid(%d)", uid);
162
163         msg = dbus_message_new_method_call(
164                 service_name, 
165                 STT_CLIENT_SERVICE_OBJECT_PATH, 
166                 target_if_name, 
167                 STTD_METHOD_GET_STATE);
168
169         if (NULL == msg) {
170                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to create message");
171                 return -1;
172         }
173
174         dbus_message_append_args(msg, DBUS_TYPE_INT32, &uid, DBUS_TYPE_INVALID);
175
176         DBusError err;
177         dbus_error_init(&err);
178
179         DBusMessage* result_msg;
180         int tmp = -1;
181         int result = 0;
182
183         result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, g_waiting_time, &err);
184         dbus_message_unref(msg);
185         if (dbus_error_is_set(&err)) {
186                 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Send error (%s)", err.message);
187                 dbus_error_free(&err);
188         }
189
190         if (NULL != result_msg) {
191                 dbus_message_get_args(result_msg, &err, DBUS_TYPE_INT32, &tmp, DBUS_TYPE_INVALID);
192
193                 if (dbus_error_is_set(&err)) {
194                         SLOG(LOG_ERROR, TAG_STTD, "[Dbus] Get arguments error (%s)\n", err.message);
195                         dbus_error_free(&err);
196                         result = -1;
197                 } else {
198                         *state = tmp;
199                         result = 0;
200                 }
201
202                 dbus_message_unref(result_msg);
203         } else {
204                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus] Result message is NULL. Client is not available");
205                 result = -1;
206         }
207
208         return result;
209 }
210
211 int sttdc_send_result(int uid, int event, const char** data, int data_count, const char* result_msg)
212 {
213         int pid = sttd_client_get_pid(uid);
214         if (0 > pid) {
215                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] pid is NOT valid");
216                 return STTD_ERROR_INVALID_PARAMETER;
217         }
218
219         char service_name[64];
220         memset(service_name, 0, 64);
221         snprintf(service_name, 64, "%s", STT_CLIENT_SERVICE_NAME);
222
223         char target_if_name[128];
224         memset(target_if_name, 0, 128);
225         snprintf(target_if_name, sizeof(target_if_name), "%s", STT_CLIENT_SERVICE_INTERFACE);
226
227         DBusMessage* msg = NULL;
228         SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] send result signal : uid(%d), event(%d), result count(%d)", uid, event, data_count);
229
230         msg = dbus_message_new_method_call(
231                 service_name, 
232                 STT_CLIENT_SERVICE_OBJECT_PATH, 
233                 target_if_name, 
234                 STTD_METHOD_RESULT);
235
236         if (NULL == msg) {
237                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to create message");
238                 return STTD_ERROR_OUT_OF_MEMORY;
239         }
240
241         DBusMessageIter args;
242         dbus_message_iter_init_append(msg, &args);
243
244         /* Append uid & type */
245         dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &uid);
246
247         char* msg_temp;
248         dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &event);
249
250         /* Append result msg */
251         if (NULL == result_msg) {
252                 msg_temp = strdup("None");
253                 dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &msg_temp);
254                 SLOG(LOG_WARN, TAG_STTD, "[Dbus] result message is NULL");
255                 free(msg_temp);
256         } else {
257                 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] result message(%s)", result_msg);
258                 dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &(result_msg));
259         }
260
261         /* Append result size */
262         if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &(data_count))) {
263                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus] response message : Fail to append result size");
264                 return -1;
265         }
266
267         int i;
268         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] result size (%d)", data_count);
269         for (i = 0; i < data_count; i++) {
270                 if (NULL != data[i]) {
271                         SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] result (%d, %s)", i, data[i]);
272
273                         if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &data[i])) {
274                                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus] response message : Fail to append result data");
275                                 dbus_message_unref(msg);
276                                 return STTD_ERROR_OPERATION_FAILED;
277                         }
278                 } else {
279                         int reason = (int)STTD_ERROR_OPERATION_FAILED;
280
281                         if (0 != sttdc_send_error_signal(uid, reason, "Fail to get recognition result from engine")) {
282                                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to send error info. Remove client data");
283
284                                 /* clean client data */
285                                 sttd_client_delete(uid);
286                         }
287
288                         dbus_message_unref(msg);
289                         SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Result from engine is NULL(%d)", i);
290                         return STTD_ERROR_OPERATION_FAILED;
291                 }
292         }
293
294         dbus_message_set_no_reply(msg, TRUE);
295
296         if (!dbus_connection_send(g_conn_sender, msg, NULL)) {
297                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to send message : Out Of Memory !");
298         }
299
300         dbus_connection_flush(g_conn_sender);
301         dbus_message_unref(msg);
302
303         return 0;
304 }
305
306 int sttdc_send_error_signal(int uid, int reason, const char *err_msg)
307 {
308         if (NULL == err_msg) {
309                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Input parameter is NULL");
310                 return STTD_ERROR_INVALID_PARAMETER;
311         }
312
313         int pid = sttd_client_get_pid(uid);
314         if (0 > pid) {
315                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] pid is NOT valid");
316                 return STTD_ERROR_INVALID_PARAMETER;
317         }
318
319         char service_name[64];
320         memset(service_name, 0, 64);
321         snprintf(service_name, 64, "%s", STT_CLIENT_SERVICE_NAME);
322
323         char target_if_name[128];
324         snprintf(target_if_name, sizeof(target_if_name), "%s", STT_CLIENT_SERVICE_INTERFACE);
325
326         DBusMessage* msg = NULL;
327         msg = dbus_message_new_method_call(
328                 service_name, 
329                 STT_CLIENT_SERVICE_OBJECT_PATH, 
330                 target_if_name, 
331                 STTD_METHOD_ERROR);
332
333         if (NULL == msg) {
334                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to create message");
335                 return STTD_ERROR_OUT_OF_MEMORY;
336         }
337
338         dbus_message_append_args(msg, 
339                 DBUS_TYPE_INT32, &uid, 
340                 DBUS_TYPE_INT32, &reason, 
341                 DBUS_TYPE_STRING, &err_msg,
342                 DBUS_TYPE_INVALID);
343
344         if (!dbus_connection_send(g_conn_sender, msg, NULL)) {
345                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] <<<< error message : Out Of Memory !");
346         } else {
347                 SLOG(LOG_DEBUG, TAG_STTD, "<<<< Send error message : uid(%d), reason(%d), err_msg(%s)", uid, reason, err_msg);
348                 dbus_connection_flush(g_conn_sender);
349         }
350
351         dbus_message_unref(msg);
352
353         return 0;
354 }
355
356 static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handler)
357 {
358         if (NULL == g_conn_listener)    return ECORE_CALLBACK_RENEW;
359
360         dbus_connection_read_write_dispatch(g_conn_listener, 50);
361
362         DBusMessage* msg = NULL;
363         msg = dbus_connection_pop_message(g_conn_listener);
364
365         if (true != dbus_connection_get_is_connected(g_conn_listener)) {
366                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Connection is disconnected");
367                 return ECORE_CALLBACK_RENEW;
368         }
369
370         /* loop again if we haven't read a message */
371         if (NULL == msg) {
372                 return ECORE_CALLBACK_RENEW;
373         }
374
375         /* client event */
376         if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_HELLO))
377                 sttd_dbus_server_hello(g_conn_listener, msg);
378
379         else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_INITIALIZE))
380                 sttd_dbus_server_initialize(g_conn_listener, msg);
381
382         else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_FINALIZE))
383                 sttd_dbus_server_finalize(g_conn_listener, msg);
384
385         else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_SET_CURRENT_ENGINE))
386                 sttd_dbus_server_set_current_engine(g_conn_listener, msg);
387
388         else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_CHECK_APP_AGREED))
389                 sttd_dbus_server_check_app_agreed(g_conn_listener, msg);
390
391         else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_GET_SUPPORT_LANGS))
392                 sttd_dbus_server_get_support_lang(g_conn_listener, msg);
393
394         else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_GET_CURRENT_LANG))
395                 sttd_dbus_server_get_default_lang(g_conn_listener, msg);
396
397         else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_IS_TYPE_SUPPORTED))
398                 sttd_dbus_server_is_recognition_type_supported(g_conn_listener, msg);
399
400
401         else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_SET_START_SOUND))
402                 sttd_dbus_server_set_start_sound(g_conn_listener, msg);
403
404         else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_UNSET_START_SOUND))
405                 sttd_dbus_server_unset_start_sound(g_conn_listener, msg);
406
407         else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_SET_STOP_SOUND))
408                 sttd_dbus_server_set_stop_sound(g_conn_listener, msg);
409
410         else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_UNSET_STOP_SOUND))
411                 sttd_dbus_server_unset_stop_sound(g_conn_listener, msg);
412
413
414         else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_START))
415                 sttd_dbus_server_start(g_conn_listener, msg);
416
417         else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_STOP))
418                 sttd_dbus_server_stop(g_conn_listener, msg);
419
420         else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_CANCEL))
421                 sttd_dbus_server_cancel(g_conn_listener, msg);
422
423
424         /* free the message */
425         dbus_message_unref(msg);
426
427         return ECORE_CALLBACK_RENEW;
428 }
429
430 int sttd_dbus_open_connection()
431 {
432         DBusError err;
433         dbus_error_init(&err);
434
435         int ret;
436
437         /* Create connection for sender */
438         g_conn_sender = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
439         if (dbus_error_is_set(&err)) {
440                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail dbus_bus_get : %s", err.message);
441                 dbus_error_free(&err);
442         }
443
444         if (NULL == g_conn_sender) {
445                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to get dbus connection sender");
446                 return STTD_ERROR_OPERATION_FAILED;
447         }
448
449         /* connect to the bus and check for errors */
450         g_conn_listener = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
451
452         if (dbus_error_is_set(&err)) {
453                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail dbus_bus_get : %s", err.message);
454                 dbus_error_free(&err);
455         }
456
457         if (NULL == g_conn_listener) {
458                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to get dbus connection");
459                 return STTD_ERROR_OPERATION_FAILED;
460         }
461
462         /* request our name on the bus and check for errors */
463         ret = dbus_bus_request_name(g_conn_listener, STT_SERVER_SERVICE_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
464
465         if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
466                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to be primary owner");
467                 return STTD_ERROR_OPERATION_FAILED;
468         }
469
470         if (dbus_error_is_set(&err)) {
471                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] dbus_bus_request_name() : %s", err.message);
472                 dbus_error_free(&err);
473                 return STTD_ERROR_OPERATION_FAILED;
474         }
475
476         /* add a rule for getting signal */
477         char rule[128];
478         snprintf(rule, 128, "type='signal',interface='%s'", STT_SERVER_SERVICE_INTERFACE);
479
480         /* add a rule for which messages we want to see */
481         dbus_bus_add_match(g_conn_listener, rule, &err); /* see signals from the given interface */
482         dbus_connection_flush(g_conn_listener);
483
484         if (dbus_error_is_set(&err)) {
485                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] dbus_bus_add_match() : %s", err.message);
486                 return STTD_ERROR_OPERATION_FAILED;
487         }
488
489         int fd = 0;
490         dbus_connection_get_unix_fd(g_conn_listener, &fd);
491
492         g_dbus_fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)listener_event_callback, g_conn_listener, NULL, NULL);
493         if (NULL == g_dbus_fd_handler) {
494                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to get fd handler");
495                 return STTD_ERROR_OPERATION_FAILED;
496         }
497
498         return 0;
499 }
500
501 int sttd_dbus_close_connection()
502 {
503         DBusError err;
504         dbus_error_init(&err);
505
506         if (NULL != g_dbus_fd_handler) {
507                 ecore_main_fd_handler_del(g_dbus_fd_handler);
508                 g_dbus_fd_handler = NULL;
509         }
510
511         dbus_bus_release_name(g_conn_listener, STT_SERVER_SERVICE_NAME, &err);
512
513         if (dbus_error_is_set(&err)) {
514                 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] dbus_bus_release_name() : %s", err.message);
515                 dbus_error_free(&err);
516         }
517
518         g_conn_listener = NULL;
519         g_conn_sender = NULL;
520
521         return 0;
522 }