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 <sound_manager.h>
16 #include <wav_player.h>
18 #include "stt_network.h"
19 #include "sttd_client_data.h"
20 #include "sttd_config.h"
21 #include "sttd_dbus.h"
22 #include "sttd_engine_agent.h"
23 #include "sttd_main.h"
24 #include "sttd_recorder.h"
25 #include "sttd_server.h"
27 static pthread_mutex_t sttpe_result_mutex = PTHREAD_MUTEX_INITIALIZER;
28 static pthread_mutex_t sttpe_result_time_mutex = PTHREAD_MUTEX_INITIALIZER;
32 * STT Server static variable
34 static double g_processing_timeout = 30;
36 static double g_recording_timeout = 60;
38 Ecore_Timer* g_recording_timer = NULL;
39 Ecore_Timer* g_processing_timer = NULL;
41 static int g_recording_log_count = 0;
43 static GList *g_proc_list = NULL;
46 * STT Server Callback Functions
48 void __stop_by_silence(void *data)
50 SLOG(LOG_DEBUG, TAG_STTD, "===== Stop by silence detection");
54 uid = stt_client_get_current_recognition();
58 ret = sttd_server_stop(uid);
63 if (STTD_RESULT_STATE_DONE == ret) {
64 ret = sttdc_send_set_state(uid, (int)APP_STATE_PROCESSING);
66 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send state : result(%d)", ret);
69 sttd_server_finalize(uid);
70 stt_client_unset_current_recognition();
74 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid is NOT valid");
77 SLOG(LOG_DEBUG, TAG_STTD, "=====");
78 SLOG(LOG_DEBUG, TAG_STTD, " ");
83 static void __cancel_recognition_internal()
85 if (NULL != g_recording_timer) {
86 ecore_timer_del(g_recording_timer);
87 g_recording_timer = NULL;
91 uid = stt_client_get_current_recognition();
94 /* cancel engine recognition */
95 int ret = sttd_engine_agent_recognize_cancel(uid);
97 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
100 /* change uid state */
101 sttd_client_set_state(uid, APP_STATE_READY);
102 stt_client_unset_current_recognition();
104 ret = sttdc_send_set_state(uid, (int)APP_STATE_READY);
106 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send state change : result(%d)", ret);
109 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid is NOT valid");
113 static void __cancel_by_error(void *data)
115 SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by error");
117 __cancel_recognition_internal();
119 SLOG(LOG_DEBUG, TAG_STTD, "=====");
120 SLOG(LOG_DEBUG, TAG_STTD, " ");
125 int __server_audio_recorder_callback(const void* data, const unsigned int length)
130 if (NULL == data || 0 == length) {
131 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Recording data is not valid");
132 ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
136 uid = stt_client_get_current_recognition();
138 ret = sttd_engine_agent_set_recording_data(uid, data, length);
140 ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
143 g_recording_log_count++;
144 if (200 <= g_recording_log_count) {
145 SLOG(LOG_DEBUG, TAG_STTD, "=== Set recording data ===");
146 g_recording_log_count = 0;
149 if (NULL != g_recording_timer) {
150 ecore_timer_del(g_recording_timer);
151 g_recording_timer = NULL;
153 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current uid in recording is is not valid");
160 void __server_audio_interrupt_callback()
162 SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by sound interrupt");
164 __cancel_recognition_internal();
166 SLOG(LOG_DEBUG, TAG_STTD, "=====");
167 SLOG(LOG_DEBUG, TAG_STTD, " ");
170 void __cancel_by_no_record(void *data)
172 SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by no record");
174 __cancel_recognition_internal();
176 SLOG(LOG_DEBUG, TAG_STTD, "=====");
177 SLOG(LOG_DEBUG, TAG_STTD, " ");
182 void __server_recognition_result_callback(sttp_result_event_e event, const char* type,
183 const char** data, int data_count, const char* msg, void *user_data)
186 pthread_mutex_lock(&sttpe_result_mutex);
188 SLOG(LOG_DEBUG, TAG_STTD, "===== RESULT event[%d] type[%s] data[%p] data_count[%d]", event, type, data, data_count);
191 int uid = stt_client_get_current_recognition();
194 if (0 == uid || 0 != sttd_client_get_state(uid, &state)) {
195 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
196 SLOG(LOG_DEBUG, TAG_STTD, "=====");
197 SLOG(LOG_DEBUG, TAG_STTD, " ");
198 pthread_mutex_unlock(&sttpe_result_mutex);
202 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid (%d), event(%d)", uid, event);
204 /* send result to client */
205 if (STTP_RESULT_EVENT_FINAL_RESULT == event) {
206 if (APP_STATE_PROCESSING != state) {
207 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is NOT 'Processing'.");
209 SLOG(LOG_DEBUG, TAG_STTD, "[Server] the size of result from engine is '%d'", data_count);
211 /* Delete timer for processing time out */
212 if (NULL != g_processing_timer) {
213 ecore_timer_del(g_processing_timer);
214 g_processing_timer = NULL;
217 sttd_config_time_save();
218 sttd_config_time_reset();
220 if (NULL == data || 0 == data_count) {
221 if (0 != sttdc_send_result(uid, event, NULL, 0, msg)) {
222 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
223 int reason = (int)STTD_ERROR_OPERATION_FAILED;
225 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
226 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
230 if (0 != sttdc_send_result(uid, event, data, data_count, msg)) {
231 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
232 int reason = (int)STTD_ERROR_OPERATION_FAILED;
234 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
235 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
240 /* change state of uid */
241 sttd_client_set_state(uid, APP_STATE_READY);
242 stt_client_unset_current_recognition();
244 } else if (STTP_RESULT_EVENT_PARTIAL_RESULT == event) {
245 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The partial result from engine is event[%d] data_count[%d]", event, data_count);
247 sttd_config_time_save();
248 sttd_config_time_reset();
250 if (0 != sttdc_send_result(uid, event, data, data_count, msg)) {
251 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
252 int reason = (int)STTD_ERROR_OPERATION_FAILED;
254 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
255 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
259 } else if (STTP_RESULT_EVENT_ERROR == event) {
260 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The event of recognition result is ERROR");
262 /* Delete timer for processing time out */
263 if (NULL != g_processing_timer) {
264 ecore_timer_del(g_processing_timer);
265 g_processing_timer = NULL;
267 sttd_config_time_reset();
269 if (0 != sttdc_send_result(uid, event, NULL, 0, msg)) {
270 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
273 int reason = (int)STTD_ERROR_INVALID_STATE;
274 if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
275 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
279 /* change state of uid */
280 sttd_client_set_state(uid, APP_STATE_READY);
281 stt_client_unset_current_recognition();
286 SLOG(LOG_DEBUG, TAG_STTD, "=====");
287 SLOG(LOG_DEBUG, TAG_STTD, " ");
288 pthread_mutex_unlock(&sttpe_result_mutex);
293 bool __server_result_time_callback(int index, sttp_result_time_event_e event, const char* text, long start_time, long end_time, void* user_data)
295 pthread_mutex_lock(&sttpe_result_time_mutex);
297 SLOG(LOG_DEBUG, TAG_STTD, "[Server] index(%d) event(%d) text(%s) start(%ld) end(%ld)",
298 index, event, text, start_time, end_time);
302 ret = sttd_config_time_add(index, (int)event, text, start_time, end_time);
304 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add time info");
305 pthread_mutex_unlock(&sttpe_result_time_mutex);
309 pthread_mutex_unlock(&sttpe_result_time_mutex);
313 pthread_mutex_unlock(&sttpe_result_time_mutex);
318 void __server_silence_dectection_callback(sttp_silence_type_e type, void *user_param)
320 SLOG(LOG_DEBUG, TAG_STTD, "===== Silence Detection Callback");
322 int uid = stt_client_get_current_recognition();
325 if (0 != sttd_client_get_state(uid, &state)) {
326 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is not valid ");
330 if (APP_STATE_RECORDING != state) {
331 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
335 if (STTP_SILENCE_TYPE_NO_RECORD_TIMEOUT == type) {
336 SLOG(LOG_DEBUG, TAG_STTD, "Silence Detection type - No Record");
337 ecore_main_loop_thread_safe_call_async(__cancel_by_no_record, NULL);
338 } else if (STTP_SILENCE_TYPE_END_OF_SPEECH_DETECTED == type) {
339 SLOG(LOG_DEBUG, TAG_STTD, "Silence Detection type - End of Speech");
340 ecore_main_loop_thread_safe_call_async(__stop_by_silence, NULL);
343 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current recogntion uid is not valid ");
346 SLOG(LOG_DEBUG, TAG_STTD, "=====");
347 SLOG(LOG_DEBUG, TAG_STTD, " ");
352 void __sttd_server_engine_changed_cb(const char* engine_id, const char* language, bool support_silence, void* user_data)
354 if (NULL == engine_id) {
355 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Engine id is NULL");
358 SLOG(LOG_DEBUG, TAG_STTD, "[Server] New default engine : %s", engine_id);
361 /* need to change state of app to ready */
363 uid = stt_client_get_current_recognition();
366 SLOG(LOG_ERROR, TAG_STTD, "[Server] Set ready state of uid(%d)", uid);
368 sttd_server_cancel(uid);
369 sttdc_send_set_state(uid, (int)APP_STATE_READY);
371 stt_client_unset_current_recognition();
375 int ret = sttd_engine_agent_set_default_engine(engine_id);
377 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : result(%d)", ret);
379 if (NULL != language) {
380 ret = sttd_engine_agent_set_default_language(language);
382 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%d)", ret);
385 ret = sttd_engine_agent_set_silence_detection(support_silence);
387 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret);
392 void __sttd_server_language_changed_cb(const char* language, void* user_data)
394 if (NULL == language) {
395 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] language is NULL");
398 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Get language changed : %s", language);
401 int ret = sttd_engine_agent_set_default_language(language);
403 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%d)", ret);
408 void __sttd_server_silence_changed_cb(bool value, void* user_data)
410 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Get silence detection changed : %s", value ? "on" : "off");
413 ret = sttd_engine_agent_set_silence_detection(value);
415 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret);
424 int sttd_initialize()
428 if (0 != pthread_mutex_init(&sttpe_result_mutex, NULL)) {
429 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize sttpe result mutex.");
432 if (0 != pthread_mutex_init(&sttpe_result_time_mutex, NULL)) {
433 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize sttpe sttpe_result_time_mutex.");
436 if (sttd_config_initialize(__sttd_server_engine_changed_cb, __sttd_server_language_changed_cb,
437 __sttd_server_silence_changed_cb, NULL)) {
438 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize config.");
441 ret = sttd_recorder_initialize(__server_audio_recorder_callback, __server_audio_interrupt_callback);
443 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize recorder : result(%d)", ret);
446 /* Engine Agent initialize */
447 ret = sttd_engine_agent_init(__server_recognition_result_callback, __server_result_time_callback,
448 __server_silence_dectection_callback);
450 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine agent initialize : result(%d)", ret);
454 /* Update engine list */
455 ret = sttd_engine_agent_initialize_engine_list();
457 if (STTD_ERROR_ENGINE_NOT_FOUND == ret) {
458 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] There is no stt engine");
460 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to update engine list : %d", ret);
465 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] initialize");
472 if (0 != pthread_mutex_destroy(&sttpe_result_mutex)) {
473 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy sttpe result mutex.");
476 if (0 != pthread_mutex_destroy(&sttpe_result_time_mutex)) {
477 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy sttpe_result_time_mutex.");
481 if (0 < g_list_length(g_proc_list)) {
482 iter = g_list_first(g_proc_list);
483 while (NULL != iter) {
484 g_proc_list = g_list_remove_link(g_proc_list, iter);
485 iter = g_list_first(g_proc_list);
489 sttd_recorder_deinitialize();
491 sttd_config_finalize();
493 sttd_engine_agent_release();
495 return STTD_ERROR_NONE;
498 static void __read_proc()
502 struct dirent *dirp = NULL;
507 if (0 < g_list_length(g_proc_list)) {
508 iter = g_list_first(g_proc_list);
509 while (NULL != iter) {
510 g_proc_list = g_list_remove_link(g_proc_list, iter);
511 iter = g_list_first(g_proc_list);
515 dp = opendir("/proc");
517 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to open proc");
520 ret = readdir_r(dp, &entry, &dirp);
522 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to readdir");
527 tmp = atoi(dirp->d_name);
528 if (0 >= tmp) continue;
529 g_proc_list = g_list_append(g_proc_list, GINT_TO_POINTER(tmp));
531 } while (NULL != dirp);
537 Eina_Bool sttd_cleanup_client(void *data)
539 int* client_list = NULL;
540 int client_count = 0;
545 if (0 != sttd_client_get_list(&client_list, &client_count)) {
546 if (NULL != client_list)
552 if (NULL != client_list) {
553 SLOG(LOG_DEBUG, TAG_STTD, "===== Clean up client ");
557 for (i = 0; i < client_count; i++) {
558 int pid = sttd_client_get_pid(client_list[i]);
560 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Invalid pid");
566 for (j = 0; j < g_list_length(g_proc_list); j++) {
567 iter = g_list_nth(g_proc_list, j);
569 if (pid == GPOINTER_TO_INT(iter->data)) {
570 SLOG(LOG_DEBUG, TAG_STTD, "uid (%d) is running", client_list[i]);
577 if (false == exist) {
578 SLOG(LOG_ERROR, TAG_STTD, "uid (%d) should be removed", client_list[i]);
579 sttd_server_finalize(client_list[i]);
582 result = sttdc_send_hello(client_list[i]);
585 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", client_list[i]);
586 sttd_server_finalize(client_list[i]);
587 } else if (-1 == result) {
588 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Hello result has error");
593 SLOG(LOG_DEBUG, TAG_STTD, "=====");
594 SLOG(LOG_DEBUG, TAG_STTD, " ");
603 * STT Server Functions for Client
606 int sttd_server_initialize(int pid, int uid, bool* silence)
608 if (false == sttd_engine_agent_is_default_engine()) {
609 /* Update installed engine */
610 sttd_engine_agent_initialize_engine_list();
612 if (false == sttd_engine_agent_is_default_engine()) {
613 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] No stt-engine");
614 return STTD_ERROR_ENGINE_NOT_FOUND;
618 /* check if uid is valid */
620 if (0 == sttd_client_get_state(uid, &state)) {
621 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid has already been registered");
622 return STTD_ERROR_NONE;
626 if (0 != sttd_engine_agent_load_current_engine(uid, NULL)) {
627 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to load default engine");
628 return STTD_ERROR_OPERATION_FAILED;
631 if (0 != sttd_engine_agent_get_option_supported(uid, silence)) {
632 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine options supported");
633 return STTD_ERROR_OPERATION_FAILED;
636 /* Add client information to client manager */
637 if (0 != sttd_client_add(pid, uid)) {
638 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add client info");
639 return STTD_ERROR_OPERATION_FAILED;
642 return STTD_ERROR_NONE;
645 static Eina_Bool __quit_ecore_loop(void *data)
647 ecore_main_loop_quit();
651 int sttd_server_finalize(int uid)
653 /* check if uid is valid */
655 if (0 != sttd_client_get_state(uid, &state)) {
656 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
657 return STTD_ERROR_INVALID_PARAMETER;
660 /* release recorder */
661 if (APP_STATE_RECORDING == state || APP_STATE_PROCESSING == state) {
662 if (APP_STATE_RECORDING == state) {
663 if (NULL != g_recording_timer) {
664 ecore_timer_del(g_recording_timer);
665 g_recording_timer = NULL;
669 if (APP_STATE_PROCESSING == state) {
670 if (NULL != g_processing_timer) {
671 ecore_timer_del(g_processing_timer);
672 g_processing_timer = NULL;
676 if (0 != sttd_engine_agent_recognize_cancel(uid)) {
677 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognition");
680 stt_client_unset_current_recognition();
683 if (0 != sttd_engine_agent_unload_current_engine(uid)) {
684 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unload engine");
687 /* Remove client information */
688 if (0 != sttd_client_delete(uid)) {
689 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to delete client");
692 /* unload engine, if ref count of client is 0 */
693 if (0 == sttd_client_get_ref_count()) {
694 sttd_dbus_close_connection();
695 ecore_timer_add(0, __quit_ecore_loop, NULL);
698 return STTD_ERROR_NONE;
701 int sttd_server_get_supported_engines(int uid, GSList** engine_list)
703 /* Check if uid is valid */
705 if (0 != sttd_client_get_state(uid, &state)) {
706 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
707 return STTD_ERROR_INVALID_PARAMETER;
710 /* Check state of uid */
711 if (APP_STATE_READY != state) {
712 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
713 return STTD_ERROR_INVALID_STATE;
717 ret = sttd_engine_agent_get_engine_list(engine_list);
719 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine list");
720 return STTD_ERROR_OPERATION_FAILED;
723 return STTD_ERROR_NONE;
726 int sttd_server_set_current_engine(int uid, const char* engine_id, bool* silence)
728 /* Check if uid is valid */
730 if (0 != sttd_client_get_state(uid, &state)) {
731 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
732 return STTD_ERROR_INVALID_PARAMETER;
735 /* Check state of uid */
736 if (APP_STATE_READY != state) {
737 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
738 return STTD_ERROR_INVALID_STATE;
742 ret = sttd_engine_agent_load_current_engine(uid, engine_id);
744 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : %d", ret);
745 return STTD_ERROR_OPERATION_FAILED;
748 ret = sttd_engine_agent_get_option_supported(uid, silence);
750 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine options : %d", ret);
751 return STTD_ERROR_OPERATION_FAILED;
754 return STTD_ERROR_NONE;
757 int sttd_server_get_current_engine(int uid, char** engine_id)
759 /* Check if uid is valid */
761 if (0 != sttd_client_get_state(uid, &state)) {
762 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
763 return STTD_ERROR_INVALID_PARAMETER;
766 /* Check state of uid */
767 if (APP_STATE_READY != state) {
768 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
769 return STTD_ERROR_INVALID_STATE;
773 ret = sttd_engine_agent_get_current_engine(uid, engine_id);
775 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine : %d", ret);
776 return STTD_ERROR_OPERATION_FAILED;
779 return STTD_ERROR_NONE;
782 int sttd_server_check_app_agreed(int uid, const char* appid, bool* available)
784 /* Check if uid is valid */
786 if (0 != sttd_client_get_state(uid, &state)) {
787 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
788 return STTD_ERROR_INVALID_PARAMETER;
791 /* Check state of uid */
792 if (APP_STATE_READY != state) {
793 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
794 return STTD_ERROR_INVALID_STATE;
797 /* Ask engine available */
800 ret = sttd_engine_agent_check_app_agreed(uid, appid, &temp);
802 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
803 return STTD_ERROR_OPERATION_FAILED;
807 stt_client_set_app_agreed(uid);
808 SLOG(LOG_DEBUG, TAG_STTD, "[Server] App(%s) confirmed that engine is available", appid);
813 return STTD_ERROR_NONE;
817 int sttd_server_get_supported_languages(int uid, GSList** lang_list)
819 /* check if uid is valid */
821 if (0 != sttd_client_get_state(uid, &state)) {
822 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
823 return STTD_ERROR_INVALID_PARAMETER;
826 /* get language list from engine */
827 int ret = sttd_engine_agent_supported_langs(uid, lang_list);
829 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get supported languages");
830 return STTD_ERROR_OPERATION_FAILED;
833 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] sttd_server_get_supported_languages");
835 return STTD_ERROR_NONE;
838 int sttd_server_get_current_langauage(int uid, char** current_lang)
840 /* check if uid is valid */
842 if (0 != sttd_client_get_state(uid, &state)) {
843 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
844 return STTD_ERROR_INVALID_PARAMETER;
847 if (NULL == current_lang) {
848 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
849 return STTD_ERROR_INVALID_PARAMETER;
852 /*get current language from engine */
853 int ret = sttd_engine_agent_get_default_lang(uid, current_lang);
855 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get default language :result(%d)", ret);
856 return STTD_ERROR_OPERATION_FAILED;
859 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Get default language");
861 return STTD_ERROR_NONE;
864 int sttd_server_is_recognition_type_supported(int uid, const char* type, int* support)
866 /* check if uid is valid */
868 if (0 != sttd_client_get_state(uid, &state)) {
869 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
870 return STTD_ERROR_INVALID_PARAMETER;
873 if (NULL == type || NULL == support) {
874 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
875 return STTD_ERROR_INVALID_PARAMETER;
879 int ret = sttd_engine_agent_is_recognition_type_supported(uid, type, &temp);
881 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get recognition type supported : result(%d)", ret);
882 return STTD_ERROR_OPERATION_FAILED;
885 *support = (int)temp;
887 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] recognition type supporting is %s", *support ? "true" : "false");
889 return STTD_ERROR_NONE;
892 int sttd_server_set_start_sound(int uid, const char* file)
894 /* check if uid is valid */
896 if (0 != sttd_client_get_state(uid, &state)) {
897 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
898 return STTD_ERROR_INVALID_PARAMETER;
901 int ret = sttd_client_set_start_sound(uid, file);
903 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
904 return STTD_ERROR_OPERATION_FAILED;
910 int sttd_server_set_stop_sound(int uid, const char* file)
912 /* check if uid is valid */
914 if (0 != sttd_client_get_state(uid, &state)) {
915 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
916 return STTD_ERROR_INVALID_PARAMETER;
919 int ret = sttd_client_set_stop_sound(uid, file);
921 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
922 return STTD_ERROR_OPERATION_FAILED;
929 Eina_Bool __check_recording_state(void *data)
932 int uid = stt_client_get_current_recognition();
937 if (0 != sttdc_send_get_state(uid, (int*)&state)) {
938 /* client is removed */
939 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", uid);
940 sttd_server_finalize(uid);
944 if (APP_STATE_READY == state) {
946 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Ready'. The daemon should cancel recording", uid);
947 sttd_server_cancel(uid);
948 } else if (APP_STATE_PROCESSING == state) {
949 /* Cancel stt and send change state */
950 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Processing'. The daemon should cancel recording", uid);
951 sttd_server_cancel(uid);
952 sttdc_send_set_state(uid, (int)APP_STATE_READY);
955 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The states of daemon and client are identical");
963 Eina_Bool __stop_by_recording_timeout(void *data)
965 SLOG(LOG_DEBUG, TAG_STTD, "===== Stop by timeout");
967 g_recording_timer = NULL;
970 uid = stt_client_get_current_recognition();
972 /* cancel engine recognition */
973 int ret = sttd_server_stop(uid);
975 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop : result(%d)", ret);
979 SLOG(LOG_DEBUG, TAG_STTD, "=====");
980 SLOG(LOG_DEBUG, TAG_STTD, " ");
985 void __sttd_server_recorder_start(void* data)
987 intptr_t puid = (intptr_t)data;
989 int current_uid = stt_client_get_current_recognition();
991 if (uid != current_uid) {
992 stt_client_unset_current_recognition();
996 int ret = sttd_engine_agent_recognize_start_recorder(uid);
998 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1002 /* Notify uid state change */
1003 sttdc_send_set_state(uid, APP_STATE_RECORDING);
1005 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
1008 void __sttd_start_sound_completed_cb(int id, void *user_data)
1010 SLOG(LOG_DEBUG, TAG_STTD, "===== Start sound completed");
1012 /* After wav play callback, recorder start */
1013 ecore_main_loop_thread_safe_call_async(__sttd_server_recorder_start, user_data);
1015 SLOG(LOG_DEBUG, TAG_STTD, "=====");
1016 SLOG(LOG_DEBUG, TAG_STTD, " ");
1020 int sttd_server_start(int uid, const char* lang, const char* recognition_type, int silence, const char* appid)
1022 if (NULL == lang || NULL == recognition_type) {
1023 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
1024 return STTD_ERROR_INVALID_PARAMETER;
1027 /* check if uid is valid */
1029 if (0 != sttd_client_get_state(uid, &state)) {
1030 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1031 return STTD_ERROR_INVALID_PARAMETER;
1034 /* check uid state */
1035 if (APP_STATE_READY != state) {
1036 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] sttd_server_start : current state is not ready");
1037 return STTD_ERROR_INVALID_STATE;
1041 if (false == stt_client_get_app_agreed(uid)) {
1043 ret = sttd_engine_agent_check_app_agreed(uid, appid, &temp);
1045 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
1046 return STTD_ERROR_OPERATION_FAILED;
1049 if (false == temp) {
1050 SLOG(LOG_ERROR, TAG_STTD, "[Server] App(%s) NOT confirmed that engine is available", appid);
1051 return STTD_ERROR_PERMISSION_DENIED;
1054 stt_client_set_app_agreed(uid);
1057 /* check if engine use network */
1058 if (true == sttd_engine_agent_need_network(uid)) {
1059 if (false == stt_network_is_connected()) {
1060 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Disconnect network. Current engine needs to network connection.");
1061 return STTD_ERROR_OUT_OF_NETWORK;
1066 if (0 != sttd_client_get_start_sound(uid, &sound)) {
1067 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
1068 return STTD_ERROR_OPERATION_FAILED;
1071 if (0 != stt_client_set_current_recognition(uid)) {
1072 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT is busy because of recording or processing");
1073 if (NULL != sound) free(sound);
1074 return STTD_ERROR_RECORDER_BUSY;
1077 /* engine start recognition */
1078 SLOG(LOG_DEBUG, TAG_STTD, "[Server] start : uid(%d), lang(%s), recog_type(%s)",
1079 uid, lang, recognition_type);
1081 SLOG(LOG_DEBUG, TAG_STTD, "[Server] start sound : %s", sound);
1083 /* 1. Set audio session */
1084 ret = sttd_recorder_set_audio_session();
1086 stt_client_unset_current_recognition();
1087 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set session : %d", ret);
1088 if (NULL != sound) free(sound);
1092 bool is_sound_done = false;
1094 /* 2. Request wav play */
1095 if (NULL != sound) {
1097 intptr_t puid = (intptr_t)uid;
1098 ret = wav_player_start(sound, SOUND_TYPE_MEDIA, __sttd_start_sound_completed_cb, (void*)puid, &id);
1099 if (WAV_PLAYER_ERROR_NONE != ret) {
1100 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
1101 is_sound_done = true;
1106 is_sound_done = true;
1109 /* 3. Create recorder & engine initialize */
1110 ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, NULL);
1112 stt_client_unset_current_recognition();
1113 sttd_recorder_unset_audio_session();
1114 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1118 if (0 != strcmp(STTP_RECOGNITION_TYPE_FREE_PARTIAL, recognition_type)) {
1119 g_recording_timer = ecore_timer_add(g_recording_timeout, __stop_by_recording_timeout, NULL);
1122 /* change uid state */
1123 sttd_client_set_state(uid, APP_STATE_RECORDING);
1125 g_recording_log_count = 0;
1127 if (true == is_sound_done) {
1128 SLOG(LOG_DEBUG, TAG_STTD, "[Server] No sound play");
1130 ret = sttd_engine_agent_recognize_start_recorder(uid);
1132 stt_client_unset_current_recognition();
1133 sttd_recorder_unset_audio_session();
1135 sttd_engine_agent_recognize_cancel(uid);
1136 ecore_timer_del(g_recording_timer);
1137 sttd_client_set_state(uid, APP_STATE_READY);
1139 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
1140 return STTD_ERROR_OPERATION_FAILED;
1143 /* Notify uid state change */
1144 sttdc_send_set_state(uid, APP_STATE_RECORDING);
1146 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
1147 return STTD_RESULT_STATE_DONE;
1150 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Wait sound finish");
1152 return STTD_RESULT_STATE_NOT_DONE;
1155 Eina_Bool __time_out_for_processing(void *data)
1157 g_processing_timer = NULL;
1160 int uid = stt_client_get_current_recognition();
1161 if (0 == uid) return EINA_FALSE;
1164 int ret = sttd_engine_agent_recognize_cancel(uid);
1166 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1169 if (0 != sttdc_send_result(uid, STTP_RESULT_EVENT_FINAL_RESULT, NULL, 0, "Time out not to receive recognition result.")) {
1170 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
1172 /* send error msg */
1173 int reason = (int)STTD_ERROR_TIMED_OUT;
1174 if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
1175 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
1179 /* Change uid state */
1180 sttd_client_set_state(uid, APP_STATE_READY);
1182 stt_client_unset_current_recognition();
1187 void __sttd_server_engine_stop(void* data)
1189 intptr_t puid = (intptr_t)data;
1190 int uid = (int)puid;
1191 /* change uid state */
1192 sttd_client_set_state(uid, APP_STATE_PROCESSING);
1194 /* Notify uid state change */
1195 sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1197 /* Unset audio session */
1198 int ret = sttd_recorder_unset_audio_session();
1200 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1205 ret = sttd_engine_agent_recognize_stop_engine(uid);
1207 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1211 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1214 void __sttd_stop_sound_completed_cb(int id, void *user_data)
1216 SLOG(LOG_DEBUG, TAG_STTD, "===== Stop sound completed");
1218 /* After wav play callback, engine stop */
1219 ecore_main_loop_thread_safe_call_async(__sttd_server_engine_stop, user_data);
1221 SLOG(LOG_DEBUG, TAG_STTD, "=====");
1222 SLOG(LOG_DEBUG, TAG_STTD, " ");
1226 int sttd_server_stop(int uid)
1228 /* check if uid is valid */
1230 if (0 != sttd_client_get_state(uid, &state)) {
1231 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1232 return STTD_ERROR_INVALID_PARAMETER;
1235 /* check uid state */
1236 if (APP_STATE_RECORDING != state) {
1237 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
1238 return STTD_ERROR_INVALID_STATE;
1241 if (NULL != g_recording_timer) {
1242 ecore_timer_del(g_recording_timer);
1243 g_recording_timer = NULL;
1247 if (0 != sttd_client_get_stop_sound(uid, &sound)) {
1248 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
1249 return STTD_ERROR_OPERATION_FAILED;
1252 SLOG(LOG_DEBUG, TAG_STTD, "[Server] stop sound path : %s", sound);
1255 /* 1. Stop recorder */
1256 ret = sttd_engine_agent_recognize_stop_recorder(uid);
1258 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop recorder : result(%d)", ret);
1259 if (0 != sttd_engine_agent_recognize_cancel(uid)) {
1260 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognize");
1262 if (NULL != sound) free(sound);
1263 return STTD_ERROR_OPERATION_FAILED;
1266 /* 2. Request wav play */
1267 if (NULL != sound) {
1269 intptr_t puid = (intptr_t)uid;
1270 ret = wav_player_start(sound, SOUND_TYPE_MEDIA, __sttd_stop_sound_completed_cb, (void*)puid, &id);
1271 if (WAV_PLAYER_ERROR_NONE != ret) {
1272 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
1274 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Play wav : %s", sound);
1279 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1281 return STTD_RESULT_STATE_NOT_DONE;
1283 SLOG(LOG_DEBUG, TAG_STTD, "[Server] No sound play");
1285 /* Unset audio session */
1286 ret = sttd_recorder_unset_audio_session();
1288 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1289 return STTD_ERROR_OPERATION_FAILED;
1293 ret = sttd_engine_agent_recognize_stop_engine(uid);
1295 stt_client_unset_current_recognition();
1296 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1297 return STTD_ERROR_OPERATION_FAILED;
1300 /* change uid state */
1301 sttd_client_set_state(uid, APP_STATE_PROCESSING);
1303 /* Notify uid state change */
1304 sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1306 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1308 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1310 return STTD_RESULT_STATE_DONE;
1313 return STTD_ERROR_NONE;
1316 int sttd_server_cancel(int uid)
1318 /* check if uid is valid */
1320 if (0 != sttd_client_get_state(uid, &state)) {
1321 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1322 return STTD_ERROR_INVALID_PARAMETER;
1325 /* check uid state */
1326 if (APP_STATE_READY == state) {
1327 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is ready");
1328 return STTD_ERROR_NONE;
1331 stt_client_unset_current_recognition();
1333 if (NULL != g_recording_timer) {
1334 ecore_timer_del(g_recording_timer);
1335 g_recording_timer = NULL;
1338 if (NULL != g_processing_timer) {
1339 ecore_timer_del(g_processing_timer);
1340 g_processing_timer = NULL;
1343 if (APP_STATE_RECORDING == state) {
1344 /* Unset audio session */
1345 int ret = sttd_recorder_unset_audio_session();
1347 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1348 return STTD_ERROR_OPERATION_FAILED;
1352 /* change uid state */
1353 sttd_client_set_state(uid, APP_STATE_READY);
1355 /* cancel engine recognition */
1356 int ret = sttd_engine_agent_recognize_cancel(uid);
1358 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1359 return STTD_ERROR_OPERATION_FAILED;
1362 /* Notify uid state change */
1363 sttdc_send_set_state(uid, APP_STATE_READY);
1365 return STTD_ERROR_NONE;