Add new flag variable for checking state
[platform/core/uifw/tts.git] / client / tts_dbus.c
1 /*
2 *  Copyright (c) 2011-2016 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 #include <Ecore.h>
15 #include <errno.h>
16 #include <fcntl.h>
17 #include <sys/inotify.h>
18
19 #include "tts_core.h"
20 #include "tts_client.h"
21 #include "tts_config_mgr.h"
22 #include "tts_dbus.h"
23 #include "tts_defs.h"
24 #include "tts_main.h"
25 #include "tts_internal.h"
26
27 #define HELLO_WAITING_TIME -1
28 #define WAITING_TIME 5000
29
30 static DBusConnection* g_conn_sender = NULL;
31 static DBusConnection* g_conn_listener = NULL;
32
33 static Ecore_Fd_Handler* g_dbus_fd_handler = NULL;
34
35 static int g_connected_client = 0;
36
37
38 static int __tts_dbus_add_match(unsigned int uid)
39 {
40         /* add a rule for daemon error */
41         tts_client_s* client = tts_client_get_by_uid(uid);
42         if (NULL == client) {
43                 SLOG(LOG_ERROR, TAG_TTSC, "Fail to get TTS client");
44                 return TTS_ERROR_OPERATION_FAILED;
45         }
46
47         char rule_err[256] = {0, };
48         snprintf(rule_err, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", TTS_SERVER_SERVICE_INTERFACE);
49
50         /* initialize the error value */
51         DBusError err;
52         dbus_error_init(&err);
53
54         dbus_bus_add_match(g_conn_listener, rule_err, &err);
55         dbus_connection_flush(g_conn_listener);
56
57         if (dbus_error_is_set(&err)) {
58                 SLOG(LOG_ERROR, TAG_TTSC, "Match Error (%s)", err.message);
59                 dbus_error_free(&err);
60                 return TTS_ERROR_OPERATION_FAILED;
61         }
62         client->reason = 0; // default value
63
64         return TTS_ERROR_NONE;
65 }
66
67 static void __tts_dbus_remove_match()
68 {
69         DBusError err;
70         dbus_error_init(&err);
71
72         /* remove a rule for daemon error */
73         char rule_err[256] = {0, };
74         snprintf(rule_err, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", TTS_SERVER_SERVICE_INTERFACE);
75
76         dbus_bus_remove_match(g_conn_listener, rule_err, &err);
77         dbus_connection_flush(g_conn_listener);
78         if (dbus_error_is_set(&err)) {
79                 SLOG(LOG_ERROR, TAG_TTSC, "Match Error (%s)", err.message);
80                 dbus_error_free(&err);
81         }
82
83         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] dbus match is removed");
84 }
85
86 static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handler)
87 {
88         if (NULL == g_conn_listener)    return ECORE_CALLBACK_RENEW;
89
90         dbus_connection_read_write_dispatch(g_conn_listener, 50);
91
92         while (1) {
93                 DBusMessage* msg = NULL;
94                 msg = dbus_connection_pop_message(g_conn_listener);
95
96                 if (true != dbus_connection_get_is_connected(g_conn_listener)) {
97                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Connection is disconnected");
98                         break;
99                 }
100
101                 /* loop again if we haven't read a message */
102                 if (NULL == msg) {
103                         break;
104                 }
105
106                 DBusError err;
107                 dbus_error_init(&err);
108
109                 char if_name[64] = {0, };
110                 snprintf(if_name, 64, "%s%d", TTS_CLIENT_SERVICE_INTERFACE, getpid());
111
112                 if (dbus_message_is_signal(msg, if_name, TTSD_METHOD_HELLO)) {
113                         SLOG(LOG_DEBUG, TAG_TTSC, "@@@ Get Hello");
114
115                         unsigned int uid;
116                         int ret;
117                         int credential_needed;
118
119                         dbus_message_get_args(msg, &err,
120                                 DBUS_TYPE_UINT32, &uid,
121                                 DBUS_TYPE_INT32, &ret,
122                                 DBUS_TYPE_INT32, &credential_needed,
123                                 DBUS_TYPE_INVALID);
124
125                         if (dbus_error_is_set(&err)) {
126                                 SLOG(LOG_ERROR, TAG_TTSC, "@@ tts Get Hello message : Get arguments error (%s)", err.message);
127                                 dbus_error_free(&err);
128                         } else {
129                                 SLOG(LOG_ERROR, TAG_TTSC, "@@ tts Get Hello message : uid(%u), credential_needed(%d)", uid, credential_needed);
130                                 if (TTS_ERROR_ALREADY_INITIALIZED == ret && TTS_CREDENTIAL_NEEDED_ALREADY_INITIALIZED == credential_needed) {
131                                         SLOG(LOG_INFO, TAG_TTSC, "@@ tts Get Hello message : already initialized");
132                                         ret = 0;
133                                 } else {
134                                         __tts_dbus_add_match(uid);
135                                 }
136                                 tts_core_receive_hello(uid, ret, credential_needed);
137                         }
138
139                         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
140                 }
141
142                 else if (dbus_message_is_signal(msg, if_name, TTSD_METHOD_UTTERANCE_STARTED)) {
143                         unsigned int uid = 0;
144                         int uttid = 0;
145
146                         dbus_message_get_args(msg, &err, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INT32, &uttid, DBUS_TYPE_INVALID);
147                         if (dbus_error_is_set(&err)) {
148                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get arguments error (%s)", err.message);
149                                 dbus_error_free(&err);
150                         }
151
152                         if (0 == tts_core_notify_utt_started(tts_client_get_by_uid(uid), uttid)) {
153                                 SLOG(LOG_DEBUG, TAG_TTSC, "<<<< tts utterance started : uid(%u) uttid(%d)", uid, uttid);
154                         }
155                 } /* TTSD_METHOD_UTTERANCE_STARTED */
156
157                 else if (dbus_message_is_signal(msg, if_name, TTSD_METHOD_UTTERANCE_COMPLETED)) {
158                         unsigned int uid = 0;
159                         int uttid = 0;
160
161                         dbus_message_get_args(msg, &err, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INT32, &uttid, DBUS_TYPE_INVALID);
162                         if (dbus_error_is_set(&err)) {
163                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get arguments error (%s)", err.message);
164                                 dbus_error_free(&err);
165                         }
166
167                         if (0 == tts_core_notify_utt_completeted(tts_client_get_by_uid(uid), uttid)) {
168                                 SLOG(LOG_DEBUG, TAG_TTSC, "<<<< tts utterance completed : uid(%u) uttid(%d)", uid, uttid);
169                         }
170                 } /* TTS_SIGNAL_UTTERANCE_STARTED */
171
172                 else if (dbus_message_is_signal(msg, if_name, TTSD_METHOD_SET_STATE)) {
173                         unsigned int uid = 0;
174                         int state = 0;
175
176                         dbus_message_get_args(msg, &err, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INT32, &state, DBUS_TYPE_INVALID);
177                         if (dbus_error_is_set(&err)) {
178                                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Get arguments error (%s)", err.message);
179                                 dbus_error_free(&err);
180                         }
181
182                         if (0 == tts_core_notify_state_changed(tts_client_get_by_uid(uid), (tts_state_e)state)) {
183                                 SLOG(LOG_DEBUG, TAG_TTSC, "<<<< tts state changed : uid(%u) state(%d)", uid, state);
184                         }
185                 } /* TTSD_SIGNAL_SET_STATE */
186
187                 else if (dbus_message_is_signal(msg, if_name, TTSD_METHOD_ERROR)) {
188                         unsigned int uid;
189                         int uttid;
190                         int reason;
191                         char* err_msg;
192
193                         dbus_message_get_args(msg, &err,
194                                 DBUS_TYPE_UINT32, &uid,
195                                 DBUS_TYPE_INT32, &uttid,
196                                 DBUS_TYPE_INT32, &reason,
197                                 DBUS_TYPE_STRING, &err_msg,
198                                 DBUS_TYPE_INVALID);
199
200                         if (dbus_error_is_set(&err)) {
201                                 SLOG(LOG_ERROR, TAG_TTSC, "<<<< Get Error message - Get arguments error (%s)", err.message);
202                                 dbus_error_free(&err);
203                         } else {
204                                 SLOG(LOG_ERROR, TAG_TTSC, "<<<< Get Error message : uid(%u), error(%d), uttid(%d), err_msg(%s)", uid, reason, uttid, (NULL == err_msg) ? "NULL" : err_msg);
205                                 tts_core_notify_error_async(tts_client_get_by_uid(uid), reason, uttid, err_msg);
206                         }
207                 } /* TTSD_SIGNAL_ERROR */
208
209                 else if (dbus_message_is_signal(msg, "org.freedesktop.DBus", "NameOwnerChanged")) {
210                         SLOG(LOG_DEBUG, TAG_TTSC, "@@@ Owner Changed");
211                         tts_core_handle_service_reset();
212                         SLOG(LOG_DEBUG, TAG_TTSC, "@@@");
213                 } /* NameOwnerChanged */
214
215                 else {
216                         SLOG(LOG_DEBUG, TAG_TTSC, "Message is NOT valid");
217                         const char* sender = dbus_message_get_sender(msg);
218                         const char* destination = dbus_message_get_destination(msg);
219                         const char* path = dbus_message_get_path(msg);
220                         const char* interf = dbus_message_get_interface(msg);
221                         const char* member = dbus_message_get_member(msg);
222                         int type = dbus_message_get_type(msg);
223                         SLOG(LOG_ERROR, TAG_TTSC, "[INFO] Message is NOT valid, sender(%s), destination(%s), path(%s), interface(%s), member(%s), type(%d)", sender, destination, path, interf, member, type);
224
225                         dbus_message_unref(msg);
226                         break;
227                 }
228
229                 /* free the message */
230                 dbus_message_unref(msg);
231         }
232         return ECORE_CALLBACK_PASS_ON;
233 }
234
235 static void __tts_dbus_connection_free()
236 {
237         if (NULL != g_conn_listener) {
238                 dbus_connection_close(g_conn_listener);
239                 dbus_connection_unref(g_conn_listener);
240                 g_conn_listener = NULL;
241         }
242         if (NULL != g_conn_sender) {
243                 dbus_connection_close(g_conn_sender);
244                 dbus_connection_unref(g_conn_sender);
245                 g_conn_sender = NULL;
246         }
247 }
248
249 static int __dbus_open_connection()
250 {
251         /* initialize the error value */
252         DBusError err;
253         dbus_error_init(&err);
254
255         /* connect to the DBUS system bus, and check for errors */
256         g_conn_sender = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
257         if (dbus_error_is_set(&err)) {
258                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Dbus Connection Error (%s)", err.message);
259                 dbus_error_free(&err);
260         }
261
262         if (NULL == g_conn_sender) {
263                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] fail to get dbus connection");
264                 return TTS_ERROR_OPERATION_FAILED;
265         }
266
267         dbus_connection_set_exit_on_disconnect(g_conn_sender, false);
268
269         g_conn_listener = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
270         if (dbus_error_is_set(&err)) {
271                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Dbus Connection Error (%s)", err.message);
272                 dbus_error_free(&err);
273         }
274
275         if (NULL == g_conn_listener) {
276                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] fail to get dbus connection for listener");
277                 __tts_dbus_connection_free();
278                 return TTS_ERROR_OPERATION_FAILED;
279         }
280
281         dbus_connection_set_exit_on_disconnect(g_conn_listener, false);
282
283         /* register our name on the bus, and check for errors */
284         dbus_bus_request_name(g_conn_listener, TTS_CLIENT_SERVICE_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
285
286         if (dbus_error_is_set(&err)) {
287                 //LCOV_EXCL_START
288                 SLOG(LOG_ERROR, TAG_TTSC, "Name Error (%s)", err.message);
289                 dbus_error_free(&err);
290                 //LCOV_EXCL_STOP
291         }
292
293         char rule[128] = {0, };
294         snprintf(rule, 128, "type='signal',interface='%s%d'", TTS_CLIENT_SERVICE_INTERFACE, getpid());
295
296         /* add a rule for which messages we want to see */
297         dbus_bus_add_match(g_conn_listener, rule, &err);
298         dbus_connection_flush(g_conn_listener);
299
300         int fd = 0;
301         if (true != dbus_connection_get_unix_fd(g_conn_listener, &fd)) {
302                 SLOG(LOG_ERROR, TAG_TTSC, "Fail to get fd from dbus");
303                 __tts_dbus_connection_free();
304                 return TTS_ERROR_OPERATION_FAILED;
305         } else {
306                 SLOG(LOG_DEBUG, TAG_TTSC, "Get fd from dbus : %d", fd);
307         }
308
309         g_dbus_fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)listener_event_callback, NULL, NULL, NULL);
310         if (NULL == g_dbus_fd_handler) {
311                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to get fd handler from ecore");
312                 __tts_dbus_connection_free();
313                 return TTS_ERROR_OPERATION_FAILED;
314         }
315
316         return TTS_ERROR_NONE;
317 }
318
319 int tts_dbus_open_connection(unsigned int uid)
320 {
321         if (NULL != g_conn_sender && NULL != g_conn_listener) {
322                 SLOG(LOG_WARN, TAG_TTSC, "already existed connection ");
323                 g_connected_client++;
324
325                 return TTS_ERROR_NONE;
326         }
327
328         int ret = __dbus_open_connection();
329         if (TTS_ERROR_NONE == ret) {
330                 g_connected_client++;
331         }
332
333         return ret;
334 }
335
336 static int __dbus_close_connection()
337 {
338         if (NULL != g_dbus_fd_handler) {
339                 ecore_main_fd_handler_del(g_dbus_fd_handler);
340                 g_dbus_fd_handler = NULL;
341         }
342
343         __tts_dbus_connection_free();
344
345         return TTS_ERROR_NONE;
346 }
347
348 int tts_dbus_close_connection(unsigned int uid)
349 {
350         g_connected_client--;
351
352         if (0 == g_connected_client) {
353                 return __dbus_close_connection();
354         }
355
356         return TTS_ERROR_NONE;
357 }
358
359 int tts_dbus_stop_listening(unsigned int uid)
360 {
361         tts_client_s* client = tts_client_get_by_uid(uid);
362         if (NULL == client) {
363                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] uid is not valid");
364                 return TTS_ERROR_INVALID_PARAMETER;
365         }
366
367         __tts_dbus_remove_match();
368         return TTS_ERROR_NONE;
369 }
370
371 int tts_dbus_reconnect()
372 {
373         if (!g_conn_sender || !g_conn_listener) {
374                 __dbus_close_connection();
375
376                 if (0 != __dbus_open_connection()) {
377                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to reconnect");
378                         return -1;
379                 }
380
381                 SLOG(LOG_DEBUG, TAG_TTSC, "[DBUS] Reconnect");
382                 return 0;
383         }
384
385         bool sender_connected = dbus_connection_get_is_connected(g_conn_sender);
386         bool listener_connected = dbus_connection_get_is_connected(g_conn_listener);
387         SLOG(LOG_DEBUG, TAG_TTSC, "[DBUS] Sender(%s) Listener(%s)",
388                  sender_connected ? "Connected" : "Not connected", listener_connected ? "Connected" : "Not connected");
389
390         if (false == sender_connected || false == listener_connected) {
391                 __dbus_close_connection();
392
393                 if (0 != __dbus_open_connection()) {
394                         SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to reconnect");
395                         return -1;
396                 }
397
398                 SLOG(LOG_DEBUG, TAG_TTSC, "[DBUS] Reconnect");
399         }
400
401         return 0;
402 }
403
404 DBusMessage* __tts_dbus_make_message(unsigned int uid, const char* method)
405 {
406         if (NULL == method) {
407                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Input method is NULL");
408                 return NULL;
409         }
410
411         tts_client_s* client = tts_client_get_by_uid(uid);
412         if (NULL == client) {
413                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] uid is not available");
414                 return NULL;
415         }
416
417         DBusMessage* msg = dbus_message_new_method_call(
418                 TTS_SERVER_SERVICE_NAME,
419                 TTS_SERVER_SERVICE_OBJECT_PATH,
420                 TTS_SERVER_SERVICE_INTERFACE,
421                 method);
422
423         return msg;
424 }
425
426 int tts_dbus_request_hello(unsigned int uid, tts_mode_e mode)
427 {
428         DBusError err;
429         dbus_error_init(&err);
430         DBusMessage* msg;
431
432         msg = __tts_dbus_make_message(uid, TTS_METHOD_HELLO);
433
434         if (dbus_error_is_set(&err)) {
435 //              SLOG(LOG_DEBUG, TAG_TTSC, "<<<< tts dbus log : %s", err);
436                 dbus_error_free(&err);
437         }
438
439         if (NULL == msg) {
440                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts hello : Fail to make message");
441                 return TTS_ERROR_OPERATION_FAILED;
442         }
443
444         int pid = getpid();
445         if (true != dbus_message_append_args(msg, DBUS_TYPE_INT32, &pid, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INT32, &mode, DBUS_TYPE_INVALID)) {
446                 dbus_message_unref(msg);
447                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to append args");
448
449                 return TTS_ERROR_OPERATION_FAILED;
450         }
451
452         dbus_message_set_no_reply(msg, TRUE);
453
454         if (1 != dbus_connection_send(g_conn_sender, msg, NULL)) {
455                 SLOG(LOG_ERROR, TAG_TTSC, "[Dbus ERROR] Fail to Send"); //LCOV_EXCL_LINE
456                 dbus_message_unref(msg);
457                 return TTS_ERROR_OPERATION_FAILED;
458         } else {
459                 SLOG(LOG_INFO, TAG_TTSC, "[Dbus DEBUG] Success to Send");
460                 dbus_connection_flush(g_conn_sender);
461         }
462
463         dbus_message_unref(msg);
464         return 0;
465 }
466
467 int tts_dbus_request_hello_sync(unsigned int uid)
468 {
469         DBusError err;
470         dbus_error_init(&err);
471         DBusMessage* msg;
472
473         msg = __tts_dbus_make_message(uid, TTS_METHOD_HELLO_SYNC);
474
475         if (dbus_error_is_set(&err)) {
476 //              SLOG(LOG_DEBUG, TAG_TTSC, "<<<< tts dbus log : %s", err);
477                 dbus_error_free(&err);
478         }
479
480         if (NULL == msg) {
481                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts hello : Fail to make message");
482                 return TTS_ERROR_OPERATION_FAILED;
483         }
484
485         DBusMessage* result_msg = NULL;
486         int result = 0;
487
488         result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, HELLO_WAITING_TIME, &err);
489         dbus_message_unref(msg);
490         if (dbus_error_is_set(&err)) {
491                 SLOG(LOG_DEBUG, TAG_TTSC, "<<<< tts dbus log : %s", err.message);
492                 dbus_error_free(&err);
493         }
494
495         if (NULL != result_msg) {
496                 dbus_message_unref(result_msg);
497
498 //              SLOG(LOG_DEBUG, TAG_TTSC, "<<<< tts hello");
499                 result = 0;
500         } else {
501                 result = TTS_ERROR_TIMED_OUT;
502         }
503
504         return result;
505 }
506
507 int tts_dbus_request_initialize(unsigned int uid, tts_mode_e mode, bool* credential_needed)
508 {
509         DBusMessage* msg;
510         DBusError err;
511         dbus_error_init(&err);
512
513         msg = __tts_dbus_make_message(uid, TTS_METHOD_INITIALIZE);
514
515         if (NULL == msg) {
516                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts initialize : Fail to make message");
517                 return TTS_ERROR_OPERATION_FAILED;
518         } else {
519                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts initialize : uid(%u)", uid);
520         }
521
522         int pid = getpid();
523         if (true != dbus_message_append_args(msg, DBUS_TYPE_INT32, &pid, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INT32, &mode, DBUS_TYPE_INVALID)) {
524                 dbus_message_unref(msg);
525                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to append args");
526
527                 return TTS_ERROR_OPERATION_FAILED;
528         }
529
530         DBusMessage* result_msg;
531         int result = TTS_ERROR_OPERATION_FAILED;
532
533         result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, WAITING_TIME, &err);
534         dbus_message_unref(msg);
535         if (dbus_error_is_set(&err)) {
536                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Send error (%s)", err.message);
537                 dbus_error_free(&err);
538         }
539
540         int temp = 0;
541         if (NULL != result_msg) {
542                 dbus_message_get_args(result_msg, &err,
543                                   DBUS_TYPE_INT32, &result,
544                                   DBUS_TYPE_INT32, &temp,
545                                   DBUS_TYPE_INVALID);
546
547                 if (dbus_error_is_set(&err)) {
548                         SLOG(LOG_ERROR, TAG_TTSC, "<<<< Get arguments error (%s)", err.message);
549                         dbus_error_free(&err);
550                         result = TTS_ERROR_OPERATION_FAILED;
551                 }
552
553                 dbus_message_unref(result_msg);
554
555                 if (0 == result) {
556                         *credential_needed = (bool)temp;
557                         SLOG(LOG_DEBUG, TAG_TTSC, "<<<< tts initialize : result = %d, credential_needed(%d)", result, *credential_needed);
558
559                         /* add a rule for daemon error */
560                         tts_client_s* client = tts_client_get_by_uid(uid);
561                         if (NULL == client) {
562                                 SLOG(LOG_ERROR, TAG_TTSC, "Fail to get TTS client");
563                                 return TTS_ERROR_OPERATION_FAILED;
564                         }
565
566                         char rule_err[256] = {0, };
567                         snprintf(rule_err, 256, "sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',type='signal',arg0='%s'", TTS_SERVER_SERVICE_INTERFACE);
568
569                         dbus_bus_add_match(g_conn_listener, rule_err, &err);
570                         dbus_connection_flush(g_conn_listener);
571
572                         if (dbus_error_is_set(&err)) {
573                                 SLOG(LOG_ERROR, TAG_TTSC, "Match Error (%s)", err.message);
574                                 dbus_error_free(&err);
575                                 return TTS_ERROR_OPERATION_FAILED;
576                         }
577                         client->reason = 0; // default value
578                 } else {
579                         SLOG(LOG_ERROR, TAG_TTSC, "<<<< tts initialize : result = %d", result);
580                 }
581         } else {
582                 SLOG(LOG_ERROR, TAG_TTSC, "<<<< Result message is NULL ");
583                 tts_dbus_reconnect();
584                 result = TTS_ERROR_TIMED_OUT;
585         }
586
587         return result;
588 }
589
590 static int __send_message_and_get_result(DBusMessage* msg, const char* method)
591 {
592         DBusError err;
593         dbus_error_init(&err);
594
595         DBusMessage* result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, WAITING_TIME, &err);
596         dbus_message_unref(msg);
597         if (dbus_error_is_set(&err)) {
598                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Send error %s", err.message);
599                 dbus_error_free(&err);
600         }
601
602         int result = TTS_ERROR_OPERATION_FAILED;
603         if (NULL != result_msg) {
604                 dbus_message_get_args(result_msg, &err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
605
606                 if (dbus_error_is_set(&err)) {
607                         SLOG(LOG_ERROR, TAG_TTSC, "<<<< tts method(%s) : Get arguments error (%s)", method, err.message);
608                         dbus_error_free(&err);
609                         result = TTS_ERROR_OPERATION_FAILED;
610                 }
611
612                 dbus_message_unref(result_msg);
613
614                 if (0 == result) {
615                         SLOG(LOG_DEBUG, TAG_TTSC, "<<<< tts method(%s) : result = %d", method, result);
616                 } else {
617                         SLOG(LOG_ERROR, TAG_TTSC, "<<<< tts method(%s) : result = %d", method, result);
618                 }
619         } else {
620                 SLOG(LOG_ERROR, TAG_TTSC, "<<<< Result message is NULL ");
621                 tts_dbus_reconnect();
622                 result = TTS_ERROR_TIMED_OUT;
623         }
624
625         return result;
626 }
627
628 int tts_dbus_request_finalize(unsigned int uid)
629 {
630         tts_client_s* client = tts_client_get_by_uid(uid);
631         if (NULL == client) {
632                 SLOG(LOG_ERROR, TAG_TTSC, "Fail to get TTS client");
633                 return TTS_ERROR_OPERATION_FAILED;
634         }
635
636         /* remove a rule for daemon error */
637         __tts_dbus_remove_match();
638
639         DBusMessage* msg = __tts_dbus_make_message(uid, TTS_METHOD_FINALIZE);
640         if (NULL == msg) {
641                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts finalize : Fail to make message");
642                 return TTS_ERROR_OPERATION_FAILED;
643         } else {
644                 SLOG(LOG_DEBUG, TAG_TTSC, ">>>> Request tts finalize : uid(%u)", uid);
645         }
646
647         if (true != dbus_message_append_args(msg, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INVALID)) {
648                 dbus_message_unref(msg);
649                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to append args");
650
651                 return TTS_ERROR_OPERATION_FAILED;
652         }
653
654         int result = __send_message_and_get_result(msg, TTS_METHOD_FINALIZE);
655         return result;
656 }
657
658 int tts_dbus_request_add_text(unsigned int uid, const char* text, const char* lang, int vctype, int speed, int uttid, const char* credential)
659 {
660         if (NULL == text || NULL == lang) {
661                 SLOG(LOG_ERROR, TAG_TTSC, "Input parameter is NULL");
662                 return TTS_ERROR_INVALID_PARAMETER;
663         }
664
665         DBusMessage* msg = __tts_dbus_make_message(uid, TTS_METHOD_ADD_TEXT);
666         if (NULL == msg) {
667                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts add text : Fail to make message");
668                 return TTS_ERROR_OPERATION_FAILED;
669         } else {
670                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts add text : uid(%u), text(%s), lang(%s), type(%d), speed(%d), id(%d), credential(%s)",
671                          uid, text, lang, vctype, speed, uttid, (NULL == credential) ? "NULL" : credential);
672         }
673
674         char *temp = NULL;
675         if (NULL == credential) {
676                 temp = strdup("NULL");
677         } else {
678                 temp = strdup(credential);
679         }
680
681         if (true != dbus_message_append_args(msg,
682                 DBUS_TYPE_UINT32, &uid,
683                 DBUS_TYPE_STRING, &text,
684                 DBUS_TYPE_STRING, &lang,
685                 DBUS_TYPE_INT32, &vctype,
686                 DBUS_TYPE_INT32, &speed,
687                 DBUS_TYPE_INT32, &uttid,
688                 DBUS_TYPE_STRING, &temp,
689                 DBUS_TYPE_INVALID)) {
690                 dbus_message_unref(msg);
691                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to append args");
692
693                 if (NULL != temp) {
694                         free(temp);
695                         temp = NULL;
696                 }
697                 return TTS_ERROR_OPERATION_FAILED;
698         }
699
700         int result = __send_message_and_get_result(msg, TTS_METHOD_ADD_TEXT);
701         if (NULL != temp) {
702                 free(temp);
703                 temp = NULL;
704         }
705         return result;
706 }
707
708 int tts_dbus_request_set_private_data(unsigned int uid, const char* key, const char* data)
709 {
710         if (NULL == key || NULL == data) {
711                 SLOG(LOG_ERROR, TAG_TTSC, "Input parameter is NULL");
712                 return TTS_ERROR_INVALID_PARAMETER;
713         }
714
715         DBusMessage* msg = __tts_dbus_make_message(uid, TTS_METHOD_SET_PRIVATE_DATA);
716         if (NULL == msg) {
717                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts set private data : Fail to make message");
718                 return TTS_ERROR_OPERATION_FAILED;
719         } else {
720                 SLOG(LOG_DEBUG, TAG_TTSC, ">>>> Request tts set private data : uid(%u)", uid);
721         }
722
723         if (true != dbus_message_append_args(msg,
724                 DBUS_TYPE_UINT32, &uid,
725                 DBUS_TYPE_STRING, &key,
726                 DBUS_TYPE_STRING, &data,
727                 DBUS_TYPE_INVALID)) {
728                 dbus_message_unref(msg);
729                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to append args");
730
731                 return TTS_ERROR_OPERATION_FAILED;
732         }
733
734         int result = __send_message_and_get_result(msg, TTS_METHOD_SET_PRIVATE_DATA);
735         return result;
736 }
737
738 int tts_dbus_request_get_private_data(unsigned int uid, const char* key, char** data)
739 {
740         if (NULL == key || NULL == data) {
741                 SLOG(LOG_ERROR, TAG_TTSC, "Input parameter is NULL");
742                 return TTS_ERROR_INVALID_PARAMETER;
743         }
744
745         DBusMessage* msg;
746         DBusError err;
747         dbus_error_init(&err);
748
749         msg = __tts_dbus_make_message(uid, TTS_METHOD_GET_PRIVATE_DATA);
750
751         if (NULL == msg) {
752                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts get private data : Fail to make message");
753                 return TTS_ERROR_OPERATION_FAILED;
754         } else {
755                 SLOG(LOG_DEBUG, TAG_TTSC, ">>>> Request tts get private data : uid(%u)", uid);
756         }
757
758         if (true != dbus_message_append_args(msg,
759                 DBUS_TYPE_UINT32, &uid,
760                 DBUS_TYPE_STRING, &key,
761                 DBUS_TYPE_INVALID)) {
762                 dbus_message_unref(msg);
763                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to append args");
764
765                 return TTS_ERROR_OPERATION_FAILED;
766         }
767
768         DBusMessage* result_msg;
769         int result = TTS_ERROR_OPERATION_FAILED;
770
771         result_msg = dbus_connection_send_with_reply_and_block(g_conn_sender, msg, WAITING_TIME, &err);
772         dbus_message_unref(msg);
773         if (dbus_error_is_set(&err)) {
774                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Send error (%s)", err.message);
775                 dbus_error_free(&err);
776         }
777
778         char* temp = NULL;
779         if (NULL != result_msg) {
780                 dbus_message_get_args(result_msg, &err,
781                         DBUS_TYPE_INT32, &result,
782                         DBUS_TYPE_STRING, &temp,
783                         DBUS_TYPE_INVALID);
784
785                 if (dbus_error_is_set(&err)) {
786                         SLOG(LOG_ERROR, TAG_TTSC, "<<<< tts get private data : Get arguments error (%s)", err.message);
787                         dbus_error_free(&err);
788                         result = TTS_ERROR_OPERATION_FAILED;
789                 }
790                 dbus_message_unref(result_msg);
791
792                 if (0 == result) {
793                         SLOG(LOG_DEBUG, TAG_TTSC, "<<<< tts get private data : result(%d)", result);
794                         if (NULL != temp) {
795                                 *data = strdup(temp);
796                         }
797                 } else {
798                         SLOG(LOG_ERROR, TAG_TTSC, "<<<< tts get private data : result(%d)", result);
799                 }
800         } else {
801                 SLOG(LOG_ERROR, TAG_TTSC, "<<<< Result message is NULL ");
802                 tts_dbus_reconnect();
803                 result = TTS_ERROR_TIMED_OUT;
804         }
805
806         return result;
807 }
808
809 int tts_dbus_request_play(unsigned int uid, const char* credential)
810 {
811         DBusMessage* msg = __tts_dbus_make_message(uid, TTS_METHOD_PLAY);
812         if (NULL == msg) {
813                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts play : Fail to make message");
814                 return TTS_ERROR_OPERATION_FAILED;
815         } else {
816                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts play : uid(%u)", uid);
817         }
818
819         char *temp = NULL;
820         if (NULL == credential) {
821                 temp = strdup("NULL");
822         } else {
823                 temp = strdup(credential);
824         }
825
826         if (true != dbus_message_append_args(msg,
827                 DBUS_TYPE_UINT32, &uid,
828                 DBUS_TYPE_STRING, &temp,
829                 DBUS_TYPE_INVALID)) {
830                 dbus_message_unref(msg);
831                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to append args");
832
833                 if (NULL != temp) {
834                         free(temp);
835                         temp = NULL;
836                 }
837                 return TTS_ERROR_OPERATION_FAILED;
838         }
839
840         int result = __send_message_and_get_result(msg, TTS_METHOD_PLAY);
841         if (NULL != temp) {
842                 free(temp);
843                 temp = NULL;
844         }
845         return result;
846 }
847
848 int tts_dbus_request_stop(unsigned int uid)
849 {
850         DBusMessage* msg = __tts_dbus_make_message(uid, TTS_METHOD_STOP);
851         if (NULL == msg) {
852                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts stop : Fail to make message");
853                 return TTS_ERROR_OPERATION_FAILED;
854         } else {
855                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts stop : uid(%u)", uid);
856         }
857
858         if (true != dbus_message_append_args(msg, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INVALID)) {
859                 dbus_message_unref(msg);
860                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to append args");
861
862                 return TTS_ERROR_OPERATION_FAILED;
863         }
864
865         int result = __send_message_and_get_result(msg, TTS_METHOD_STOP);
866         return result;
867 }
868
869 int tts_dbus_request_pause(unsigned int uid)
870 {
871         DBusMessage* msg = __tts_dbus_make_message(uid, TTS_METHOD_PAUSE);
872         if (NULL == msg) {
873                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts pause : Fail to make message");
874                 return TTS_ERROR_OPERATION_FAILED;
875         } else {
876                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts pause : uid(%u)", uid);
877         }
878
879         if (true != dbus_message_append_args(msg, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INVALID)) {
880                 dbus_message_unref(msg);
881                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to append args");
882
883                 return TTS_ERROR_OPERATION_FAILED;
884         }
885
886         int result = __send_message_and_get_result(msg, TTS_METHOD_PAUSE);
887         return result;
888 }
889
890 //LCOV_EXCL_START
891 int tts_dbus_request_play_pcm(unsigned int uid)
892 {
893         DBusMessage* msg = __tts_dbus_make_message(uid, TTS_METHOD_PLAY_PCM);
894         if (NULL == msg) {
895                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts play pcm : Fail to make message");
896                 return TTS_ERROR_OPERATION_FAILED;
897         } else {
898                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts play pcm : uid(%u)", uid);
899         }
900
901         if (true != dbus_message_append_args(msg,
902                 DBUS_TYPE_UINT32, &uid,
903                 DBUS_TYPE_INVALID)) {
904                 dbus_message_unref(msg);
905                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to append args");
906                 return TTS_ERROR_OPERATION_FAILED;
907         }
908
909         int result = __send_message_and_get_result(msg, TTS_METHOD_PLAY_PCM);
910         return result;
911 }
912
913 int tts_dbus_request_stop_pcm(unsigned int uid)
914 {
915         DBusMessage* msg = __tts_dbus_make_message(uid, TTS_METHOD_STOP_PCM);
916         if (NULL == msg) {
917                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts stop pcm : Fail to make message");
918                 return TTS_ERROR_OPERATION_FAILED;
919         } else {
920                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts stop pcm : uid(%u)", uid);
921         }
922
923         if (true != dbus_message_append_args(msg,
924                 DBUS_TYPE_UINT32, &uid,
925                 DBUS_TYPE_INVALID)) {
926                 dbus_message_unref(msg);
927                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to append args");
928                 return TTS_ERROR_OPERATION_FAILED;
929         }
930
931         int result = __send_message_and_get_result(msg, TTS_METHOD_STOP_PCM);
932         return result;
933 }
934
935 int tts_dbus_request_add_pcm(unsigned int uid, int event, const char* data, int data_size, int audio_type, int rate)
936 {
937         DBusMessage* msg = __tts_dbus_make_message(uid, TTS_METHOD_ADD_PCM);
938         if (NULL == msg) {
939                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts add pcm : Fail to make message");
940                 return TTS_ERROR_OPERATION_FAILED;
941         } else {
942                 SLOG(LOG_ERROR, TAG_TTSC, ">>>> Request tts add pcm : uid(%u)", uid);
943         }
944
945         if (true != dbus_message_append_args(msg,
946                 DBUS_TYPE_UINT32, &uid,
947                 DBUS_TYPE_INT32, &event,
948                 DBUS_TYPE_INT32, &audio_type,
949                 DBUS_TYPE_INT32, &rate,
950                 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
951                 &data, data_size,
952                 DBUS_TYPE_INVALID)) {
953                 dbus_message_unref(msg);
954                 SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Fail to append args");
955                 return TTS_ERROR_OPERATION_FAILED;
956         }
957
958         int result = __send_message_and_get_result(msg, TTS_METHOD_ADD_PCM);
959         return result;
960 }
961 // LCOV_EXCL_STOP