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;
92 uid = stt_client_get_current_recognition();
94 app_state_e state = 0;
95 ret = sttd_client_get_state(uid, &state);
98 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
102 if (0 != uid && (APP_STATE_PROCESSING == state || APP_STATE_RECORDING == state)) {
103 /* cancel engine recognition */
104 ret = sttd_engine_agent_recognize_cancel();
106 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
109 /* change uid state */
110 sttd_client_set_state(uid, APP_STATE_READY);
111 stt_client_unset_current_recognition();
113 ret = sttdc_send_set_state(uid, (int)APP_STATE_READY);
115 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send state change : result(%d)", ret);
118 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid is NOT valid");
122 static void __cancel_by_error(void *data)
124 SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by error");
126 __cancel_recognition_internal();
128 SLOG(LOG_DEBUG, TAG_STTD, "=====");
129 SLOG(LOG_DEBUG, TAG_STTD, " ");
134 int __server_audio_recorder_callback(const void* data, const unsigned int length)
139 if (NULL == data || 0 == length) {
140 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Recording data is not valid");
141 ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
145 uid = stt_client_get_current_recognition();
147 ret = sttd_engine_agent_set_recording_data(data, length);
149 ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
152 g_recording_log_count++;
153 if (200 <= g_recording_log_count) {
154 SLOG(LOG_DEBUG, TAG_STTD, "=== Set recording data ===");
155 g_recording_log_count = 0;
158 if (NULL != g_recording_timer) {
159 ecore_timer_del(g_recording_timer);
160 g_recording_timer = NULL;
162 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current uid in recording is is not valid");
169 void __server_audio_interrupt_callback()
171 SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by sound interrupt");
173 __cancel_recognition_internal();
175 SLOG(LOG_DEBUG, TAG_STTD, "=====");
176 SLOG(LOG_DEBUG, TAG_STTD, " ");
179 void __cancel_by_no_record(void *data)
181 SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by no record");
183 __cancel_recognition_internal();
185 SLOG(LOG_DEBUG, TAG_STTD, "=====");
186 SLOG(LOG_DEBUG, TAG_STTD, " ");
191 int __server_recognition_result_callback(stte_result_event_e event, const char* type,
192 const char** data, int data_count, const char* msg, void *user_data)
195 pthread_mutex_lock(&stte_result_mutex);
197 SLOG(LOG_DEBUG, TAG_STTD, "===== RESULT event[%d] type[%s] data[%p] data_count[%d]", event, type, data, data_count);
200 int uid = stt_client_get_current_recognition();
203 if (0 == uid || 0 != sttd_client_get_state(uid, &state)) {
204 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
205 SLOG(LOG_DEBUG, TAG_STTD, "=====");
206 SLOG(LOG_DEBUG, TAG_STTD, " ");
207 pthread_mutex_unlock(&stte_result_mutex);
208 return STTD_ERROR_OPERATION_FAILED;
211 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid (%d), event(%d)", uid, event);
213 /* send result to client */
214 if (STTE_RESULT_EVENT_FINAL_RESULT == event) {
215 if (APP_STATE_PROCESSING != state) {
216 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is NOT 'Processing'.");
218 SLOG(LOG_DEBUG, TAG_STTD, "[Server] the size of result from engine is '%d'", data_count);
220 /* Delete timer for processing time out */
221 if (NULL != g_processing_timer) {
222 ecore_timer_del(g_processing_timer);
223 g_processing_timer = NULL;
226 sttd_config_time_save();
227 sttd_config_time_reset();
229 sttd_client_set_state(uid, APP_STATE_READY);
230 stt_client_unset_current_recognition();
232 if (NULL == data || 0 == data_count) {
233 if (0 != sttdc_send_result(uid, event, NULL, 0, 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");
242 if (0 != sttdc_send_result(uid, event, data, data_count, msg)) {
243 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
244 int reason = (int)STTD_ERROR_OPERATION_FAILED;
246 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
247 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
252 /* change state of uid */
253 // sttd_client_set_state(uid, APP_STATE_READY);
254 // stt_client_unset_current_recognition();
256 } else if (STTE_RESULT_EVENT_PARTIAL_RESULT == event) {
257 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The partial result from engine is event[%d] data_count[%d]", event, data_count);
259 sttd_config_time_save();
260 sttd_config_time_reset();
262 if (0 != sttdc_send_result(uid, event, data, data_count, msg)) {
263 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
264 int reason = (int)STTD_ERROR_OPERATION_FAILED;
266 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
267 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
271 } else if (STTE_RESULT_EVENT_ERROR == event) {
272 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The event of recognition result is ERROR");
274 /* Delete timer for processing time out */
275 if (NULL != g_processing_timer) {
276 ecore_timer_del(g_processing_timer);
277 g_processing_timer = NULL;
279 sttd_config_time_reset();
282 if (APP_STATE_RECORDING == state) {
283 ret = sttd_engine_agent_recognize_cancel();
285 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel: result(%d)", ret);
289 sttd_client_set_state(uid, APP_STATE_READY);
290 stt_client_unset_current_recognition();
292 if (0 != sttdc_send_result(uid, event, NULL, 0, msg)) {
293 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
296 int reason = (int)STTD_ERROR_INVALID_STATE;
297 if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
298 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
302 /* change state of uid */
303 // sttd_client_set_state(uid, APP_STATE_READY);
304 // stt_client_unset_current_recognition();
309 SLOG(LOG_DEBUG, TAG_STTD, "=====");
310 SLOG(LOG_DEBUG, TAG_STTD, " ");
311 pthread_mutex_unlock(&stte_result_mutex);
313 return STTD_ERROR_NONE;
316 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)
318 pthread_mutex_lock(&stte_result_time_mutex);
320 SLOG(LOG_DEBUG, TAG_STTD, "[Server] index(%d) event(%d) text(%s) start(%ld) end(%ld)",
321 index, event, text, start_time, end_time);
324 ret = sttd_config_time_add(index, (int)event, text, start_time, end_time);
326 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add time info");
327 pthread_mutex_unlock(&stte_result_time_mutex);
331 pthread_mutex_unlock(&stte_result_time_mutex);
336 int __server_speech_status_callback(stte_speech_status_e status, void *user_param)
338 SLOG(LOG_DEBUG, TAG_STTD, "===== Speech status detected Callback");
340 int uid = stt_client_get_current_recognition();
343 if (0 != sttd_client_get_state(uid, &state)) {
344 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is not valid ");
345 return STTD_ERROR_OPERATION_FAILED;
348 if (APP_STATE_RECORDING != state) {
349 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
350 return STTD_ERROR_INVALID_STATE;
353 if (STTE_SPEECH_STATUS_BEGINNING_POINT_DETECTED == status) {
354 SLOG(LOG_DEBUG, TAG_STTD, "Begin Speech detected");
355 sttdc_send_speech_status(uid, status);
356 } else if (STTE_SPEECH_STATUS_END_POINT_DETECTED == status) {
357 SLOG(LOG_DEBUG, TAG_STTD, "End Speech detected");
358 ecore_main_loop_thread_safe_call_async(__stop_by_silence, NULL);
361 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current recogntion uid is not valid ");
364 SLOG(LOG_DEBUG, TAG_STTD, "=====");
365 SLOG(LOG_DEBUG, TAG_STTD, " ");
367 return STTD_ERROR_NONE;
370 int __server_error_callback(stte_error_e error, const char* msg)
372 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Error Callback is called");
373 ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
375 return STTD_ERROR_NONE;
378 void __sttd_server_engine_changed_cb(const char* engine_id, const char* language, bool support_silence, bool need_credential, void* user_data)
380 if (NULL == engine_id) {
381 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Engine id is NULL");
384 SLOG(LOG_DEBUG, TAG_STTD, "[Server] New default engine : %s", engine_id);
387 /* need to change state of app to ready */
389 uid = stt_client_get_current_recognition();
392 SLOG(LOG_ERROR, TAG_STTD, "[Server] Set ready state of uid(%d)", uid);
394 sttd_server_cancel(uid);
395 sttdc_send_set_state(uid, (int)APP_STATE_READY);
397 stt_client_unset_current_recognition();
401 int ret = sttd_engine_agent_set_default_engine(engine_id);
403 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : result(%d)", ret);
405 if (NULL != language) {
406 ret = sttd_engine_agent_set_default_language(language);
408 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%d)", ret);
411 ret = sttd_engine_agent_set_silence_detection(support_silence);
413 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret);
418 void __sttd_server_language_changed_cb(const char* language, void* user_data)
420 if (NULL == language) {
421 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] language is NULL");
424 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Get language changed : %s", language);
427 int ret = sttd_engine_agent_set_default_language(language);
429 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%d)", ret);
434 void __sttd_server_silence_changed_cb(bool value, void* user_data)
436 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Get silence detection changed : %s", value ? "on" : "off");
439 ret = sttd_engine_agent_set_silence_detection(value);
441 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret);
449 int sttd_initialize(stte_request_callback_s *callback)
453 if (0 != pthread_mutex_init(&stte_result_mutex, NULL)) {
454 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize stte result mutex.");
457 if (0 != pthread_mutex_init(&stte_result_time_mutex, NULL)) {
458 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize stte stte_result_time_mutex.");
461 if (sttd_config_initialize(__sttd_server_engine_changed_cb, __sttd_server_language_changed_cb,
462 __sttd_server_silence_changed_cb, NULL)) {
463 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize config.");
466 ret = sttd_recorder_initialize(__server_audio_recorder_callback, __server_audio_interrupt_callback);
468 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize recorder : result(%d)", ret);
472 /* Engine Agent initialize */
473 ret = sttd_engine_agent_init(__server_recognition_result_callback, __server_result_time_callback,
474 __server_speech_status_callback, __server_error_callback);
476 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine agent initialize : result(%d)", ret);
481 ret = sttd_engine_agent_load_current_engine(callback);
483 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to load default engine");
487 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] initialize");
494 if (0 != pthread_mutex_destroy(&stte_result_mutex)) {
495 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy stte result mutex.");
498 if (0 != pthread_mutex_destroy(&stte_result_time_mutex)) {
499 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy stte_result_time_mutex.");
503 if (0 < g_list_length(g_proc_list)) {
504 iter = g_list_first(g_proc_list);
505 while (NULL != iter) {
506 g_proc_list = g_list_remove_link(g_proc_list, iter);
507 iter = g_list_first(g_proc_list);
511 sttd_recorder_deinitialize();
513 sttd_config_finalize();
515 sttd_engine_agent_release();
517 return STTD_ERROR_NONE;
520 static void __read_proc()
523 struct dirent *dirp = NULL;
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 dp = opendir("/proc");
537 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to open proc");
543 tmp = atoi(dirp->d_name);
544 if (0 >= tmp) continue;
545 g_proc_list = g_list_append(g_proc_list, GINT_TO_POINTER(tmp));
547 } while (NULL != dirp);
553 Eina_Bool sttd_cleanup_client(void *data)
555 int* client_list = NULL;
556 int client_count = 0;
561 if (0 != sttd_client_get_list(&client_list, &client_count)) {
562 if (NULL != client_list)
568 if (NULL != client_list) {
569 SLOG(LOG_DEBUG, TAG_STTD, "===== Clean up client ");
573 for (i = 0; i < client_count; i++) {
574 int pid = sttd_client_get_pid(client_list[i]);
576 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Invalid pid");
582 for (j = 0; j < g_list_length(g_proc_list); j++) {
583 iter = g_list_nth(g_proc_list, j);
585 if (pid == GPOINTER_TO_INT(iter->data)) {
586 SLOG(LOG_DEBUG, TAG_STTD, "uid (%d) is running", client_list[i]);
593 if (false == exist) {
594 SLOG(LOG_ERROR, TAG_STTD, "uid (%d) should be removed", client_list[i]);
595 sttd_server_finalize(client_list[i]);
598 result = sttdc_send_hello(client_list[i]);
601 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", client_list[i]);
602 sttd_server_finalize(client_list[i]);
603 } else if (-1 == result) {
604 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Hello result has error");
609 SLOG(LOG_DEBUG, TAG_STTD, "=====");
610 SLOG(LOG_DEBUG, TAG_STTD, " ");
619 * STT Server Functions for Client
622 int sttd_server_initialize(int pid, int uid, bool* silence, bool* credential)
624 int ret = STTD_ERROR_NONE;
626 /* check if uid is valid */
628 if (0 == sttd_client_get_state(uid, &state)) {
629 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid has already been registered");
630 return STTD_ERROR_NONE;
633 ret = sttd_engine_agent_get_option_supported(silence);
635 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine options supported");
639 ret = sttd_engine_agent_is_credential_needed(uid, credential);
641 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get credential necessity");
645 /* Add client information to client manager */
646 ret = sttd_client_add(pid, uid);
648 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add client info");
652 return STTD_ERROR_NONE;
655 static Eina_Bool __quit_ecore_loop(void *data)
657 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Quit");
659 stt_network_finalize();
661 ecore_main_loop_quit();
663 SLOG(LOG_DEBUG, TAG_STTD, "");
668 int sttd_server_finalize(int uid)
670 /* check if uid is valid */
672 if (0 != sttd_client_get_state(uid, &state)) {
673 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
674 return STTD_ERROR_INVALID_PARAMETER;
677 /* release recorder */
678 if (APP_STATE_RECORDING == state || APP_STATE_PROCESSING == state) {
679 if (APP_STATE_RECORDING == state) {
680 if (NULL != g_recording_timer) {
681 ecore_timer_del(g_recording_timer);
682 g_recording_timer = NULL;
686 if (APP_STATE_PROCESSING == state) {
687 if (NULL != g_processing_timer) {
688 ecore_timer_del(g_processing_timer);
689 g_processing_timer = NULL;
693 if (0 != sttd_engine_agent_recognize_cancel(uid)) {
694 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognition");
697 stt_client_unset_current_recognition();
700 /* Remove client information */
701 if (0 != sttd_client_delete(uid)) {
702 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to delete client");
705 /* unload engine, if ref count of client is 0 */
706 if (0 == sttd_client_get_ref_count()) {
707 // sttd_dbus_close_connection();
708 ecore_timer_add(0, __quit_ecore_loop, NULL);
711 return STTD_ERROR_NONE;
714 int sttd_server_get_supported_engines(int uid, GSList** engine_list)
716 /* Check if uid is valid */
718 if (0 != sttd_client_get_state(uid, &state)) {
719 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
720 return STTD_ERROR_INVALID_PARAMETER;
723 /* Check state of uid */
724 if (APP_STATE_READY != state) {
725 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
726 return STTD_ERROR_INVALID_STATE;
730 ret = sttd_engine_agent_get_engine_list(engine_list);
732 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine list");
736 return STTD_ERROR_NONE;
739 int sttd_server_set_current_engine(int uid, const char* engine_id, bool* silence, bool* credential)
741 /* Check if uid is valid */
743 if (0 != sttd_client_get_state(uid, &state)) {
744 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
745 return STTD_ERROR_INVALID_PARAMETER;
748 /* Check state of uid */
749 if (APP_STATE_READY != state) {
750 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
751 return STTD_ERROR_INVALID_STATE;
755 ret = sttd_engine_agent_load_current_engine(NULL);
757 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : %d", ret);
761 ret = sttd_engine_agent_get_option_supported(silence);
763 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine options : %d", ret);
767 if (0 != sttd_engine_agent_is_credential_needed(uid, credential)) {
768 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get credential necessity");
772 return STTD_ERROR_NONE;
775 int sttd_server_get_current_engine(int uid, char** engine_id)
777 /* Check if uid is valid */
779 if (0 != sttd_client_get_state(uid, &state)) {
780 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
781 return STTD_ERROR_INVALID_PARAMETER;
784 /* Check state of uid */
785 if (APP_STATE_READY != state) {
786 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
787 return STTD_ERROR_INVALID_STATE;
791 ret = sttd_engine_agent_get_current_engine(engine_id);
793 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine : %d", ret);
797 return STTD_ERROR_NONE;
800 int sttd_server_check_app_agreed(int uid, const char* appid, bool* available)
802 /* Check if uid is valid */
804 if (0 != sttd_client_get_state(uid, &state)) {
805 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
806 return STTD_ERROR_INVALID_PARAMETER;
809 /* Check state of uid */
810 if (APP_STATE_READY != state) {
811 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
812 return STTD_ERROR_INVALID_STATE;
815 /* Ask engine available */
818 ret = sttd_engine_agent_check_app_agreed(appid, &temp);
820 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
825 stt_client_set_app_agreed(uid);
826 SLOG(LOG_DEBUG, TAG_STTD, "[Server] App(%s) confirmed that engine is available", appid);
831 return STTD_ERROR_NONE;
835 int sttd_server_get_supported_languages(int uid, GSList** lang_list)
837 /* check if uid is valid */
839 if (0 != sttd_client_get_state(uid, &state)) {
840 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
841 return STTD_ERROR_INVALID_PARAMETER;
844 /* get language list from engine */
845 int ret = sttd_engine_agent_supported_langs(lang_list);
847 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get supported languages");
851 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] sttd_server_get_supported_languages");
853 return STTD_ERROR_NONE;
856 int sttd_server_get_current_langauage(int uid, char** current_lang)
858 /* check if uid is valid */
860 if (0 != sttd_client_get_state(uid, &state)) {
861 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
862 return STTD_ERROR_INVALID_PARAMETER;
865 if (NULL == current_lang) {
866 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
867 return STTD_ERROR_INVALID_PARAMETER;
870 /*get current language from engine */
871 int ret = sttd_engine_agent_get_default_lang(current_lang);
873 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get default language :result(%d)", ret);
877 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Get default language");
879 return STTD_ERROR_NONE;
882 int sttd_server_set_private_data(int uid, const char* key, const char* data)
884 /* check if uid is valid */
886 if (0 != sttd_client_get_state(uid, &state)) {
887 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
888 return STTD_ERROR_INVALID_PARAMETER;
891 if (NULL == key || NULL == data) {
892 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
893 return STTD_ERROR_INVALID_PARAMETER;
896 /* set private data to engine */
898 ret = sttd_engine_agent_set_private_data(key, data);
900 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set private data :result(%d)", ret);
904 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Set private data");
906 return STTD_ERROR_NONE;
909 int sttd_server_get_private_data(int uid, const char* key, char** data)
911 /* check if uid is valid */
913 if (0 != sttd_client_get_state(uid, &state)) {
914 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
915 return STTD_ERROR_INVALID_PARAMETER;
918 if (NULL == key || NULL == data) {
919 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
920 return STTD_ERROR_INVALID_PARAMETER;
923 /* get private data to engine */
925 ret = sttd_engine_agent_get_private_data(key, data);
927 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get private data :result(%d)", ret);
931 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Get private data, key(%s), data(%s)", key, *data);
933 return STTD_ERROR_NONE;
936 int sttd_server_is_recognition_type_supported(int uid, const char* type, int* support)
938 /* check if uid is valid */
940 if (0 != sttd_client_get_state(uid, &state)) {
941 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
942 return STTD_ERROR_INVALID_PARAMETER;
945 if (NULL == type || NULL == support) {
946 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
947 return STTD_ERROR_INVALID_PARAMETER;
951 int ret = sttd_engine_agent_is_recognition_type_supported(type, &temp);
953 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get recognition type supported : result(%d)", ret);
957 *support = (int)temp;
959 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] recognition type supporting is %s", *support ? "true" : "false");
961 return STTD_ERROR_NONE;
964 int sttd_server_set_start_sound(int uid, const char* file)
966 /* check if uid is valid */
968 if (0 != sttd_client_get_state(uid, &state)) {
969 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
970 return STTD_ERROR_INVALID_PARAMETER;
973 int ret = sttd_client_set_start_sound(uid, file);
975 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
982 int sttd_server_set_stop_sound(int uid, const char* file)
984 /* check if uid is valid */
986 if (0 != sttd_client_get_state(uid, &state)) {
987 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
988 return STTD_ERROR_INVALID_PARAMETER;
991 int ret = sttd_client_set_stop_sound(uid, file);
993 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
1001 Eina_Bool __check_recording_state(void *data)
1004 int uid = stt_client_get_current_recognition();
1009 if (0 != sttdc_send_get_state(uid, (int*)&state)) {
1010 /* client is removed */
1011 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", uid);
1012 sttd_server_finalize(uid);
1016 if (APP_STATE_READY == state) {
1018 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Ready'. The STT service should cancel recording", uid);
1019 sttd_server_cancel(uid);
1020 } else if (APP_STATE_PROCESSING == state) {
1021 /* Cancel stt and send change state */
1022 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Processing'. The STT service should cancel recording", uid);
1023 sttd_server_cancel(uid);
1024 sttdc_send_set_state(uid, (int)APP_STATE_READY);
1027 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The states of STT service and client are identical");
1035 Eina_Bool __stop_by_recording_timeout(void *data)
1037 SLOG(LOG_DEBUG, TAG_STTD, "===== Stop by timeout");
1039 g_recording_timer = NULL;
1042 uid = stt_client_get_current_recognition();
1044 /* cancel engine recognition */
1045 int ret = sttd_server_stop(uid);
1047 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop : result(%d)", ret);
1051 SLOG(LOG_DEBUG, TAG_STTD, "=====");
1052 SLOG(LOG_DEBUG, TAG_STTD, " ");
1057 void __sttd_server_recorder_start(void* data)
1059 intptr_t puid = (intptr_t)data;
1060 int uid = (int)puid;
1061 int current_uid = stt_client_get_current_recognition();
1063 if (uid != current_uid) {
1064 stt_client_unset_current_recognition();
1068 int ret = sttd_engine_agent_recognize_start_recorder(uid);
1070 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1074 /* Notify uid state change */
1075 sttdc_send_set_state(uid, APP_STATE_RECORDING);
1077 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
1080 void __sttd_start_sound_completed_cb(int id, void *user_data)
1082 SLOG(LOG_DEBUG, TAG_STTD, "===== Start sound completed");
1084 /* After wav play callback, recorder start */
1085 ecore_main_loop_thread_safe_call_async(__sttd_server_recorder_start, user_data);
1087 SLOG(LOG_DEBUG, TAG_STTD, "=====");
1088 SLOG(LOG_DEBUG, TAG_STTD, " ");
1092 int sttd_server_start(int uid, const char* lang, const char* recognition_type, int silence, const char* appid, const char* credential)
1094 if (NULL == lang || NULL == recognition_type) {
1095 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
1096 return STTD_ERROR_INVALID_PARAMETER;
1099 /* check if uid is valid */
1101 if (0 != sttd_client_get_state(uid, &state)) {
1102 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1103 return STTD_ERROR_INVALID_PARAMETER;
1106 /* check uid state */
1107 if (APP_STATE_READY != state) {
1108 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] sttd_server_start : current state is not ready");
1109 return STTD_ERROR_INVALID_STATE;
1113 if (false == stt_client_get_app_agreed(uid)) {
1115 ret = sttd_engine_agent_check_app_agreed(appid, &temp);
1117 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
1121 if (false == temp) {
1122 SLOG(LOG_ERROR, TAG_STTD, "[Server] App(%s) NOT confirmed that engine is available", appid);
1123 return STTD_ERROR_PERMISSION_DENIED;
1126 stt_client_set_app_agreed(uid);
1129 /* check if engine use network */
1130 if (true == sttd_engine_agent_need_network()) {
1131 if (false == stt_network_is_connected()) {
1132 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Disconnect network. Current engine needs to network connection.");
1133 return STTD_ERROR_OUT_OF_NETWORK;
1138 ret = sttd_client_get_start_sound(uid, &sound);
1140 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
1144 if (0 != stt_client_set_current_recognition(uid)) {
1145 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT is busy because of recording or processing");
1146 if (NULL != sound) free(sound);
1147 return STTD_ERROR_RECORDER_BUSY;
1150 /* engine start recognition */
1151 SLOG(LOG_DEBUG, TAG_STTD, "[Server] start : uid(%d), lang(%s), recog_type(%s)",
1152 uid, lang, recognition_type);
1154 SLOG(LOG_DEBUG, TAG_STTD, "[Server] start sound : %s", sound);
1156 /* 1. Set audio session */
1157 ret = sttd_recorder_set_audio_session();
1159 stt_client_unset_current_recognition();
1160 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set session : %d", ret);
1161 if (NULL != sound) free(sound);
1165 bool is_sound_done = false;
1167 /* 2. Request wav play */
1168 if (NULL != sound) {
1170 intptr_t puid = (intptr_t)uid;
1171 ret = wav_player_start(sound, SOUND_TYPE_MEDIA, __sttd_start_sound_completed_cb, (void*)puid, &id);
1172 if (WAV_PLAYER_ERROR_NONE != ret) {
1173 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
1174 is_sound_done = true;
1179 is_sound_done = true;
1182 /* 3. Create recorder & engine initialize */
1183 ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, appid, credential, NULL);
1185 stt_client_unset_current_recognition();
1186 sttd_recorder_unset_audio_session();
1187 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1191 if (0 != strcmp(STTE_RECOGNITION_TYPE_FREE_PARTIAL, recognition_type)) {
1192 g_recording_timer = ecore_timer_add(g_recording_timeout, __stop_by_recording_timeout, NULL);
1195 /* change uid state */
1196 sttd_client_set_state(uid, APP_STATE_RECORDING);
1198 g_recording_log_count = 0;
1200 if (true == is_sound_done) {
1201 SLOG(LOG_DEBUG, TAG_STTD, "[Server] No sound play");
1203 ret = sttd_engine_agent_recognize_start_recorder(uid);
1205 stt_client_unset_current_recognition();
1206 sttd_recorder_unset_audio_session();
1208 sttd_engine_agent_recognize_cancel();
1209 ecore_timer_del(g_recording_timer);
1210 sttd_client_set_state(uid, APP_STATE_READY);
1212 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
1216 /* Notify uid state change */
1217 sttdc_send_set_state(uid, APP_STATE_RECORDING);
1219 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
1220 return STTD_RESULT_STATE_DONE;
1223 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Wait sound finish");
1225 return STTD_RESULT_STATE_NOT_DONE;
1228 Eina_Bool __time_out_for_processing(void *data)
1230 g_processing_timer = NULL;
1233 int uid = stt_client_get_current_recognition();
1234 if (0 == uid) return EINA_FALSE;
1237 int ret = sttd_engine_agent_recognize_cancel();
1239 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1242 if (0 != sttdc_send_result(uid, STTE_RESULT_EVENT_FINAL_RESULT, NULL, 0, "Time out not to receive recognition result.")) {
1243 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
1245 /* send error msg */
1246 int reason = (int)STTD_ERROR_TIMED_OUT;
1247 if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
1248 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
1252 /* Change uid state */
1253 sttd_client_set_state(uid, APP_STATE_READY);
1255 stt_client_unset_current_recognition();
1260 void __sttd_server_engine_stop(void* data)
1262 intptr_t puid = (intptr_t)data;
1263 int uid = (int)puid;
1264 /* change uid state */
1265 sttd_client_set_state(uid, APP_STATE_PROCESSING);
1267 /* Notify uid state change */
1268 sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1270 /* Unset audio session */
1271 int ret = sttd_recorder_unset_audio_session();
1273 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1278 ret = sttd_engine_agent_recognize_stop_engine();
1280 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1284 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1287 void __sttd_stop_sound_completed_cb(int id, void *user_data)
1289 SLOG(LOG_DEBUG, TAG_STTD, "===== Stop sound completed");
1291 /* After wav play callback, engine stop */
1292 ecore_main_loop_thread_safe_call_async(__sttd_server_engine_stop, user_data);
1294 SLOG(LOG_DEBUG, TAG_STTD, "=====");
1295 SLOG(LOG_DEBUG, TAG_STTD, " ");
1299 int sttd_server_stop(int uid)
1301 /* check if uid is valid */
1303 if (0 != sttd_client_get_state(uid, &state)) {
1304 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1305 return STTD_ERROR_INVALID_PARAMETER;
1308 /* check uid state */
1309 if (APP_STATE_RECORDING != state) {
1310 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
1311 return STTD_ERROR_INVALID_STATE;
1314 if (NULL != g_recording_timer) {
1315 ecore_timer_del(g_recording_timer);
1316 g_recording_timer = NULL;
1320 if (0 != sttd_client_get_stop_sound(uid, &sound)) {
1321 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
1322 return STTD_ERROR_OPERATION_FAILED;
1325 SLOG(LOG_DEBUG, TAG_STTD, "[Server] stop sound path : %s", sound);
1328 /* 1. Stop recorder */
1329 ret = sttd_engine_agent_recognize_stop_recorder();
1331 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop recorder : result(%d)", ret);
1332 if (0 != sttd_engine_agent_recognize_cancel()) {
1333 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognize");
1335 if (NULL != sound) free(sound);
1339 /* 2. Request wav play */
1340 if (NULL != sound) {
1342 intptr_t puid = (intptr_t)uid;
1343 ret = wav_player_start(sound, SOUND_TYPE_MEDIA, __sttd_stop_sound_completed_cb, (void*)puid, &id);
1344 if (WAV_PLAYER_ERROR_NONE != ret) {
1345 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
1347 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Play wav : %s", sound);
1352 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1354 return STTD_RESULT_STATE_NOT_DONE;
1356 SLOG(LOG_DEBUG, TAG_STTD, "[Server] No sound play");
1358 /* Unset audio session */
1359 ret = sttd_recorder_unset_audio_session();
1361 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1366 ret = sttd_engine_agent_recognize_stop_engine();
1368 stt_client_unset_current_recognition();
1369 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1373 /* change uid state */
1374 sttd_client_set_state(uid, APP_STATE_PROCESSING);
1376 /* Notify uid state change */
1377 sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1379 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1381 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1383 return STTD_RESULT_STATE_DONE;
1386 return STTD_ERROR_NONE;
1389 int sttd_server_cancel(int uid)
1391 /* check if uid is valid */
1393 if (0 != sttd_client_get_state(uid, &state)) {
1394 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1395 return STTD_ERROR_INVALID_PARAMETER;
1398 /* check uid state */
1399 if (APP_STATE_READY == state) {
1400 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is ready");
1401 return STTD_ERROR_NONE;
1404 stt_client_unset_current_recognition();
1406 if (NULL != g_recording_timer) {
1407 ecore_timer_del(g_recording_timer);
1408 g_recording_timer = NULL;
1411 if (NULL != g_processing_timer) {
1412 ecore_timer_del(g_processing_timer);
1413 g_processing_timer = NULL;
1416 if (APP_STATE_RECORDING == state) {
1417 /* Unset audio session */
1418 int ret = sttd_recorder_unset_audio_session();
1420 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1425 /* change uid state */
1426 sttd_client_set_state(uid, APP_STATE_READY);
1428 /* cancel engine recognition */
1429 int ret = sttd_engine_agent_recognize_cancel();
1431 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1435 /* Notify uid state change */
1436 sttdc_send_set_state(uid, APP_STATE_READY);
1438 return STTD_ERROR_NONE;