merge with master
[platform/core/uifw/tts.git] / server / ttsd_dbus.c
1 /*
2 *  Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd All Rights Reserved 
3 *  Licensed under the Apache License, Version 2.0 (the "License");
4 *  you may not use this file except in compliance with the License.
5 *  You may obtain a copy of the License at
6 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14
15 #include <dbus/dbus.h>
16 #include <Ecore.h>
17
18 #include "ttsd_main.h"
19 #include "ttsd_dbus_server.h"
20 #include "ttsd_dbus.h"
21 #include "ttsd_server.h"
22
23
24 static DBusConnection* g_conn;
25
26 static int g_waiting_time = 3000;
27
28 static char *g_service_name;
29 static char *g_service_object;
30 static char *g_service_interface;
31
32 int ttsdc_send_hello(int pid, int uid)
33 {
34         char service_name[64];
35         memset(service_name, 0, 64);
36         snprintf(service_name, 64, "%s%d", TTS_CLIENT_SERVICE_NAME, pid);
37
38         char target_if_name[64];
39         snprintf(target_if_name, sizeof(target_if_name), "%s%d", TTS_CLIENT_SERVICE_INTERFACE, pid);
40
41         DBusMessage* msg;
42
43         /* create a message & check for errors */
44         msg = dbus_message_new_method_call(
45                 service_name, 
46                 TTS_CLIENT_SERVICE_OBJECT_PATH, 
47                 target_if_name, 
48                 TTSD_METHOD_HELLO);
49
50         if (NULL == msg) { 
51                 SLOG(LOG_ERROR, get_tag(), "<<<< [Dbus ERROR] Fail to create hello message : uid(%d)", uid); 
52                 return -1;
53         } else {
54                 SLOG(LOG_DEBUG, get_tag(), "<<<< [Dbus] Send hello message : uid(%d)", uid);
55         }
56
57         dbus_message_append_args(msg, DBUS_TYPE_INT32, &uid, DBUS_TYPE_INVALID);
58
59         DBusError err;
60         dbus_error_init(&err);
61
62         DBusMessage* result_msg;
63         int result = -1;
64
65         result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
66         dbus_message_unref(msg);
67
68         if (NULL != result_msg) {
69                 dbus_message_get_args(result_msg, &err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
70
71                 if (dbus_error_is_set(&err)) { 
72                         SLOG(LOG_ERROR, get_tag(), ">>>> [Dbus] Get arguments error (%s)", err.message);
73                         dbus_error_free(&err); 
74                         result = -1;
75                 }
76
77                 dbus_message_unref(result_msg);
78         } else {
79                 SLOG(LOG_DEBUG, get_tag(), ">>>> [Dbus] Result message is NULL. Client is not available");
80                 result = 0;
81         }
82
83         return result;
84 }
85
86 int ttsdc_send_message(int pid, int uid, int data, char *method)
87 {   
88         char service_name[64];
89         memset(service_name, 0, 64);
90         snprintf(service_name, 64, "%s%d", TTS_CLIENT_SERVICE_NAME, pid);
91
92         char target_if_name[64];
93         snprintf(target_if_name, sizeof(target_if_name), "%s%d", TTS_CLIENT_SERVICE_INTERFACE, pid);
94
95         DBusMessage* msg;
96
97         /* create a message & check for errors */
98         msg = dbus_message_new_method_call(
99                 service_name, 
100                 TTS_CLIENT_SERVICE_OBJECT_PATH, 
101                 target_if_name, 
102                 method);
103
104         if (NULL == msg) { 
105                 SLOG(LOG_ERROR, get_tag(), "[Dbus ERROR] Fail to create message : type(%s), uid(%d)\n", method, uid); 
106                 return -1;
107         } 
108
109         dbus_message_append_args(msg, DBUS_TYPE_INT32, &uid, DBUS_TYPE_INT32, &data, DBUS_TYPE_INVALID);
110
111         /* send the message and flush the connection */
112         if (!dbus_connection_send(g_conn, msg, NULL)) {
113                 SLOG(LOG_ERROR, get_tag(), "[Dbus ERROR] <<<< send message : Out Of Memory, type(%s), ifname(%s), uid(%d), data(%d)", method, target_if_name, uid, data); 
114         } else {
115                 SLOG(LOG_DEBUG, get_tag(), "<<<< send message : type(%s), uid(%d), data(%d)", method, uid, data);
116
117                 dbus_connection_flush(g_conn);
118         }
119
120         dbus_message_unref(msg);
121
122         return 0;
123 }
124
125 int ttsdc_send_utt_start_message(int pid, int uid, int uttid)
126 {
127         return ttsdc_send_message(pid, uid, uttid, TTSD_METHOD_UTTERANCE_STARTED);
128 }
129
130 int ttsdc_send_utt_finish_message(int pid, int uid, int uttid) 
131 {
132         return ttsdc_send_message(pid, uid, uttid, TTSD_METHOD_UTTERANCE_COMPLETED);
133 }
134
135 int ttsdc_send_set_state_message(int pid, int uid, int state)
136 {
137         return ttsdc_send_message(pid, uid, state, TTSD_METHOD_SET_STATE);
138 }
139
140 int ttsdc_send_error_message(int pid, int uid, int uttid, int reason)
141 {
142         char service_name[64];
143         memset(service_name, 0, 64);
144         snprintf(service_name, 64, "%s%d", TTS_CLIENT_SERVICE_NAME, pid);
145
146         char target_if_name[128];
147         snprintf(target_if_name, sizeof(target_if_name), "%s%d", TTS_CLIENT_SERVICE_INTERFACE, pid);
148
149         DBusMessage* msg;
150
151         msg = dbus_message_new_method_call(
152                 service_name, 
153                 TTS_CLIENT_SERVICE_OBJECT_PATH, 
154                 target_if_name, 
155                 TTSD_METHOD_ERROR);
156
157         if (NULL == msg) { 
158                 SLOG(LOG_ERROR, get_tag(), "[Dbus ERROR] Fail to create error message : uid(%d)\n", uid); 
159                 return -1;
160         }
161
162         dbus_message_append_args( msg, 
163                 DBUS_TYPE_INT32, &uid, 
164                 DBUS_TYPE_INT32, &uttid, 
165                 DBUS_TYPE_INT32, &reason, 
166                 DBUS_TYPE_INVALID);
167         
168         if (!dbus_connection_send(g_conn, msg, NULL)) {
169                 SLOG(LOG_ERROR, get_tag(), "[Dbus ERROR] <<<< error message : Out Of Memory !\n"); 
170         } else {
171                 SLOG(LOG_DEBUG, get_tag(), "<<<< Send error signal : uid(%d), reason(%d), uttid(%d)", uid, reason, uttid);
172                 dbus_connection_flush(g_conn);
173         }
174
175         dbus_message_unref(msg);
176
177         return 0;
178 }
179
180
181 static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handler)
182 {
183         DBusConnection* conn = (DBusConnection*)data;
184
185         if (NULL == conn)       return ECORE_CALLBACK_RENEW;
186
187         dbus_connection_read_write_dispatch(conn, 50);
188
189         DBusMessage* msg = NULL;
190         msg = dbus_connection_pop_message(conn);
191
192         /* loop again if we haven't read a message */
193         if (NULL == msg || NULL == conn) { 
194                 return ECORE_CALLBACK_RENEW;
195         }
196
197         /* client event */
198         if (dbus_message_is_method_call(msg, g_service_interface, TTS_METHOD_HELLO))
199                 ttsd_dbus_server_hello(conn, msg);
200
201         else if( dbus_message_is_method_call(msg, g_service_interface, TTS_METHOD_INITIALIZE) )
202                 ttsd_dbus_server_initialize(conn, msg);
203         
204         else if( dbus_message_is_method_call(msg, g_service_interface, TTS_METHOD_FINALIZE) )
205                 ttsd_dbus_server_finalize(conn, msg);
206         
207         else if( dbus_message_is_method_call(msg, g_service_interface, TTS_METHOD_GET_SUPPORT_VOICES) )
208                 ttsd_dbus_server_get_support_voices(conn, msg);
209
210         else if( dbus_message_is_method_call(msg, g_service_interface, TTS_METHOD_GET_CURRENT_VOICE) )
211                 ttsd_dbus_server_get_current_voice(conn, msg);
212
213         else if( dbus_message_is_method_call(msg, g_service_interface, TTS_METHOD_ADD_QUEUE) )
214                 ttsd_dbus_server_add_text(conn, msg);
215
216         else if (dbus_message_is_method_call(msg, g_service_interface, TTS_METHOD_PLAY)) 
217                 ttsd_dbus_server_play(conn, msg);
218         
219         else if (dbus_message_is_method_call(msg, g_service_interface, TTS_METHOD_STOP)) 
220                 ttsd_dbus_server_stop(conn, msg);
221
222         else if (dbus_message_is_method_call(msg, g_service_interface, TTS_METHOD_PAUSE)) 
223                 ttsd_dbus_server_pause(conn, msg);
224
225         /* daemon internal event*/
226         else if (dbus_message_is_signal(msg, g_service_interface, TTSD_SIGNAL_NEXT_SYNTHESIS)) 
227                 ttsd_dbus_server_start_next_synthesis();
228
229         /* setting event */
230         else if (dbus_message_is_method_call(msg, g_service_interface, TTS_SETTING_METHOD_HELLO))
231                 ttsd_dbus_server_hello(conn, msg);
232
233         else if (dbus_message_is_method_call(msg, g_service_interface, TTS_SETTING_METHOD_INITIALIZE) )
234                 ttsd_dbus_server_setting_initialize(conn, msg);
235
236         else if (dbus_message_is_method_call(msg, g_service_interface, TTS_SETTING_METHOD_FINALIZE) )
237                 ttsd_dbus_server_setting_finalize(conn, msg);
238
239         else if (dbus_message_is_method_call(msg, g_service_interface, TTS_SETTING_METHOD_GET_ENGINE_LIST) )
240                 ttsd_dbus_server_setting_get_engine_list(conn, msg);
241
242         else if (dbus_message_is_method_call(msg, g_service_interface, TTS_SETTING_METHOD_GET_ENGINE) )
243                 ttsd_dbus_server_setting_get_engine(conn, msg);
244
245         else if (dbus_message_is_method_call(msg, g_service_interface, TTS_SETTING_METHOD_SET_ENGINE) )
246                 ttsd_dbus_server_setting_set_engine(conn, msg);
247
248         else if (dbus_message_is_method_call(msg, g_service_interface, TTS_SETTING_METHOD_GET_VOICE_LIST) )
249                 ttsd_dbus_server_setting_get_voice_list(conn, msg);
250
251         else if (dbus_message_is_method_call(msg, g_service_interface, TTS_SETTING_METHOD_GET_DEFAULT_VOICE) )
252                 ttsd_dbus_server_setting_get_default_voice(conn, msg);
253
254         else if (dbus_message_is_method_call(msg, g_service_interface, TTS_SETTING_METHOD_SET_DEFAULT_VOICE) )
255                 ttsd_dbus_server_setting_set_default_voice(conn, msg);
256
257         else if (dbus_message_is_method_call(msg, g_service_interface, TTS_SETTING_METHOD_GET_DEFAULT_SPEED) )
258                 ttsd_dbus_server_setting_get_speed(conn, msg);
259
260         else if (dbus_message_is_method_call(msg, g_service_interface, TTS_SETTING_METHOD_SET_DEFAULT_SPEED) )
261                 ttsd_dbus_server_setting_set_speed(conn, msg);
262
263         else if (dbus_message_is_method_call(msg, g_service_interface, TTS_SETTING_METHOD_GET_ENGINE_SETTING) )
264                 ttsd_dbus_server_setting_get_engine_setting(conn, msg);
265
266         else if (dbus_message_is_method_call(msg, g_service_interface, TTS_SETTING_METHOD_SET_ENGINE_SETTING) )
267                 ttsd_dbus_server_setting_set_engine_setting(conn, msg);
268         
269
270         /* free the message */
271         dbus_message_unref(msg);
272
273         return ECORE_CALLBACK_RENEW;
274 }
275
276 int ttsd_dbus_open_connection()
277 {
278         DBusError err;
279         dbus_error_init(&err);
280
281         int ret;
282
283         /* connect to the bus and check for errors */
284         g_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
285
286         if (dbus_error_is_set(&err)) { 
287                 SLOG(LOG_ERROR, get_tag(), "[Dbus ERROR] fail dbus_bus_get : %s\n", err.message);
288                 dbus_error_free(&err); 
289         }
290
291         if (NULL == g_conn) { 
292                 SLOG(LOG_ERROR, get_tag(), "[Dbus ERROR] fail to get dbus connection \n" );
293                 return -1;
294         }
295
296         if (TTSD_MODE_SCREEN_READER == ttsd_get_mode()) {
297                 g_service_name = (char*)malloc(sizeof(char) * strlen(TTS_SR_SERVER_SERVICE_NAME) + 1);
298                 g_service_object = (char*)malloc(sizeof(char) * strlen(TTS_SR_SERVER_SERVICE_OBJECT_PATH) + 1);
299                 g_service_interface = (char*)malloc(sizeof(char) * strlen(TTS_SR_SERVER_SERVICE_INTERFACE) + 1);
300
301                 strcpy(g_service_name, TTS_SR_SERVER_SERVICE_NAME);
302                 strcpy(g_service_object, TTS_SR_SERVER_SERVICE_OBJECT_PATH);
303                 strcpy(g_service_interface, TTS_SR_SERVER_SERVICE_INTERFACE);
304         } else if (TTSD_MODE_NOTIFICATION == ttsd_get_mode()) {
305                 g_service_name = (char*)malloc(sizeof(char) * strlen(TTS_NOTI_SERVER_SERVICE_NAME) + 1);
306                 g_service_object = (char*)malloc(sizeof(char) * strlen(TTS_NOTI_SERVER_SERVICE_OBJECT_PATH) + 1);
307                 g_service_interface = (char*)malloc(sizeof(char) * strlen(TTS_NOTI_SERVER_SERVICE_INTERFACE) + 1);
308
309                 strcpy(g_service_name, TTS_NOTI_SERVER_SERVICE_NAME);
310                 strcpy(g_service_object, TTS_NOTI_SERVER_SERVICE_OBJECT_PATH);
311                 strcpy(g_service_interface, TTS_NOTI_SERVER_SERVICE_INTERFACE);
312         } else {
313                 g_service_name = (char*)malloc(sizeof(char) * strlen(TTS_SERVER_SERVICE_NAME) + 1);
314                 g_service_object = (char*)malloc(sizeof(char) * strlen(TTS_SERVER_SERVICE_OBJECT_PATH) + 1);
315                 g_service_interface = (char*)malloc(sizeof(char) * strlen(TTS_SERVER_SERVICE_INTERFACE) + 1);
316
317                 strcpy(g_service_name, TTS_SERVER_SERVICE_NAME);
318                 strcpy(g_service_object, TTS_SERVER_SERVICE_OBJECT_PATH);
319                 strcpy(g_service_interface, TTS_SERVER_SERVICE_INTERFACE);
320         }
321
322         /* request our name on the bus and check for errors */
323         ret = dbus_bus_request_name(g_conn, g_service_name, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
324
325         if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
326                 printf("Fail to be primary owner in dbus request. \n");
327                 SLOG(LOG_ERROR, get_tag(), "[Dbus ERROR] fail to be primary owner \n");
328                 return -1;
329         }
330
331         if (dbus_error_is_set(&err)) { 
332                 SLOG(LOG_ERROR, get_tag(), "[Dbus ERROR] dbus_bus_request_name() : %s \n", err.message);
333                 dbus_error_free(&err); 
334
335                 return -1;
336         }
337
338         /* add a rule for getting signal */
339         char rule[128];
340         snprintf(rule, 128, "type='signal',interface='%s'", g_service_interface);
341
342         /* add a rule for which messages we want to see */
343         dbus_bus_add_match(g_conn, rule, &err); /* see signals from the given interface */
344         dbus_connection_flush(g_conn);
345
346         if (dbus_error_is_set(&err)) { 
347                 SLOG(LOG_ERROR, get_tag(), "[Dbus ERROR] dbus_bus_add_match() : %s \n", err.message);
348                 return -1; 
349         }
350
351         int fd = 0;
352         dbus_connection_get_unix_fd(g_conn, &fd);
353
354         Ecore_Fd_Handler* fd_handler;
355         fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ , (Ecore_Fd_Cb)listener_event_callback, g_conn, NULL, NULL);
356
357         if (NULL == fd_handler) {
358                 SLOG(LOG_ERROR, get_tag(), "[Dbus ERROR] ecore_main_fd_handler_add() : fail to get fd handler \n");
359                 return -1;
360         }
361
362         SLOG(LOG_DEBUG, get_tag(), "[Dbus SUCCESS] Open connection. ");
363         return 0;
364 }
365
366 int ttsd_dbus_close_connection()
367 {
368         DBusError err;
369         dbus_error_init(&err);
370
371         dbus_bus_release_name (g_conn, g_service_name, &err);
372
373         if (dbus_error_is_set(&err)) {
374                 SLOG(LOG_ERROR, get_tag(), "[Dbus ERROR] dbus_bus_release_name() : %s\n", err.message); 
375                 dbus_error_free(&err); 
376                 return -1;
377         }
378
379         if (NULL != g_service_name)
380                 free(g_service_name);
381
382         if (NULL != g_service_object)
383                 free(g_service_object);
384
385         if (NULL != g_service_interface)
386                 free(g_service_interface);
387
388         SLOG(LOG_DEBUG, get_tag(), "[Dbus SUCCESS] Close connection. ");
389
390         return 0;
391 }
392
393 int ttsd_send_start_next_synthesis()
394 {
395         DBusMessage* msg;
396
397         msg = dbus_message_new_signal(
398                 g_service_object,               /* object name of the signal */
399                 g_service_interface,            /* interface name of the signal */
400                 TTSD_SIGNAL_NEXT_SYNTHESIS);    /* name of the signal */
401
402         if (NULL == msg) { 
403                 SLOG(LOG_ERROR, get_tag(), "[Dbus ERROR] >>>> Fail to make message for 'start next synthesis'"); 
404                 return -1;
405         }
406
407         if (!dbus_connection_send(g_conn, msg, NULL)) {
408                 SLOG(LOG_ERROR, get_tag(), "[Dbus ERROR] >>>> Fail to send message for 'start next synthesis'"); 
409                 return -1;
410         }
411
412         dbus_connection_flush(g_conn);
413         dbus_message_unref(msg);
414
415         return 0;
416 }