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.
15 #include <dbus/dbus.h>
18 #include "sttd_main.h"
19 #include "sttd_dbus.h"
20 #include "sttd_client_data.h"
21 #include "sttd_dbus_server.h"
24 static DBusConnection* g_conn;
25 static int g_waiting_time = 3000;
27 int sttdc_send_hello(int uid)
29 int pid = sttd_client_get_pid(uid);
32 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] pid is NOT valid");
36 char service_name[64];
37 memset(service_name, 0, 64);
38 snprintf(service_name, 64, "%s%d", STT_CLIENT_SERVICE_NAME, pid);
40 char target_if_name[128];
41 snprintf(target_if_name, sizeof(target_if_name), "%s%d", STT_CLIENT_SERVICE_INTERFACE, pid);
45 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] Send hello message : uid(%d)", uid);
47 msg = dbus_message_new_method_call(
49 STT_CLIENT_SERVICE_OBJECT_PATH,
54 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to create message");
58 dbus_message_append_args(msg, DBUS_TYPE_INT32, &uid, DBUS_TYPE_INVALID);
61 dbus_error_init(&err);
63 DBusMessage* result_msg;
66 result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
67 dbus_message_unref(msg);
69 if (NULL != result_msg) {
70 dbus_message_get_args(result_msg, &err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
72 if (dbus_error_is_set(&err)) {
73 SLOG(LOG_ERROR, TAG_STTD, "[Dbus] Get arguments error (%s)\n", err.message);
74 dbus_error_free(&err);
78 dbus_message_unref(result_msg);
80 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] Result message is NULL. Client is not available");
87 int sttdc_send_get_state(int uid, int* state)
89 int pid = sttd_client_get_pid(uid);
92 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] pid is NOT valid");
96 char service_name[64];
97 memset(service_name, 0, 64);
98 snprintf(service_name, 64, "%s%d", STT_CLIENT_SERVICE_NAME, pid);
100 char target_if_name[128];
101 snprintf(target_if_name, sizeof(target_if_name), "%s%d", STT_CLIENT_SERVICE_INTERFACE, pid);
105 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] Send get state message : uid(%d)", uid);
107 msg = dbus_message_new_method_call(
109 STT_CLIENT_SERVICE_OBJECT_PATH,
111 STTD_METHOD_GET_STATE);
114 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to create message");
118 dbus_message_append_args(msg, DBUS_TYPE_INT32, &uid, DBUS_TYPE_INVALID);
121 dbus_error_init(&err);
123 DBusMessage* result_msg;
127 result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
128 dbus_message_unref(msg);
130 if (NULL != result_msg) {
131 dbus_message_get_args(result_msg, &err, DBUS_TYPE_INT32, &tmp, DBUS_TYPE_INVALID);
133 if (dbus_error_is_set(&err)) {
134 SLOG(LOG_ERROR, TAG_STTD, "[Dbus] Get arguments error (%s)\n", err.message);
135 dbus_error_free(&err);
142 dbus_message_unref(result_msg);
144 SLOG(LOG_ERROR, TAG_STTD, "[Dbus] Result message is NULL. Client is not available");
151 int sttdc_send_result(int uid, const char* type, const char** data, int data_count, const char* result_msg)
153 int pid = sttd_client_get_pid(uid);
156 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] pid is NOT valid" );
160 char service_name[64];
161 memset(service_name, 0, 64);
162 snprintf(service_name, 64, "%s%d", STT_CLIENT_SERVICE_NAME, pid);
164 char target_if_name[128];
165 snprintf(target_if_name, sizeof(target_if_name), "%s%d", STT_CLIENT_SERVICE_INTERFACE, pid);
169 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] send result signal : uid(%d), type(%s), result count(%d)", uid, type, data_count);
171 msg = dbus_message_new_method_call(
173 STT_CLIENT_SERVICE_OBJECT_PATH,
178 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to create message");
182 DBusMessageIter args;
183 dbus_message_iter_init_append(msg, &args);
185 /* Append uid & type */
186 dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &uid);
190 msg_temp = strdup("None");
191 dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &(msg_temp));
192 SLOG(LOG_WARN, TAG_STTD, "[Dbus] result type is NULL");
195 dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &(type));
196 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] result type(%s)", type );
199 /* Append result msg */
200 if (NULL == result_msg) {
201 msg_temp = strdup("None");
202 dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &msg_temp);
203 SLOG(LOG_WARN, TAG_STTD, "[Dbus] result message is NULL");
206 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] result message(%s)", result_msg );
207 dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &(result_msg));
210 /* Append result size */
211 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &(data_count))) {
212 SLOG(LOG_ERROR, TAG_STTD, "[Dbus] response message : Fail to append result size");
218 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] result size (%d)", data_count);
219 for (i=0 ; i<data_count ; i++) {
220 if (NULL != data[i]) {
221 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] result (%d, %s)", i, data[i] );
223 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &data[i])) {
224 SLOG(LOG_ERROR, TAG_STTD, "[Dbus] response message : Fail to append result data");
228 int reason = (int)STTD_ERROR_OPERATION_FAILED;
230 if (0 != sttdc_send_error_signal(uid, reason, "Fail to get recognition result from engine")) {
231 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to send error info. Remove client data");
233 /* clean client data */
234 sttd_client_delete(uid);
237 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Result from engine is NULL(%d) %s", i);
243 if (!dbus_connection_send(g_conn, msg, NULL)) {
244 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to send message : Out Of Memory !");
248 dbus_connection_flush(g_conn);
249 dbus_message_unref(msg);
254 int sttdc_send_partial_result(int uid, const char* data)
256 int pid = sttd_client_get_pid(uid);
259 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] pid is NOT valid" );
264 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Input data is NULL" );
268 char service_name[64];
269 memset(service_name, 0, 64);
270 snprintf(service_name, 64, "%s%d", STT_CLIENT_SERVICE_NAME, pid);
272 char target_if_name[128];
273 snprintf(target_if_name, sizeof(target_if_name), "%s%d", STT_CLIENT_SERVICE_INTERFACE, pid);
277 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] send result signal : uid(%d), result(%s)", uid, data);
279 msg = dbus_message_new_method_call(
281 STT_CLIENT_SERVICE_OBJECT_PATH,
283 STTD_METHOD_PARTIAL_RESULT);
286 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to create message");
290 DBusMessageIter args;
291 dbus_message_iter_init_append(msg, &args);
293 /* Append uid & type */
294 dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &uid);
296 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] Partial result (%s)", data );
298 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, data)) {
299 SLOG(LOG_ERROR, TAG_STTD, "[Dbus] response message : Fail to append result data");
303 if (!dbus_connection_send(g_conn, msg, NULL)) {
304 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to send message : Out Of Memory !");
308 dbus_connection_flush(g_conn);
309 dbus_message_unref(msg);
314 int sttdc_send_error_signal(int uid, int reason, char *err_msg)
316 if (NULL == err_msg) {
317 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Input parameter is NULL");
318 return STTD_ERROR_INVALID_PARAMETER;
321 int pid = sttd_client_get_pid(uid);
324 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] pid is NOT valid" );
328 char service_name[64];
329 memset(service_name, 0, 64);
330 snprintf(service_name, 64, "%s%d", STT_CLIENT_SERVICE_NAME, pid);
332 char target_if_name[128];
333 snprintf(target_if_name, sizeof(target_if_name), "%s%d", STT_CLIENT_SERVICE_INTERFACE, pid);
336 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] send error signal : reason(%d), Error Msg(%s)", reason, err_msg);
338 msg = dbus_message_new_method_call(
340 STT_CLIENT_SERVICE_OBJECT_PATH,
345 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to create message");
349 dbus_message_append_args(msg,
350 DBUS_TYPE_INT32, &uid,
351 DBUS_TYPE_INT32, &reason,
352 DBUS_TYPE_STRING, &err_msg,
356 dbus_error_init(&err);
358 DBusMessage* result_msg;
360 result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
361 dbus_message_unref(msg);
363 if (NULL != result_msg) {
364 dbus_message_unref(result_msg);
366 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] Result message is NULL.");
372 int sttdc_send_set_state(int uid, int state)
374 int pid = sttd_client_get_pid(uid);
377 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] pid is NOT valid");
381 char service_name[64];
382 memset(service_name, 0, 64);
383 snprintf(service_name, 64, "%s%d", STT_CLIENT_SERVICE_NAME, pid);
385 char target_if_name[128];
386 snprintf(target_if_name, sizeof(target_if_name), "%s%d", STT_CLIENT_SERVICE_INTERFACE, pid);
390 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] Send change state message : uid(%d), state(%d)", uid, state);
392 msg = dbus_message_new_method_call(
394 STT_CLIENT_SERVICE_OBJECT_PATH,
396 STTD_METHOD_SET_STATE);
399 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to create message");
403 dbus_message_append_args(msg,
404 DBUS_TYPE_INT32, &uid,
405 DBUS_TYPE_INT32, &state,
409 dbus_error_init(&err);
411 DBusMessage* result_msg;
414 result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
415 dbus_message_unref(msg);
417 if (NULL != result_msg) {
418 dbus_message_get_args(result_msg, &err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
420 if (dbus_error_is_set(&err)) {
421 SLOG(LOG_ERROR, TAG_STTD, "[Dbus] Get arguments error (%s)\n", err.message);
422 dbus_error_free(&err);
426 dbus_message_unref(result_msg);
428 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] Result message is NULL. Client is not available");
434 static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handler)
436 DBusConnection* conn = (DBusConnection*)data;
437 DBusMessage* msg = NULL;
440 return ECORE_CALLBACK_RENEW;
442 dbus_connection_read_write_dispatch(conn, 50);
444 msg = dbus_connection_pop_message(conn);
446 /* loop again if we haven't read a message */
447 if (NULL == msg || NULL == conn) {
448 return ECORE_CALLBACK_RENEW;
452 /* daemon internal event */
453 if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STTD_METHOD_STOP_BY_DAEMON))
454 sttd_dbus_server_stop_by_daemon(msg);
457 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_HELLO))
458 sttd_dbus_server_hello(conn, msg);
460 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_INITIALIZE))
461 sttd_dbus_server_initialize(conn, msg);
463 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_FINALIZE))
464 sttd_dbus_server_finalize(conn, msg);
466 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_GET_SUPPORT_LANGS))
467 sttd_dbus_server_get_support_lang(conn, msg);
469 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_GET_CURRENT_LANG))
470 sttd_dbus_server_get_default_lang(conn, msg);
472 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_IS_PARTIAL_SUPPORTED))
473 sttd_dbus_server_is_partial_result_supported(conn, msg);
475 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_GET_AUDIO_VOLUME))
476 sttd_dbus_server_get_audio_volume(conn, msg);
478 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_START))
479 sttd_dbus_server_start(conn, msg);
481 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_STOP))
482 sttd_dbus_server_stop(conn, msg);
484 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_CANCEL))
485 sttd_dbus_server_cancel(conn, msg);
489 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_HELLO))
490 sttd_dbus_server_hello(conn, msg);
492 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_INITIALIZE))
493 sttd_dbus_server_setting_initialize(conn, msg);
495 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_FINALIZE))
496 sttd_dbus_server_setting_finalize(conn, msg);
498 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_GET_ENGINE_LIST))
499 sttd_dbus_server_setting_get_engine_list(conn, msg);
501 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_GET_ENGINE))
502 sttd_dbus_server_setting_get_engine(conn, msg);
504 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_SET_ENGINE))
505 sttd_dbus_server_setting_set_engine(conn, msg);
507 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_GET_LANG_LIST))
508 sttd_dbus_server_setting_get_language_list(conn, msg);
510 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_GET_DEFAULT_LANG))
511 sttd_dbus_server_setting_get_default_language(conn, msg);
513 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_SET_DEFAULT_LANG))
514 sttd_dbus_server_setting_set_default_language(conn, msg);
517 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_GET_PROFANITY))
518 sttd_dbus_server_setting_get_profanity_filter(conn, msg);
520 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_SET_PROFANITY))
521 sttd_dbus_server_setting_set_profanity_filter(conn, msg);
523 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_GET_PUNCTUATION))
524 sttd_dbus_server_setting_get_punctuation_override(conn, msg);
526 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_SET_PUNCTUATION))
527 sttd_dbus_server_setting_set_punctuation_override(conn, msg);
529 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_GET_SILENCE))
530 sttd_dbus_server_setting_get_silence_detection(conn, msg);
532 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_SET_SILENCE))
533 sttd_dbus_server_setting_set_silence_detection(conn, msg);
536 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_GET_ENGINE_SETTING))
537 sttd_dbus_server_setting_get_engine_setting(conn, msg);
539 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_SET_ENGINE_SETTING))
540 sttd_dbus_server_setting_set_engine_setting(conn, msg);
543 /* free the message */
544 dbus_message_unref(msg);
546 return ECORE_CALLBACK_RENEW;
549 int sttd_dbus_open_connection()
552 dbus_error_init(&err);
556 /* connect to the bus and check for errors */
557 g_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
559 if (dbus_error_is_set(&err)) {
560 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail dbus_bus_get : %s", err.message);
561 dbus_error_free(&err);
564 if (NULL == g_conn) {
565 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to get dbus connection" );
569 /* request our name on the bus and check for errors */
570 ret = dbus_bus_request_name(g_conn, STT_SERVER_SERVICE_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
572 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
573 printf("Fail to be primary owner in dbus request.");
574 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to be primary owner");
578 if (dbus_error_is_set(&err)) {
579 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] dbus_bus_request_name() : %s", err.message);
580 dbus_error_free(&err);
584 /* add a rule for getting signal */
586 snprintf(rule, 128, "type='signal',interface='%s'", STT_SERVER_SERVICE_INTERFACE);
588 /* add a rule for which messages we want to see */
589 dbus_bus_add_match(g_conn, rule, &err); /* see signals from the given interface */
590 dbus_connection_flush(g_conn);
592 if (dbus_error_is_set(&err)) {
593 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] dbus_bus_add_match() : %s", err.message);
598 dbus_connection_get_unix_fd(g_conn, &fd);
601 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] ecore_init()");
605 Ecore_Fd_Handler* fd_handler;
606 fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ , (Ecore_Fd_Cb)listener_event_callback, g_conn, NULL, NULL);
608 if (NULL == fd_handler) {
609 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to get fd handler");
616 int sttd_dbus_close_connection()
619 dbus_error_init(&err);
621 dbus_bus_release_name (g_conn, STT_SERVER_SERVICE_NAME, &err);
623 if (dbus_error_is_set(&err)) {
624 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] dbus_bus_release_name() : %s", err.message);
625 dbus_error_free(&err);
632 int sttd_send_stop_recognition_by_daemon(int uid)
636 msg = dbus_message_new_method_call(
637 STT_SERVER_SERVICE_NAME,
638 STT_SERVER_SERVICE_OBJECT_PATH,
639 STT_SERVER_SERVICE_INTERFACE,
640 STTD_METHOD_STOP_BY_DAEMON);
643 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] >>>> Fail to make message for 'stop by daemon'");
647 dbus_message_append_args(msg, DBUS_TYPE_INT32, &uid, DBUS_TYPE_INVALID);
649 if (!dbus_connection_send(g_conn, msg, NULL)) {
650 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to send message for 'stop by daemon'");
653 dbus_connection_flush(g_conn);
654 dbus_message_unref(msg);