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 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 (STTE_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 (STTE_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(&stte_result_mutex);
290 return STTD_ERROR_NONE;
293 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)
295 pthread_mutex_lock(&stte_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);
301 ret = sttd_config_time_add(index, (int)event, text, start_time, end_time);
303 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add time info");
304 pthread_mutex_unlock(&stte_result_time_mutex);
308 pthread_mutex_unlock(&stte_result_time_mutex);
313 int __server_speech_status_callback(stte_speech_status_e status, void *user_param)
315 SLOG(LOG_DEBUG, TAG_STTD, "===== Speech status detected Callback");
317 int uid = stt_client_get_current_recognition();
320 if (0 != sttd_client_get_state(uid, &state)) {
321 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is not valid ");
322 return STTD_ERROR_OPERATION_FAILED;
325 if (APP_STATE_RECORDING != state) {
326 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
327 return STTD_ERROR_INVALID_STATE;
330 if (STTE_SPEECH_STATUS_BEGINNING_POINT_DETECTED == status) {
331 SLOG(LOG_DEBUG, TAG_STTD, "Begin Speech detected");
332 } else if (STTE_SPEECH_STATUS_END_POINT_DETECTED == status) {
333 SLOG(LOG_DEBUG, TAG_STTD, "End Speech detected");
334 ecore_main_loop_thread_safe_call_async(__stop_by_silence, NULL);
337 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current recogntion uid is not valid ");
340 SLOG(LOG_DEBUG, TAG_STTD, "=====");
341 SLOG(LOG_DEBUG, TAG_STTD, " ");
343 return STTD_ERROR_NONE;
346 int __server_error_callback(stte_error_e error, const char* msg)
348 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Error Callback is called");
349 return STTD_ERROR_NONE;
352 void __sttd_server_engine_changed_cb(const char* engine_id, const char* language, bool support_silence, bool need_credential, 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 static void __sig_handler(int signo)
426 /* restore signal handler */
427 signal(signo, SIG_DFL);
429 /* Send error signal to clients */
430 int* client_list = NULL;
431 int client_count = 0;
433 if (0 != sttd_client_get_list(&client_list, &client_count)) {
434 if (NULL != client_list) {
440 if (NULL != client_list) {
441 for (i = 0; i < client_count; i++) {
442 sttdc_send_error_signal(client_list[i], STTD_ERROR_SERVICE_RESET, "Service Reset");
449 /* invoke signal again */
453 static void __register_sig_handler()
455 signal(SIGSEGV, __sig_handler);
456 signal(SIGABRT, __sig_handler);
457 signal(SIGTERM, __sig_handler);
458 signal(SIGINT, __sig_handler);
459 signal(SIGQUIT, __sig_handler);
462 int sttd_initialize(stte_request_callback_s *callback)
466 __register_sig_handler();
468 if (0 != pthread_mutex_init(&stte_result_mutex, NULL)) {
469 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize stte result mutex.");
472 if (0 != pthread_mutex_init(&stte_result_time_mutex, NULL)) {
473 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize stte stte_result_time_mutex.");
476 if (sttd_config_initialize(__sttd_server_engine_changed_cb, __sttd_server_language_changed_cb,
477 __sttd_server_silence_changed_cb, NULL)) {
478 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize config.");
481 ret = sttd_recorder_initialize(__server_audio_recorder_callback, __server_audio_interrupt_callback);
483 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize recorder : result(%d)", ret);
487 /* Engine Agent initialize */
488 ret = sttd_engine_agent_init(__server_recognition_result_callback, __server_result_time_callback,
489 __server_speech_status_callback, __server_error_callback);
491 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine agent initialize : result(%d)", ret);
496 ret = sttd_engine_agent_load_current_engine(callback);
498 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to load default engine");
502 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] initialize");
509 if (0 != pthread_mutex_destroy(&stte_result_mutex)) {
510 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy stte result mutex.");
513 if (0 != pthread_mutex_destroy(&stte_result_time_mutex)) {
514 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy stte_result_time_mutex.");
518 if (0 < g_list_length(g_proc_list)) {
519 iter = g_list_first(g_proc_list);
520 while (NULL != iter) {
521 g_proc_list = g_list_remove_link(g_proc_list, iter);
522 iter = g_list_first(g_proc_list);
526 sttd_recorder_deinitialize();
528 sttd_config_finalize();
530 sttd_engine_agent_release();
532 return STTD_ERROR_NONE;
535 static void __read_proc()
539 struct dirent *dirp = NULL;
544 if (0 < g_list_length(g_proc_list)) {
545 iter = g_list_first(g_proc_list);
546 while (NULL != iter) {
547 g_proc_list = g_list_remove_link(g_proc_list, iter);
548 iter = g_list_first(g_proc_list);
552 dp = opendir("/proc");
554 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to open proc");
557 ret = readdir_r(dp, &entry, &dirp);
559 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to readdir");
564 tmp = atoi(dirp->d_name);
565 if (0 >= tmp) continue;
566 g_proc_list = g_list_append(g_proc_list, GINT_TO_POINTER(tmp));
568 } while (NULL != dirp);
574 Eina_Bool sttd_cleanup_client(void *data)
576 int* client_list = NULL;
577 int client_count = 0;
582 if (0 != sttd_client_get_list(&client_list, &client_count)) {
583 if (NULL != client_list)
589 if (NULL != client_list) {
590 SLOG(LOG_DEBUG, TAG_STTD, "===== Clean up client ");
594 for (i = 0; i < client_count; i++) {
595 int pid = sttd_client_get_pid(client_list[i]);
597 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Invalid pid");
603 for (j = 0; j < g_list_length(g_proc_list); j++) {
604 iter = g_list_nth(g_proc_list, j);
606 if (pid == GPOINTER_TO_INT(iter->data)) {
607 SLOG(LOG_DEBUG, TAG_STTD, "uid (%d) is running", client_list[i]);
614 if (false == exist) {
615 SLOG(LOG_ERROR, TAG_STTD, "uid (%d) should be removed", client_list[i]);
616 sttd_server_finalize(client_list[i]);
619 result = sttdc_send_hello(client_list[i]);
622 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", client_list[i]);
623 sttd_server_finalize(client_list[i]);
624 } else if (-1 == result) {
625 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Hello result has error");
630 SLOG(LOG_DEBUG, TAG_STTD, "=====");
631 SLOG(LOG_DEBUG, TAG_STTD, " ");
640 * STT Server Functions for Client
643 int sttd_server_initialize(int pid, int uid, bool* silence, bool* credential)
645 int ret = STTD_ERROR_NONE;
647 /* check if uid is valid */
649 if (0 == sttd_client_get_state(uid, &state)) {
650 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid has already been registered");
651 return STTD_ERROR_NONE;
654 ret = sttd_engine_agent_get_option_supported(silence);
656 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine options supported");
660 ret = sttd_engine_agent_is_credential_needed(uid, credential);
662 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get credential necessity");
666 /* Add client information to client manager */
667 ret = sttd_client_add(pid, uid);
669 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add client info");
673 return STTD_ERROR_NONE;
676 static Eina_Bool __quit_ecore_loop(void *data)
678 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Quit");
680 stt_network_finalize();
682 ecore_main_loop_quit();
684 SLOG(LOG_DEBUG, TAG_STTD, "");
689 int sttd_server_finalize(int uid)
691 /* check if uid is valid */
693 if (0 != sttd_client_get_state(uid, &state)) {
694 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
695 return STTD_ERROR_INVALID_PARAMETER;
698 /* release recorder */
699 if (APP_STATE_RECORDING == state || APP_STATE_PROCESSING == state) {
700 if (APP_STATE_RECORDING == state) {
701 if (NULL != g_recording_timer) {
702 ecore_timer_del(g_recording_timer);
703 g_recording_timer = NULL;
707 if (APP_STATE_PROCESSING == state) {
708 if (NULL != g_processing_timer) {
709 ecore_timer_del(g_processing_timer);
710 g_processing_timer = NULL;
714 if (0 != sttd_engine_agent_recognize_cancel(uid)) {
715 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognition");
718 stt_client_unset_current_recognition();
721 /* Remove client information */
722 if (0 != sttd_client_delete(uid)) {
723 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to delete client");
726 /* unload engine, if ref count of client is 0 */
727 if (0 == sttd_client_get_ref_count()) {
728 // sttd_dbus_close_connection();
729 ecore_timer_add(0, __quit_ecore_loop, NULL);
732 return STTD_ERROR_NONE;
735 int sttd_server_get_supported_engines(int uid, GSList** engine_list)
737 /* Check if uid is valid */
739 if (0 != sttd_client_get_state(uid, &state)) {
740 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
741 return STTD_ERROR_INVALID_PARAMETER;
744 /* Check state of uid */
745 if (APP_STATE_READY != state) {
746 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
747 return STTD_ERROR_INVALID_STATE;
751 ret = sttd_engine_agent_get_engine_list(engine_list);
753 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine list");
757 return STTD_ERROR_NONE;
760 int sttd_server_set_current_engine(int uid, const char* engine_id, bool* silence, bool* credential)
762 /* Check if uid is valid */
764 if (0 != sttd_client_get_state(uid, &state)) {
765 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
766 return STTD_ERROR_INVALID_PARAMETER;
769 /* Check state of uid */
770 if (APP_STATE_READY != state) {
771 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
772 return STTD_ERROR_INVALID_STATE;
776 ret = sttd_engine_agent_load_current_engine(NULL);
778 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : %d", ret);
782 ret = sttd_engine_agent_get_option_supported(silence);
784 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine options : %d", ret);
788 if (0 != sttd_engine_agent_is_credential_needed(uid, credential)) {
789 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get credential necessity");
793 return STTD_ERROR_NONE;
796 int sttd_server_get_current_engine(int uid, char** engine_id)
798 /* Check if uid is valid */
800 if (0 != sttd_client_get_state(uid, &state)) {
801 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
802 return STTD_ERROR_INVALID_PARAMETER;
805 /* Check state of uid */
806 if (APP_STATE_READY != state) {
807 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
808 return STTD_ERROR_INVALID_STATE;
812 ret = sttd_engine_agent_get_current_engine(engine_id);
814 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine : %d", ret);
818 return STTD_ERROR_NONE;
821 int sttd_server_check_app_agreed(int uid, const char* appid, bool* available)
823 /* Check if uid is valid */
825 if (0 != sttd_client_get_state(uid, &state)) {
826 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
827 return STTD_ERROR_INVALID_PARAMETER;
830 /* Check state of uid */
831 if (APP_STATE_READY != state) {
832 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
833 return STTD_ERROR_INVALID_STATE;
836 /* Ask engine available */
839 ret = sttd_engine_agent_check_app_agreed(appid, &temp);
841 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
846 stt_client_set_app_agreed(uid);
847 SLOG(LOG_DEBUG, TAG_STTD, "[Server] App(%s) confirmed that engine is available", appid);
852 return STTD_ERROR_NONE;
856 int sttd_server_get_supported_languages(int uid, GSList** lang_list)
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 /* get language list from engine */
866 int ret = sttd_engine_agent_supported_langs(lang_list);
868 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get supported languages");
872 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] sttd_server_get_supported_languages");
874 return STTD_ERROR_NONE;
877 int sttd_server_get_current_langauage(int uid, char** current_lang)
879 /* check if uid is valid */
881 if (0 != sttd_client_get_state(uid, &state)) {
882 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
883 return STTD_ERROR_INVALID_PARAMETER;
886 if (NULL == current_lang) {
887 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
888 return STTD_ERROR_INVALID_PARAMETER;
891 /*get current language from engine */
892 int ret = sttd_engine_agent_get_default_lang(current_lang);
894 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get default language :result(%d)", ret);
898 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Get default language");
900 return STTD_ERROR_NONE;
903 int sttd_server_set_private_data(int uid, const char* key, const char* data)
905 /* check if uid is valid */
907 if (0 != sttd_client_get_state(uid, &state)) {
908 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
909 return STTD_ERROR_INVALID_PARAMETER;
912 if (NULL == key || NULL == data) {
913 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
914 return STTD_ERROR_INVALID_PARAMETER;
917 /* set private data to engine */
919 ret = sttd_engine_agent_set_private_data(key, data);
921 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set private data :result(%d)", ret);
925 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Set private data");
927 return STTD_ERROR_NONE;
930 int sttd_server_get_private_data(int uid, const char* key, char** data)
932 /* check if uid is valid */
934 if (0 != sttd_client_get_state(uid, &state)) {
935 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
936 return STTD_ERROR_INVALID_PARAMETER;
939 if (NULL == key || NULL == data) {
940 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
941 return STTD_ERROR_INVALID_PARAMETER;
944 /* get private data to engine */
946 ret = sttd_engine_agent_get_private_data(key, data);
948 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get private data :result(%d)", ret);
952 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Get private data, key(%s), data(%s)", key, *data);
954 return STTD_ERROR_NONE;
957 int sttd_server_is_recognition_type_supported(int uid, const char* type, int* support)
959 /* check if uid is valid */
961 if (0 != sttd_client_get_state(uid, &state)) {
962 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
963 return STTD_ERROR_INVALID_PARAMETER;
966 if (NULL == type || NULL == support) {
967 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
968 return STTD_ERROR_INVALID_PARAMETER;
972 int ret = sttd_engine_agent_is_recognition_type_supported(type, &temp);
974 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get recognition type supported : result(%d)", ret);
978 *support = (int)temp;
980 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] recognition type supporting is %s", *support ? "true" : "false");
982 return STTD_ERROR_NONE;
985 int sttd_server_set_start_sound(int uid, const char* file)
987 /* check if uid is valid */
989 if (0 != sttd_client_get_state(uid, &state)) {
990 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
991 return STTD_ERROR_INVALID_PARAMETER;
994 int ret = sttd_client_set_start_sound(uid, file);
996 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
1003 int sttd_server_set_stop_sound(int uid, const char* file)
1005 /* check if uid is valid */
1007 if (0 != sttd_client_get_state(uid, &state)) {
1008 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1009 return STTD_ERROR_INVALID_PARAMETER;
1012 int ret = sttd_client_set_stop_sound(uid, file);
1014 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
1022 Eina_Bool __check_recording_state(void *data)
1025 int uid = stt_client_get_current_recognition();
1030 if (0 != sttdc_send_get_state(uid, (int*)&state)) {
1031 /* client is removed */
1032 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", uid);
1033 sttd_server_finalize(uid);
1037 if (APP_STATE_READY == state) {
1039 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Ready'. The STT service should cancel recording", uid);
1040 sttd_server_cancel(uid);
1041 } else if (APP_STATE_PROCESSING == state) {
1042 /* Cancel stt and send change state */
1043 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Processing'. The STT service should cancel recording", uid);
1044 sttd_server_cancel(uid);
1045 sttdc_send_set_state(uid, (int)APP_STATE_READY);
1048 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The states of STT service and client are identical");
1056 Eina_Bool __stop_by_recording_timeout(void *data)
1058 SLOG(LOG_DEBUG, TAG_STTD, "===== Stop by timeout");
1060 g_recording_timer = NULL;
1063 uid = stt_client_get_current_recognition();
1065 /* cancel engine recognition */
1066 int ret = sttd_server_stop(uid);
1068 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop : result(%d)", ret);
1072 SLOG(LOG_DEBUG, TAG_STTD, "=====");
1073 SLOG(LOG_DEBUG, TAG_STTD, " ");
1078 void __sttd_server_recorder_start(void* data)
1080 intptr_t puid = (intptr_t)data;
1081 int uid = (int)puid;
1082 int current_uid = stt_client_get_current_recognition();
1084 if (uid != current_uid) {
1085 stt_client_unset_current_recognition();
1089 int ret = sttd_engine_agent_recognize_start_recorder(uid);
1091 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1095 /* Notify uid state change */
1096 sttdc_send_set_state(uid, APP_STATE_RECORDING);
1098 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
1101 void __sttd_start_sound_completed_cb(int id, void *user_data)
1103 SLOG(LOG_DEBUG, TAG_STTD, "===== Start sound completed");
1105 /* After wav play callback, recorder start */
1106 ecore_main_loop_thread_safe_call_async(__sttd_server_recorder_start, user_data);
1108 SLOG(LOG_DEBUG, TAG_STTD, "=====");
1109 SLOG(LOG_DEBUG, TAG_STTD, " ");
1113 int sttd_server_start(int uid, const char* lang, const char* recognition_type, int silence, const char* appid, const char* credential)
1115 if (NULL == lang || NULL == recognition_type) {
1116 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
1117 return STTD_ERROR_INVALID_PARAMETER;
1120 /* check if uid is valid */
1122 if (0 != sttd_client_get_state(uid, &state)) {
1123 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1124 return STTD_ERROR_INVALID_PARAMETER;
1127 /* check uid state */
1128 if (APP_STATE_READY != state) {
1129 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] sttd_server_start : current state is not ready");
1130 return STTD_ERROR_INVALID_STATE;
1134 if (false == stt_client_get_app_agreed(uid)) {
1136 ret = sttd_engine_agent_check_app_agreed(appid, &temp);
1138 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
1142 if (false == temp) {
1143 SLOG(LOG_ERROR, TAG_STTD, "[Server] App(%s) NOT confirmed that engine is available", appid);
1144 return STTD_ERROR_PERMISSION_DENIED;
1147 stt_client_set_app_agreed(uid);
1150 /* check if engine use network */
1151 if (true == sttd_engine_agent_need_network()) {
1152 if (false == stt_network_is_connected()) {
1153 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Disconnect network. Current engine needs to network connection.");
1154 return STTD_ERROR_OUT_OF_NETWORK;
1159 ret = sttd_client_get_start_sound(uid, &sound);
1161 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
1165 if (0 != stt_client_set_current_recognition(uid)) {
1166 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT is busy because of recording or processing");
1167 if (NULL != sound) free(sound);
1168 return STTD_ERROR_RECORDER_BUSY;
1171 /* engine start recognition */
1172 SLOG(LOG_DEBUG, TAG_STTD, "[Server] start : uid(%d), lang(%s), recog_type(%s)",
1173 uid, lang, recognition_type);
1175 SLOG(LOG_DEBUG, TAG_STTD, "[Server] start sound : %s", sound);
1177 /* 1. Set audio session */
1178 ret = sttd_recorder_set_audio_session();
1180 stt_client_unset_current_recognition();
1181 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set session : %d", ret);
1182 if (NULL != sound) free(sound);
1186 bool is_sound_done = false;
1188 /* 2. Request wav play */
1189 if (NULL != sound) {
1191 intptr_t puid = (intptr_t)uid;
1192 ret = wav_player_start(sound, SOUND_TYPE_MEDIA, __sttd_start_sound_completed_cb, (void*)puid, &id);
1193 if (WAV_PLAYER_ERROR_NONE != ret) {
1194 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
1195 is_sound_done = true;
1200 is_sound_done = true;
1203 /* 3. Create recorder & engine initialize */
1204 ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, appid, credential, NULL);
1206 stt_client_unset_current_recognition();
1207 sttd_recorder_unset_audio_session();
1208 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1212 if (0 != strcmp(STTE_RECOGNITION_TYPE_FREE_PARTIAL, recognition_type)) {
1213 g_recording_timer = ecore_timer_add(g_recording_timeout, __stop_by_recording_timeout, NULL);
1216 /* change uid state */
1217 sttd_client_set_state(uid, APP_STATE_RECORDING);
1219 g_recording_log_count = 0;
1221 if (true == is_sound_done) {
1222 SLOG(LOG_DEBUG, TAG_STTD, "[Server] No sound play");
1224 ret = sttd_engine_agent_recognize_start_recorder(uid);
1226 stt_client_unset_current_recognition();
1227 sttd_recorder_unset_audio_session();
1229 sttd_engine_agent_recognize_cancel();
1230 ecore_timer_del(g_recording_timer);
1231 sttd_client_set_state(uid, APP_STATE_READY);
1233 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
1237 /* Notify uid state change */
1238 sttdc_send_set_state(uid, APP_STATE_RECORDING);
1240 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
1241 return STTD_RESULT_STATE_DONE;
1244 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Wait sound finish");
1246 return STTD_RESULT_STATE_NOT_DONE;
1249 Eina_Bool __time_out_for_processing(void *data)
1251 g_processing_timer = NULL;
1254 int uid = stt_client_get_current_recognition();
1255 if (0 == uid) return EINA_FALSE;
1258 int ret = sttd_engine_agent_recognize_cancel();
1260 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1263 if (0 != sttdc_send_result(uid, STTE_RESULT_EVENT_FINAL_RESULT, NULL, 0, "Time out not to receive recognition result.")) {
1264 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
1266 /* send error msg */
1267 int reason = (int)STTD_ERROR_TIMED_OUT;
1268 if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
1269 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
1273 /* Change uid state */
1274 sttd_client_set_state(uid, APP_STATE_READY);
1276 stt_client_unset_current_recognition();
1281 void __sttd_server_engine_stop(void* data)
1283 intptr_t puid = (intptr_t)data;
1284 int uid = (int)puid;
1285 /* change uid state */
1286 sttd_client_set_state(uid, APP_STATE_PROCESSING);
1288 /* Notify uid state change */
1289 sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1291 /* Unset audio session */
1292 int ret = sttd_recorder_unset_audio_session();
1294 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1299 ret = sttd_engine_agent_recognize_stop_engine();
1301 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1305 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1308 void __sttd_stop_sound_completed_cb(int id, void *user_data)
1310 SLOG(LOG_DEBUG, TAG_STTD, "===== Stop sound completed");
1312 /* After wav play callback, engine stop */
1313 ecore_main_loop_thread_safe_call_async(__sttd_server_engine_stop, user_data);
1315 SLOG(LOG_DEBUG, TAG_STTD, "=====");
1316 SLOG(LOG_DEBUG, TAG_STTD, " ");
1320 int sttd_server_stop(int uid)
1322 /* check if uid is valid */
1324 if (0 != sttd_client_get_state(uid, &state)) {
1325 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1326 return STTD_ERROR_INVALID_PARAMETER;
1329 /* check uid state */
1330 if (APP_STATE_RECORDING != state) {
1331 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
1332 return STTD_ERROR_INVALID_STATE;
1335 if (NULL != g_recording_timer) {
1336 ecore_timer_del(g_recording_timer);
1337 g_recording_timer = NULL;
1341 if (0 != sttd_client_get_stop_sound(uid, &sound)) {
1342 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
1343 return STTD_ERROR_OPERATION_FAILED;
1346 SLOG(LOG_DEBUG, TAG_STTD, "[Server] stop sound path : %s", sound);
1349 /* 1. Stop recorder */
1350 ret = sttd_engine_agent_recognize_stop_recorder();
1352 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop recorder : result(%d)", ret);
1353 if (0 != sttd_engine_agent_recognize_cancel()) {
1354 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognize");
1356 if (NULL != sound) free(sound);
1360 /* 2. Request wav play */
1361 if (NULL != sound) {
1363 intptr_t puid = (intptr_t)uid;
1364 ret = wav_player_start(sound, SOUND_TYPE_MEDIA, __sttd_stop_sound_completed_cb, (void*)puid, &id);
1365 if (WAV_PLAYER_ERROR_NONE != ret) {
1366 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
1368 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Play wav : %s", sound);
1373 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1375 return STTD_RESULT_STATE_NOT_DONE;
1377 SLOG(LOG_DEBUG, TAG_STTD, "[Server] No sound play");
1379 /* Unset audio session */
1380 ret = sttd_recorder_unset_audio_session();
1382 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1387 ret = sttd_engine_agent_recognize_stop_engine();
1389 stt_client_unset_current_recognition();
1390 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1394 /* change uid state */
1395 sttd_client_set_state(uid, APP_STATE_PROCESSING);
1397 /* Notify uid state change */
1398 sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1400 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1402 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1404 return STTD_RESULT_STATE_DONE;
1407 return STTD_ERROR_NONE;
1410 int sttd_server_cancel(int uid)
1412 /* check if uid is valid */
1414 if (0 != sttd_client_get_state(uid, &state)) {
1415 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1416 return STTD_ERROR_INVALID_PARAMETER;
1419 /* check uid state */
1420 if (APP_STATE_READY == state) {
1421 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is ready");
1422 return STTD_ERROR_NONE;
1425 stt_client_unset_current_recognition();
1427 if (NULL != g_recording_timer) {
1428 ecore_timer_del(g_recording_timer);
1429 g_recording_timer = NULL;
1432 if (NULL != g_processing_timer) {
1433 ecore_timer_del(g_processing_timer);
1434 g_processing_timer = NULL;
1437 if (APP_STATE_RECORDING == state) {
1438 /* Unset audio session */
1439 int ret = sttd_recorder_unset_audio_session();
1441 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1446 /* change uid state */
1447 sttd_client_set_state(uid, APP_STATE_READY);
1449 /* cancel engine recognition */
1450 int ret = sttd_engine_agent_recognize_cancel();
1452 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1456 /* Notify uid state change */
1457 sttdc_send_set_state(uid, APP_STATE_READY);
1459 return STTD_ERROR_NONE;