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