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