2 * Copyright (c) 2011-2016 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 stte_result_mutex = PTHREAD_MUTEX_INITIALIZER;
28 static pthread_mutex_t stte_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();
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(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 int __server_recognition_result_callback(stte_result_event_e event, const char* type,
183 const char** data, int data_count, const char* msg, void *user_data)
186 pthread_mutex_lock(&stte_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(&stte_result_mutex);
199 return STTD_ERROR_OPERATION_FAILED;
202 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid (%d), event(%d)", uid, event);
204 /* send result to client */
205 if (STTE_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 sttd_client_set_state(uid, APP_STATE_READY);
221 stt_client_unset_current_recognition();
223 if (NULL == data || 0 == data_count) {
224 if (0 != sttdc_send_result(uid, event, NULL, 0, msg)) {
225 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
226 int reason = (int)STTD_ERROR_OPERATION_FAILED;
228 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
229 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
233 if (0 != sttdc_send_result(uid, event, data, data_count, msg)) {
234 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
235 int reason = (int)STTD_ERROR_OPERATION_FAILED;
237 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
238 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
243 /* change state of uid */
244 // sttd_client_set_state(uid, APP_STATE_READY);
245 // stt_client_unset_current_recognition();
247 } else if (STTE_RESULT_EVENT_PARTIAL_RESULT == event) {
248 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The partial result from engine is event[%d] data_count[%d]", event, data_count);
250 sttd_config_time_save();
251 sttd_config_time_reset();
253 if (0 != sttdc_send_result(uid, event, data, data_count, msg)) {
254 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
255 int reason = (int)STTD_ERROR_OPERATION_FAILED;
257 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
258 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
262 } else if (STTE_RESULT_EVENT_ERROR == event) {
263 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The event of recognition result is ERROR");
265 /* Delete timer for processing time out */
266 if (NULL != g_processing_timer) {
267 ecore_timer_del(g_processing_timer);
268 g_processing_timer = NULL;
270 sttd_config_time_reset();
272 sttd_client_set_state(uid, APP_STATE_READY);
273 stt_client_unset_current_recognition();
275 if (0 != sttdc_send_result(uid, event, NULL, 0, msg)) {
276 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
279 int reason = (int)STTD_ERROR_INVALID_STATE;
280 if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
281 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
285 /* change state of uid */
286 // sttd_client_set_state(uid, APP_STATE_READY);
287 // stt_client_unset_current_recognition();
292 SLOG(LOG_DEBUG, TAG_STTD, "=====");
293 SLOG(LOG_DEBUG, TAG_STTD, " ");
294 pthread_mutex_unlock(&stte_result_mutex);
296 return STTD_ERROR_NONE;
299 bool __server_result_time_callback(int index, stte_result_time_event_e event, const char* text, long start_time, long end_time, void* user_data)
301 pthread_mutex_lock(&stte_result_time_mutex);
303 SLOG(LOG_DEBUG, TAG_STTD, "[Server] index(%d) event(%d) text(%s) start(%ld) end(%ld)",
304 index, event, text, start_time, end_time);
307 ret = sttd_config_time_add(index, (int)event, text, start_time, end_time);
309 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add time info");
310 pthread_mutex_unlock(&stte_result_time_mutex);
314 pthread_mutex_unlock(&stte_result_time_mutex);
319 int __server_speech_status_callback(stte_speech_status_e status, void *user_param)
321 SLOG(LOG_DEBUG, TAG_STTD, "===== Speech status detected Callback");
323 int uid = stt_client_get_current_recognition();
326 if (0 != sttd_client_get_state(uid, &state)) {
327 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is not valid ");
328 return STTD_ERROR_OPERATION_FAILED;
331 if (APP_STATE_RECORDING != state) {
332 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
333 return STTD_ERROR_INVALID_STATE;
336 if (STTE_SPEECH_STATUS_BEGINNING_POINT_DETECTED == status) {
337 SLOG(LOG_DEBUG, TAG_STTD, "Begin Speech detected");
338 sttdc_send_speech_status(uid, status);
339 } else if (STTE_SPEECH_STATUS_END_POINT_DETECTED == status) {
340 SLOG(LOG_DEBUG, TAG_STTD, "End Speech detected");
341 ecore_main_loop_thread_safe_call_async(__stop_by_silence, NULL);
344 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current recogntion uid is not valid ");
347 SLOG(LOG_DEBUG, TAG_STTD, "=====");
348 SLOG(LOG_DEBUG, TAG_STTD, " ");
350 return STTD_ERROR_NONE;
353 int __server_error_callback(stte_error_e error, const char* msg)
355 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Error Callback is called");
356 ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
358 return STTD_ERROR_NONE;
361 void __sttd_server_engine_changed_cb(const char* engine_id, const char* language, bool support_silence, bool need_credential, void* user_data)
363 if (NULL == engine_id) {
364 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Engine id is NULL");
367 SLOG(LOG_DEBUG, TAG_STTD, "[Server] New default engine : %s", engine_id);
370 /* need to change state of app to ready */
372 uid = stt_client_get_current_recognition();
375 SLOG(LOG_ERROR, TAG_STTD, "[Server] Set ready state of uid(%d)", uid);
377 sttd_server_cancel(uid);
378 sttdc_send_set_state(uid, (int)APP_STATE_READY);
380 stt_client_unset_current_recognition();
384 int ret = sttd_engine_agent_set_default_engine(engine_id);
386 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : result(%d)", ret);
388 if (NULL != language) {
389 ret = sttd_engine_agent_set_default_language(language);
391 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%d)", ret);
394 ret = sttd_engine_agent_set_silence_detection(support_silence);
396 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret);
401 void __sttd_server_language_changed_cb(const char* language, void* user_data)
403 if (NULL == language) {
404 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] language is NULL");
407 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Get language changed : %s", language);
410 int ret = sttd_engine_agent_set_default_language(language);
412 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%d)", ret);
417 void __sttd_server_silence_changed_cb(bool value, void* user_data)
419 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Get silence detection changed : %s", value ? "on" : "off");
422 ret = sttd_engine_agent_set_silence_detection(value);
424 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret);
433 static void __sig_handler(int signo)
435 /* restore signal handler */
436 signal(signo, SIG_DFL);
438 /* Send error signal to clients */
439 int* client_list = NULL;
440 int client_count = 0;
442 if (0 != sttd_client_get_list(&client_list, &client_count)) {
443 if (NULL != client_list) {
449 if (NULL != client_list) {
450 for (i = 0; i < client_count; i++) {
451 sttdc_send_error_signal(client_list[i], STTD_ERROR_SERVICE_RESET, "Service Reset");
458 /* invoke signal again */
462 static void __register_sig_handler()
464 signal(SIGSEGV, __sig_handler);
465 signal(SIGABRT, __sig_handler);
466 signal(SIGTERM, __sig_handler);
467 signal(SIGINT, __sig_handler);
468 signal(SIGQUIT, __sig_handler);
471 int sttd_initialize(stte_request_callback_s *callback)
475 __register_sig_handler();
477 if (0 != pthread_mutex_init(&stte_result_mutex, NULL)) {
478 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize stte result mutex.");
481 if (0 != pthread_mutex_init(&stte_result_time_mutex, NULL)) {
482 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize stte stte_result_time_mutex.");
485 if (sttd_config_initialize(__sttd_server_engine_changed_cb, __sttd_server_language_changed_cb,
486 __sttd_server_silence_changed_cb, NULL)) {
487 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize config.");
490 ret = sttd_recorder_initialize(__server_audio_recorder_callback, __server_audio_interrupt_callback);
492 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize recorder : result(%d)", ret);
496 /* Engine Agent initialize */
497 ret = sttd_engine_agent_init(__server_recognition_result_callback, __server_result_time_callback,
498 __server_speech_status_callback, __server_error_callback);
500 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine agent initialize : result(%d)", ret);
505 ret = sttd_engine_agent_load_current_engine(callback);
507 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to load default engine");
511 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] initialize");
518 if (0 != pthread_mutex_destroy(&stte_result_mutex)) {
519 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy stte result mutex.");
522 if (0 != pthread_mutex_destroy(&stte_result_time_mutex)) {
523 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy stte_result_time_mutex.");
527 if (0 < g_list_length(g_proc_list)) {
528 iter = g_list_first(g_proc_list);
529 while (NULL != iter) {
530 g_proc_list = g_list_remove_link(g_proc_list, iter);
531 iter = g_list_first(g_proc_list);
535 sttd_recorder_deinitialize();
537 sttd_config_finalize();
539 sttd_engine_agent_release();
541 return STTD_ERROR_NONE;
544 static void __read_proc()
547 struct dirent *dirp = NULL;
551 if (0 < g_list_length(g_proc_list)) {
552 iter = g_list_first(g_proc_list);
553 while (NULL != iter) {
554 g_proc_list = g_list_remove_link(g_proc_list, iter);
555 iter = g_list_first(g_proc_list);
559 dp = opendir("/proc");
561 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to open proc");
567 tmp = atoi(dirp->d_name);
568 if (0 >= tmp) continue;
569 g_proc_list = g_list_append(g_proc_list, GINT_TO_POINTER(tmp));
571 } while (NULL != dirp);
577 Eina_Bool sttd_cleanup_client(void *data)
579 int* client_list = NULL;
580 int client_count = 0;
585 if (0 != sttd_client_get_list(&client_list, &client_count)) {
586 if (NULL != client_list)
592 if (NULL != client_list) {
593 SLOG(LOG_DEBUG, TAG_STTD, "===== Clean up client ");
597 for (i = 0; i < client_count; i++) {
598 int pid = sttd_client_get_pid(client_list[i]);
600 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Invalid pid");
606 for (j = 0; j < g_list_length(g_proc_list); j++) {
607 iter = g_list_nth(g_proc_list, j);
609 if (pid == GPOINTER_TO_INT(iter->data)) {
610 SLOG(LOG_DEBUG, TAG_STTD, "uid (%d) is running", client_list[i]);
617 if (false == exist) {
618 SLOG(LOG_ERROR, TAG_STTD, "uid (%d) should be removed", client_list[i]);
619 sttd_server_finalize(client_list[i]);
622 result = sttdc_send_hello(client_list[i]);
625 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", client_list[i]);
626 sttd_server_finalize(client_list[i]);
627 } else if (-1 == result) {
628 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Hello result has error");
633 SLOG(LOG_DEBUG, TAG_STTD, "=====");
634 SLOG(LOG_DEBUG, TAG_STTD, " ");
643 * STT Server Functions for Client
646 int sttd_server_initialize(int pid, int uid, bool* silence, bool* credential)
648 int ret = STTD_ERROR_NONE;
650 /* check if uid is valid */
652 if (0 == sttd_client_get_state(uid, &state)) {
653 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid has already been registered");
654 return STTD_ERROR_NONE;
657 ret = sttd_engine_agent_get_option_supported(silence);
659 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine options supported");
663 ret = sttd_engine_agent_is_credential_needed(uid, credential);
665 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get credential necessity");
669 /* Add client information to client manager */
670 ret = sttd_client_add(pid, uid);
672 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add client info");
676 return STTD_ERROR_NONE;
679 static Eina_Bool __quit_ecore_loop(void *data)
681 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Quit");
683 stt_network_finalize();
685 ecore_main_loop_quit();
687 SLOG(LOG_DEBUG, TAG_STTD, "");
692 int sttd_server_finalize(int uid)
694 /* check if uid is valid */
696 if (0 != sttd_client_get_state(uid, &state)) {
697 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
698 return STTD_ERROR_INVALID_PARAMETER;
701 /* release recorder */
702 if (APP_STATE_RECORDING == state || APP_STATE_PROCESSING == state) {
703 if (APP_STATE_RECORDING == state) {
704 if (NULL != g_recording_timer) {
705 ecore_timer_del(g_recording_timer);
706 g_recording_timer = NULL;
710 if (APP_STATE_PROCESSING == state) {
711 if (NULL != g_processing_timer) {
712 ecore_timer_del(g_processing_timer);
713 g_processing_timer = NULL;
717 if (0 != sttd_engine_agent_recognize_cancel(uid)) {
718 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognition");
721 stt_client_unset_current_recognition();
724 /* Remove client information */
725 if (0 != sttd_client_delete(uid)) {
726 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to delete client");
729 /* unload engine, if ref count of client is 0 */
730 if (0 == sttd_client_get_ref_count()) {
731 // sttd_dbus_close_connection();
732 ecore_timer_add(0, __quit_ecore_loop, NULL);
735 return STTD_ERROR_NONE;
738 int sttd_server_get_supported_engines(int uid, GSList** engine_list)
740 /* Check if uid is valid */
742 if (0 != sttd_client_get_state(uid, &state)) {
743 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
744 return STTD_ERROR_INVALID_PARAMETER;
747 /* Check state of uid */
748 if (APP_STATE_READY != state) {
749 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
750 return STTD_ERROR_INVALID_STATE;
754 ret = sttd_engine_agent_get_engine_list(engine_list);
756 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine list");
760 return STTD_ERROR_NONE;
763 int sttd_server_set_current_engine(int uid, const char* engine_id, bool* silence, bool* credential)
765 /* Check if uid is valid */
767 if (0 != sttd_client_get_state(uid, &state)) {
768 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
769 return STTD_ERROR_INVALID_PARAMETER;
772 /* Check state of uid */
773 if (APP_STATE_READY != state) {
774 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
775 return STTD_ERROR_INVALID_STATE;
779 ret = sttd_engine_agent_load_current_engine(NULL);
781 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : %d", ret);
785 ret = sttd_engine_agent_get_option_supported(silence);
787 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine options : %d", ret);
791 if (0 != sttd_engine_agent_is_credential_needed(uid, credential)) {
792 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get credential necessity");
796 return STTD_ERROR_NONE;
799 int sttd_server_get_current_engine(int uid, char** engine_id)
801 /* Check if uid is valid */
803 if (0 != sttd_client_get_state(uid, &state)) {
804 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
805 return STTD_ERROR_INVALID_PARAMETER;
808 /* Check state of uid */
809 if (APP_STATE_READY != state) {
810 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
811 return STTD_ERROR_INVALID_STATE;
815 ret = sttd_engine_agent_get_current_engine(engine_id);
817 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine : %d", ret);
821 return STTD_ERROR_NONE;
824 int sttd_server_check_app_agreed(int uid, const char* appid, bool* available)
826 /* Check if uid is valid */
828 if (0 != sttd_client_get_state(uid, &state)) {
829 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
830 return STTD_ERROR_INVALID_PARAMETER;
833 /* Check state of uid */
834 if (APP_STATE_READY != state) {
835 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
836 return STTD_ERROR_INVALID_STATE;
839 /* Ask engine available */
842 ret = sttd_engine_agent_check_app_agreed(appid, &temp);
844 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
849 stt_client_set_app_agreed(uid);
850 SLOG(LOG_DEBUG, TAG_STTD, "[Server] App(%s) confirmed that engine is available", appid);
855 return STTD_ERROR_NONE;
859 int sttd_server_get_supported_languages(int uid, GSList** lang_list)
861 /* check if uid is valid */
863 if (0 != sttd_client_get_state(uid, &state)) {
864 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
865 return STTD_ERROR_INVALID_PARAMETER;
868 /* get language list from engine */
869 int ret = sttd_engine_agent_supported_langs(lang_list);
871 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get supported languages");
875 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] sttd_server_get_supported_languages");
877 return STTD_ERROR_NONE;
880 int sttd_server_get_current_langauage(int uid, char** current_lang)
882 /* check if uid is valid */
884 if (0 != sttd_client_get_state(uid, &state)) {
885 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
886 return STTD_ERROR_INVALID_PARAMETER;
889 if (NULL == current_lang) {
890 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
891 return STTD_ERROR_INVALID_PARAMETER;
894 /*get current language from engine */
895 int ret = sttd_engine_agent_get_default_lang(current_lang);
897 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get default language :result(%d)", ret);
901 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Get default language");
903 return STTD_ERROR_NONE;
906 int sttd_server_set_private_data(int uid, const char* key, const char* data)
908 /* check if uid is valid */
910 if (0 != sttd_client_get_state(uid, &state)) {
911 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
912 return STTD_ERROR_INVALID_PARAMETER;
915 if (NULL == key || NULL == data) {
916 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
917 return STTD_ERROR_INVALID_PARAMETER;
920 /* set private data to engine */
922 ret = sttd_engine_agent_set_private_data(key, data);
924 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set private data :result(%d)", ret);
928 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Set private data");
930 return STTD_ERROR_NONE;
933 int sttd_server_get_private_data(int uid, const char* key, char** data)
935 /* check if uid is valid */
937 if (0 != sttd_client_get_state(uid, &state)) {
938 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
939 return STTD_ERROR_INVALID_PARAMETER;
942 if (NULL == key || NULL == data) {
943 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
944 return STTD_ERROR_INVALID_PARAMETER;
947 /* get private data to engine */
949 ret = sttd_engine_agent_get_private_data(key, data);
951 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get private data :result(%d)", ret);
955 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Get private data, key(%s), data(%s)", key, *data);
957 return STTD_ERROR_NONE;
960 int sttd_server_is_recognition_type_supported(int uid, const char* type, int* support)
962 /* check if uid is valid */
964 if (0 != sttd_client_get_state(uid, &state)) {
965 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
966 return STTD_ERROR_INVALID_PARAMETER;
969 if (NULL == type || NULL == support) {
970 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
971 return STTD_ERROR_INVALID_PARAMETER;
975 int ret = sttd_engine_agent_is_recognition_type_supported(type, &temp);
977 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get recognition type supported : result(%d)", ret);
981 *support = (int)temp;
983 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] recognition type supporting is %s", *support ? "true" : "false");
985 return STTD_ERROR_NONE;
988 int sttd_server_set_start_sound(int uid, const char* file)
990 /* check if uid is valid */
992 if (0 != sttd_client_get_state(uid, &state)) {
993 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
994 return STTD_ERROR_INVALID_PARAMETER;
997 int ret = sttd_client_set_start_sound(uid, file);
999 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
1006 int sttd_server_set_stop_sound(int uid, const char* file)
1008 /* check if uid is valid */
1010 if (0 != sttd_client_get_state(uid, &state)) {
1011 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1012 return STTD_ERROR_INVALID_PARAMETER;
1015 int ret = sttd_client_set_stop_sound(uid, file);
1017 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
1025 Eina_Bool __check_recording_state(void *data)
1028 int uid = stt_client_get_current_recognition();
1033 if (0 != sttdc_send_get_state(uid, (int*)&state)) {
1034 /* client is removed */
1035 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", uid);
1036 sttd_server_finalize(uid);
1040 if (APP_STATE_READY == state) {
1042 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Ready'. The STT service should cancel recording", uid);
1043 sttd_server_cancel(uid);
1044 } else if (APP_STATE_PROCESSING == state) {
1045 /* Cancel stt and send change state */
1046 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Processing'. The STT service should cancel recording", uid);
1047 sttd_server_cancel(uid);
1048 sttdc_send_set_state(uid, (int)APP_STATE_READY);
1051 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The states of STT service and client are identical");
1059 Eina_Bool __stop_by_recording_timeout(void *data)
1061 SLOG(LOG_DEBUG, TAG_STTD, "===== Stop by timeout");
1063 g_recording_timer = NULL;
1066 uid = stt_client_get_current_recognition();
1068 /* cancel engine recognition */
1069 int ret = sttd_server_stop(uid);
1071 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop : result(%d)", ret);
1075 SLOG(LOG_DEBUG, TAG_STTD, "=====");
1076 SLOG(LOG_DEBUG, TAG_STTD, " ");
1081 void __sttd_server_recorder_start(void* data)
1083 intptr_t puid = (intptr_t)data;
1084 int uid = (int)puid;
1085 int current_uid = stt_client_get_current_recognition();
1087 if (uid != current_uid) {
1088 stt_client_unset_current_recognition();
1092 int ret = sttd_engine_agent_recognize_start_recorder(uid);
1094 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1098 /* Notify uid state change */
1099 sttdc_send_set_state(uid, APP_STATE_RECORDING);
1101 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
1104 void __sttd_start_sound_completed_cb(int id, void *user_data)
1106 SLOG(LOG_DEBUG, TAG_STTD, "===== Start sound completed");
1108 /* After wav play callback, recorder start */
1109 ecore_main_loop_thread_safe_call_async(__sttd_server_recorder_start, user_data);
1111 SLOG(LOG_DEBUG, TAG_STTD, "=====");
1112 SLOG(LOG_DEBUG, TAG_STTD, " ");
1116 int sttd_server_start(int uid, const char* lang, const char* recognition_type, int silence, const char* appid, const char* credential)
1118 if (NULL == lang || NULL == recognition_type) {
1119 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
1120 return STTD_ERROR_INVALID_PARAMETER;
1123 /* check if uid is valid */
1125 if (0 != sttd_client_get_state(uid, &state)) {
1126 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1127 return STTD_ERROR_INVALID_PARAMETER;
1130 /* check uid state */
1131 if (APP_STATE_READY != state) {
1132 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] sttd_server_start : current state is not ready");
1133 return STTD_ERROR_INVALID_STATE;
1137 if (false == stt_client_get_app_agreed(uid)) {
1139 ret = sttd_engine_agent_check_app_agreed(appid, &temp);
1141 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
1145 if (false == temp) {
1146 SLOG(LOG_ERROR, TAG_STTD, "[Server] App(%s) NOT confirmed that engine is available", appid);
1147 return STTD_ERROR_PERMISSION_DENIED;
1150 stt_client_set_app_agreed(uid);
1153 /* check if engine use network */
1154 if (true == sttd_engine_agent_need_network()) {
1155 if (false == stt_network_is_connected()) {
1156 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Disconnect network. Current engine needs to network connection.");
1157 return STTD_ERROR_OUT_OF_NETWORK;
1162 ret = sttd_client_get_start_sound(uid, &sound);
1164 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
1168 if (0 != stt_client_set_current_recognition(uid)) {
1169 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT is busy because of recording or processing");
1170 if (NULL != sound) free(sound);
1171 return STTD_ERROR_RECORDER_BUSY;
1174 /* engine start recognition */
1175 SLOG(LOG_DEBUG, TAG_STTD, "[Server] start : uid(%d), lang(%s), recog_type(%s)",
1176 uid, lang, recognition_type);
1178 SLOG(LOG_DEBUG, TAG_STTD, "[Server] start sound : %s", sound);
1180 /* 1. Set audio session */
1181 ret = sttd_recorder_set_audio_session();
1183 stt_client_unset_current_recognition();
1184 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set session : %d", ret);
1185 if (NULL != sound) free(sound);
1189 bool is_sound_done = false;
1191 /* 2. Request wav play */
1192 if (NULL != sound) {
1194 intptr_t puid = (intptr_t)uid;
1195 ret = wav_player_start(sound, SOUND_TYPE_MEDIA, __sttd_start_sound_completed_cb, (void*)puid, &id);
1196 if (WAV_PLAYER_ERROR_NONE != ret) {
1197 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
1198 is_sound_done = true;
1203 is_sound_done = true;
1206 /* 3. Create recorder & engine initialize */
1207 ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, appid, credential, NULL);
1209 stt_client_unset_current_recognition();
1210 sttd_recorder_unset_audio_session();
1211 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1215 if (0 != strcmp(STTE_RECOGNITION_TYPE_FREE_PARTIAL, recognition_type)) {
1216 g_recording_timer = ecore_timer_add(g_recording_timeout, __stop_by_recording_timeout, NULL);
1219 /* change uid state */
1220 sttd_client_set_state(uid, APP_STATE_RECORDING);
1222 g_recording_log_count = 0;
1224 if (true == is_sound_done) {
1225 SLOG(LOG_DEBUG, TAG_STTD, "[Server] No sound play");
1227 ret = sttd_engine_agent_recognize_start_recorder(uid);
1229 stt_client_unset_current_recognition();
1230 sttd_recorder_unset_audio_session();
1232 sttd_engine_agent_recognize_cancel();
1233 ecore_timer_del(g_recording_timer);
1234 sttd_client_set_state(uid, APP_STATE_READY);
1236 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
1240 /* Notify uid state change */
1241 sttdc_send_set_state(uid, APP_STATE_RECORDING);
1243 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
1244 return STTD_RESULT_STATE_DONE;
1247 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Wait sound finish");
1249 return STTD_RESULT_STATE_NOT_DONE;
1252 Eina_Bool __time_out_for_processing(void *data)
1254 g_processing_timer = NULL;
1257 int uid = stt_client_get_current_recognition();
1258 if (0 == uid) return EINA_FALSE;
1261 int ret = sttd_engine_agent_recognize_cancel();
1263 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1266 if (0 != sttdc_send_result(uid, STTE_RESULT_EVENT_FINAL_RESULT, NULL, 0, "Time out not to receive recognition result.")) {
1267 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
1269 /* send error msg */
1270 int reason = (int)STTD_ERROR_TIMED_OUT;
1271 if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
1272 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
1276 /* Change uid state */
1277 sttd_client_set_state(uid, APP_STATE_READY);
1279 stt_client_unset_current_recognition();
1284 void __sttd_server_engine_stop(void* data)
1286 intptr_t puid = (intptr_t)data;
1287 int uid = (int)puid;
1288 /* change uid state */
1289 sttd_client_set_state(uid, APP_STATE_PROCESSING);
1291 /* Notify uid state change */
1292 sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1294 /* Unset audio session */
1295 int ret = sttd_recorder_unset_audio_session();
1297 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1302 ret = sttd_engine_agent_recognize_stop_engine();
1304 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1308 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1311 void __sttd_stop_sound_completed_cb(int id, void *user_data)
1313 SLOG(LOG_DEBUG, TAG_STTD, "===== Stop sound completed");
1315 /* After wav play callback, engine stop */
1316 ecore_main_loop_thread_safe_call_async(__sttd_server_engine_stop, user_data);
1318 SLOG(LOG_DEBUG, TAG_STTD, "=====");
1319 SLOG(LOG_DEBUG, TAG_STTD, " ");
1323 int sttd_server_stop(int uid)
1325 /* check if uid is valid */
1327 if (0 != sttd_client_get_state(uid, &state)) {
1328 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1329 return STTD_ERROR_INVALID_PARAMETER;
1332 /* check uid state */
1333 if (APP_STATE_RECORDING != state) {
1334 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
1335 return STTD_ERROR_INVALID_STATE;
1338 if (NULL != g_recording_timer) {
1339 ecore_timer_del(g_recording_timer);
1340 g_recording_timer = NULL;
1344 if (0 != sttd_client_get_stop_sound(uid, &sound)) {
1345 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
1346 return STTD_ERROR_OPERATION_FAILED;
1349 SLOG(LOG_DEBUG, TAG_STTD, "[Server] stop sound path : %s", sound);
1352 /* 1. Stop recorder */
1353 ret = sttd_engine_agent_recognize_stop_recorder();
1355 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop recorder : result(%d)", ret);
1356 if (0 != sttd_engine_agent_recognize_cancel()) {
1357 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognize");
1359 if (NULL != sound) free(sound);
1363 /* 2. Request wav play */
1364 if (NULL != sound) {
1366 intptr_t puid = (intptr_t)uid;
1367 ret = wav_player_start(sound, SOUND_TYPE_MEDIA, __sttd_stop_sound_completed_cb, (void*)puid, &id);
1368 if (WAV_PLAYER_ERROR_NONE != ret) {
1369 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
1371 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Play wav : %s", sound);
1376 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1378 return STTD_RESULT_STATE_NOT_DONE;
1380 SLOG(LOG_DEBUG, TAG_STTD, "[Server] No sound play");
1382 /* Unset audio session */
1383 ret = sttd_recorder_unset_audio_session();
1385 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1390 ret = sttd_engine_agent_recognize_stop_engine();
1392 stt_client_unset_current_recognition();
1393 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1397 /* change uid state */
1398 sttd_client_set_state(uid, APP_STATE_PROCESSING);
1400 /* Notify uid state change */
1401 sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1403 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1405 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1407 return STTD_RESULT_STATE_DONE;
1410 return STTD_ERROR_NONE;
1413 int sttd_server_cancel(int uid)
1415 /* check if uid is valid */
1417 if (0 != sttd_client_get_state(uid, &state)) {
1418 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1419 return STTD_ERROR_INVALID_PARAMETER;
1422 /* check uid state */
1423 if (APP_STATE_READY == state) {
1424 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is ready");
1425 return STTD_ERROR_NONE;
1428 stt_client_unset_current_recognition();
1430 if (NULL != g_recording_timer) {
1431 ecore_timer_del(g_recording_timer);
1432 g_recording_timer = NULL;
1435 if (NULL != g_processing_timer) {
1436 ecore_timer_del(g_processing_timer);
1437 g_processing_timer = NULL;
1440 if (APP_STATE_RECORDING == state) {
1441 /* Unset audio session */
1442 int ret = sttd_recorder_unset_audio_session();
1444 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1449 /* change uid state */
1450 sttd_client_set_state(uid, APP_STATE_READY);
1452 /* cancel engine recognition */
1453 int ret = sttd_engine_agent_recognize_cancel();
1455 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1459 /* Notify uid state change */
1460 sttdc_send_set_state(uid, APP_STATE_READY);
1462 return STTD_ERROR_NONE;