2 * Copyright (c) 2011-2014 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 SECURE_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);
68 if (dbus_error_is_set(&err)) {
69 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Send error (%s)", err.message);
70 dbus_error_free(&err);
73 if (NULL != result_msg) {
74 dbus_message_get_args(result_msg, &err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
76 if (dbus_error_is_set(&err)) {
77 SLOG(LOG_ERROR, TAG_STTD, "[Dbus] Get arguments error (%s)\n", err.message);
78 dbus_error_free(&err);
82 dbus_message_unref(result_msg);
84 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] Result message is NULL. Client is not available");
91 int sttdc_send_get_state(int uid, int* state)
93 int pid = sttd_client_get_pid(uid);
96 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] pid is NOT valid");
100 char service_name[64];
101 memset(service_name, 0, 64);
102 snprintf(service_name, 64, "%s%d", STT_CLIENT_SERVICE_NAME, pid);
104 char target_if_name[128];
105 snprintf(target_if_name, sizeof(target_if_name), "%s%d", STT_CLIENT_SERVICE_INTERFACE, pid);
109 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] Send get state message : uid(%d)", uid);
111 msg = dbus_message_new_method_call(
113 STT_CLIENT_SERVICE_OBJECT_PATH,
115 STTD_METHOD_GET_STATE);
118 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to create message");
122 dbus_message_append_args(msg, DBUS_TYPE_INT32, &uid, DBUS_TYPE_INVALID);
125 dbus_error_init(&err);
127 DBusMessage* result_msg;
131 result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
132 dbus_message_unref(msg);
133 if (dbus_error_is_set(&err)) {
134 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Send error (%s)", err.message);
135 dbus_error_free(&err);
138 if (NULL != result_msg) {
139 dbus_message_get_args(result_msg, &err, DBUS_TYPE_INT32, &tmp, DBUS_TYPE_INVALID);
141 if (dbus_error_is_set(&err)) {
142 SLOG(LOG_ERROR, TAG_STTD, "[Dbus] Get arguments error (%s)\n", err.message);
143 dbus_error_free(&err);
150 dbus_message_unref(result_msg);
152 SLOG(LOG_ERROR, TAG_STTD, "[Dbus] Result message is NULL. Client is not available");
159 int sttdc_send_result(int uid, int event, const char** data, int data_count, const char* result_msg)
161 int pid = sttd_client_get_pid(uid);
164 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] pid is NOT valid" );
168 char service_name[64];
169 memset(service_name, 0, 64);
170 snprintf(service_name, 64, "%s%d", STT_CLIENT_SERVICE_NAME, pid);
172 char target_if_name[128];
173 snprintf(target_if_name, sizeof(target_if_name), "%s%d", STT_CLIENT_SERVICE_INTERFACE, pid);
177 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] send result signal : uid(%d), event(%d), result count(%d)", uid, event, data_count);
179 msg = dbus_message_new_method_call(
181 STT_CLIENT_SERVICE_OBJECT_PATH,
186 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to create message");
190 DBusMessageIter args;
191 dbus_message_iter_init_append(msg, &args);
193 /* Append uid & type */
194 dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &uid);
197 dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &event);
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");
217 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] result size (%d)", data_count);
218 for (i = 0;i < data_count;i++) {
219 if (NULL != data[i]) {
220 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] result (%d, %s)", i, data[i] );
222 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &data[i])) {
223 SLOG(LOG_ERROR, TAG_STTD, "[Dbus] response message : Fail to append result data");
227 int reason = (int)STTD_ERROR_OPERATION_FAILED;
229 if (0 != sttdc_send_error_signal(uid, reason, "Fail to get recognition result from engine")) {
230 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to send error info. Remove client data");
232 /* clean client data */
233 sttd_client_delete(uid);
236 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Result from engine is NULL(%d)", i);
241 if (!dbus_connection_send(g_conn, msg, NULL)) {
242 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to send message : Out Of Memory !");
246 dbus_connection_flush(g_conn);
247 dbus_message_unref(msg);
252 int sttdc_send_error_signal(int uid, int reason, const char *err_msg)
254 if (NULL == err_msg) {
255 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Input parameter is NULL");
256 return STTD_ERROR_INVALID_PARAMETER;
259 int pid = sttd_client_get_pid(uid);
262 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] pid is NOT valid" );
266 char service_name[64];
267 memset(service_name, 0, 64);
268 snprintf(service_name, 64, "%s%d", STT_CLIENT_SERVICE_NAME, pid);
270 char target_if_name[128];
271 snprintf(target_if_name, sizeof(target_if_name), "%s%d", STT_CLIENT_SERVICE_INTERFACE, pid);
274 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] send error signal : reason(%d), Error Msg(%s)", reason, err_msg);
276 msg = dbus_message_new_method_call(
278 STT_CLIENT_SERVICE_OBJECT_PATH,
283 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to create message");
287 dbus_message_append_args(msg,
288 DBUS_TYPE_INT32, &uid,
289 DBUS_TYPE_INT32, &reason,
290 DBUS_TYPE_STRING, &err_msg,
294 dbus_error_init(&err);
296 DBusMessage* result_msg;
298 result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
299 dbus_message_unref(msg);
300 if (dbus_error_is_set(&err)) {
301 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Send error (%s)", err.message);
302 dbus_error_free(&err);
305 if (NULL != result_msg) {
306 dbus_message_unref(result_msg);
308 SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] Result message is NULL.");
314 int sttdc_send_set_state(int uid, int state)
316 int pid = sttd_client_get_pid(uid);
319 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] pid is NOT valid");
323 char service_name[64];
324 memset(service_name, 0, 64);
325 snprintf(service_name, 64, "%s%d", STT_CLIENT_SERVICE_NAME, pid);
327 char target_if_name[128];
328 snprintf(target_if_name, sizeof(target_if_name), "%s%d", STT_CLIENT_SERVICE_INTERFACE, pid);
332 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Dbus] Send change state message : uid(%d), state(%d)", uid, state);
334 msg = dbus_message_new_method_call(
336 STT_CLIENT_SERVICE_OBJECT_PATH,
338 STTD_METHOD_SET_STATE);
341 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to create message");
345 dbus_message_append_args(msg,
346 DBUS_TYPE_INT32, &uid,
347 DBUS_TYPE_INT32, &state,
350 if (!dbus_connection_send(g_conn, msg, NULL)) {
351 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to send message : Out Of Memory !");
355 dbus_connection_flush(g_conn);
356 dbus_message_unref(msg);
361 static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handler)
363 DBusConnection* conn = (DBusConnection*)data;
364 DBusMessage* msg = NULL;
367 return ECORE_CALLBACK_RENEW;
369 dbus_connection_read_write_dispatch(conn, 50);
371 msg = dbus_connection_pop_message(conn);
373 if (true != dbus_connection_get_is_connected(conn)) {
374 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Conn is disconnected");
375 return ECORE_CALLBACK_RENEW;
378 /* loop again if we haven't read a message */
380 return ECORE_CALLBACK_RENEW;
384 if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_HELLO))
385 sttd_dbus_server_hello(conn, msg);
387 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_INITIALIZE))
388 sttd_dbus_server_initialize(conn, msg);
390 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_FINALIZE))
391 sttd_dbus_server_finalize(conn, msg);
393 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_SET_CURRENT_ENGINE))
394 sttd_dbus_server_set_current_engine(conn, msg);
396 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_CHECK_APP_AGREED))
397 sttd_dbus_server_check_app_agreed(conn, msg);
399 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_GET_SUPPORT_LANGS))
400 sttd_dbus_server_get_support_lang(conn, msg);
402 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_GET_CURRENT_LANG))
403 sttd_dbus_server_get_default_lang(conn, msg);
405 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_IS_TYPE_SUPPORTED))
406 sttd_dbus_server_is_recognition_type_supported(conn, msg);
409 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_SET_START_SOUND))
410 sttd_dbus_server_set_start_sound(conn, msg);
412 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_UNSET_START_SOUND))
413 sttd_dbus_server_unset_start_sound(conn, msg);
415 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_SET_STOP_SOUND))
416 sttd_dbus_server_set_stop_sound(conn, msg);
418 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_UNSET_STOP_SOUND))
419 sttd_dbus_server_unset_stop_sound(conn, msg);
422 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_START))
423 sttd_dbus_server_start(conn, msg);
425 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_STOP))
426 sttd_dbus_server_stop(conn, msg);
428 else if (dbus_message_is_method_call(msg, STT_SERVER_SERVICE_INTERFACE, STT_METHOD_CANCEL))
429 sttd_dbus_server_cancel(conn, msg);
432 /* free the message */
433 dbus_message_unref(msg);
435 return ECORE_CALLBACK_RENEW;
438 int sttd_dbus_open_connection()
441 dbus_error_init(&err);
445 /* connect to the bus and check for errors */
446 g_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
448 if (dbus_error_is_set(&err)) {
449 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail dbus_bus_get : %s", err.message);
450 dbus_error_free(&err);
453 if (NULL == g_conn) {
454 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to get dbus connection" );
458 /* request our name on the bus and check for errors */
459 ret = dbus_bus_request_name(g_conn, STT_SERVER_SERVICE_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
461 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
462 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to be primary owner");
466 if (dbus_error_is_set(&err)) {
467 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] dbus_bus_request_name() : %s", err.message);
468 dbus_error_free(&err);
472 /* add a rule for getting signal */
474 snprintf(rule, 128, "type='signal',interface='%s'", STT_SERVER_SERVICE_INTERFACE);
476 /* add a rule for which messages we want to see */
477 dbus_bus_add_match(g_conn, rule, &err); /* see signals from the given interface */
478 dbus_connection_flush(g_conn);
480 if (dbus_error_is_set(&err)) {
481 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] dbus_bus_add_match() : %s", err.message);
486 dbus_connection_get_unix_fd(g_conn, &fd);
489 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] ecore_init()");
493 Ecore_Fd_Handler* fd_handler;
494 fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ , (Ecore_Fd_Cb)listener_event_callback, g_conn, NULL, NULL);
496 if (NULL == fd_handler) {
497 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] Fail to get fd handler");
504 int sttd_dbus_close_connection()
507 dbus_error_init(&err);
509 dbus_bus_release_name (g_conn, STT_SERVER_SERVICE_NAME, &err);
511 if (dbus_error_is_set(&err)) {
512 SLOG(LOG_ERROR, TAG_STTD, "[Dbus ERROR] dbus_bus_release_name() : %s", err.message);
513 dbus_error_free(&err);