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 if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_HELLO))
453 sttd_dbus_server_hello(conn, msg);
455 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_INITIALIZE))
456 sttd_dbus_server_initialize(conn, msg);
458 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_FINALIZE))
459 sttd_dbus_server_finalize(conn, msg);
461 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_GET_SUPPORT_LANGS))
462 sttd_dbus_server_get_support_lang(conn, msg);
464 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_GET_CURRENT_LANG))
465 sttd_dbus_server_get_default_lang(conn, msg);
467 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_IS_PARTIAL_SUPPORTED))
468 sttd_dbus_server_is_partial_result_supported(conn, msg);
470 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_START))
471 sttd_dbus_server_start(conn, msg);
473 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_STOP))
474 sttd_dbus_server_stop(conn, msg);
476 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_CANCEL))
477 sttd_dbus_server_cancel(conn, msg);
479 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_START_FILE_RECONITION))
480 sttd_dbus_server_start_file_recognition(conn, msg);
483 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_HELLO))
484 sttd_dbus_server_hello(conn, msg);
486 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_INITIALIZE))
487 sttd_dbus_server_setting_initialize(conn, msg);
489 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_FINALIZE))
490 sttd_dbus_server_setting_finalize(conn, msg);
492 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_GET_ENGINE_LIST))
493 sttd_dbus_server_setting_get_engine_list(conn, msg);
495 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_GET_ENGINE))
496 sttd_dbus_server_setting_get_engine(conn, msg);
498 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_SET_ENGINE))
499 sttd_dbus_server_setting_set_engine(conn, msg);
501 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_GET_LANG_LIST))
502 sttd_dbus_server_setting_get_language_list(conn, msg);
504 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_GET_DEFAULT_LANG))
505 sttd_dbus_server_setting_get_default_language(conn, msg);
507 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_SET_DEFAULT_LANG))
508 sttd_dbus_server_setting_set_default_language(conn, msg);
511 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_GET_PROFANITY))
512 sttd_dbus_server_setting_get_profanity_filter(conn, msg);
514 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_SET_PROFANITY))
515 sttd_dbus_server_setting_set_profanity_filter(conn, msg);
517 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_GET_PUNCTUATION))
518 sttd_dbus_server_setting_get_punctuation_override(conn, msg);
520 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_SET_PUNCTUATION))
521 sttd_dbus_server_setting_set_punctuation_override(conn, msg);
523 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_GET_SILENCE))
524 sttd_dbus_server_setting_get_silence_detection(conn, msg);
526 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_SET_SILENCE))
527 sttd_dbus_server_setting_set_silence_detection(conn, msg);
530 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_GET_ENGINE_SETTING))
531 sttd_dbus_server_setting_get_engine_setting(conn, msg);
533 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_SETTING_METHOD_SET_ENGINE_SETTING))
534 sttd_dbus_server_setting_set_engine_setting(conn, msg);
537 /* free the message */
538 dbus_message_unref(msg);
540 return ECORE_CALLBACK_RENEW;
543 int sttd_dbus_open_connection()
546 dbus_error_init(&err);
550 /* connect to the bus and check for errors */
551 g_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
553 if (dbus_error_is_set(&err)) {
554 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail dbus_bus_get : %s", err.message);
555 dbus_error_free(&err);
558 if (NULL == g_conn) {
559 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to get dbus connection" );
563 /* request our name on the bus and check for errors */
564 ret = dbus_bus_request_name(g_conn, STT_SERVER_SERVICE_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
566 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
567 printf("Fail to be primary owner in dbus request.");
568 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to be primary owner");
572 if (dbus_error_is_set(&err)) {
573 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] dbus_bus_request_name() : %s", err.message);
574 dbus_error_free(&err);
578 /* add a rule for getting signal */
580 snprintf(rule, 128, "type='signal',interface='%s'", STT_SERVER_SERVICE_INTERFACE);
582 /* add a rule for which messages we want to see */
583 dbus_bus_add_match(g_conn, rule, &err); /* see signals from the given interface */
584 dbus_connection_flush(g_conn);
586 if (dbus_error_is_set(&err)) {
587 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] dbus_bus_add_match() : %s", err.message);
592 dbus_connection_get_unix_fd(g_conn, &fd);
595 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] ecore_init()");
599 Ecore_Fd_Handler* fd_handler;
600 fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ , (Ecore_Fd_Cb)listener_event_callback, g_conn, NULL, NULL);
602 if (NULL == fd_handler) {
603 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to get fd handler");
610 int sttd_dbus_close_connection()
613 dbus_error_init(&err);
615 dbus_bus_release_name (g_conn, STT_SERVER_SERVICE_NAME, &err);
617 if (dbus_error_is_set(&err)) {
618 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] dbus_bus_release_name() : %s", err.message);
619 dbus_error_free(&err);