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"
28 #define CLIENT_CLEAN_UP_TIME 500
31 static pthread_mutex_t stte_result_mutex = PTHREAD_MUTEX_INITIALIZER;
32 static pthread_mutex_t stte_result_time_mutex = PTHREAD_MUTEX_INITIALIZER;
36 * STT Server static variable
38 static double g_processing_timeout = 30;
40 static double g_recording_timeout = 60;
42 static Ecore_Timer* g_check_client_timer = NULL;
43 Ecore_Timer* g_recording_timer = NULL;
44 Ecore_Timer* g_processing_timer = NULL;
46 static int g_recording_log_count = 0;
48 static GList *g_proc_list = NULL;
51 * STT Server Callback Functions
53 void __stop_by_silence(void *data)
55 SLOG(LOG_DEBUG, TAG_STTD, "===== Stop by silence detection");
59 uid = stt_client_get_current_recognition();
63 ret = sttd_server_stop(uid);
68 if (STTD_RESULT_STATE_DONE == ret) {
69 ret = sttdc_send_set_state(uid, (int)APP_STATE_PROCESSING);
71 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send state : result(%d)", ret);
74 sttd_server_finalize(uid);
75 stt_client_unset_current_recognition();
79 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid is NOT valid");
82 SLOG(LOG_DEBUG, TAG_STTD, "=====");
83 SLOG(LOG_DEBUG, TAG_STTD, " ");
88 static void __cancel_recognition_internal()
90 if (NULL != g_recording_timer) {
91 ecore_timer_del(g_recording_timer);
92 g_recording_timer = NULL;
97 uid = stt_client_get_current_recognition();
99 app_state_e state = 0;
100 ret = sttd_client_get_state(uid, &state);
103 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
107 if (0 != uid && (APP_STATE_PROCESSING == state || APP_STATE_RECORDING == state)) {
108 /* cancel engine recognition */
109 ret = sttd_server_cancel(uid);
111 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
114 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid is NOT valid");
118 static void __cancel_by_error(void *data)
120 SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by error");
122 __cancel_recognition_internal();
124 SLOG(LOG_DEBUG, TAG_STTD, "=====");
125 SLOG(LOG_DEBUG, TAG_STTD, " ");
130 int __server_audio_recorder_callback(const void* data, const unsigned int length)
135 if (NULL == data || 0 == length) {
136 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Recording data is not valid");
137 ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
141 uid = stt_client_get_current_recognition();
143 ret = sttd_engine_agent_set_recording_data(data, length);
145 ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
148 g_recording_log_count++;
149 if (200 <= g_recording_log_count) {
150 SLOG(LOG_DEBUG, TAG_STTD, "=== Set recording data ===");
151 g_recording_log_count = 0;
154 if (NULL != g_recording_timer) {
155 ecore_timer_del(g_recording_timer);
156 g_recording_timer = NULL;
158 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current uid in recording is is not valid");
165 void __server_audio_interrupt_callback()
167 SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by sound interrupt");
169 __cancel_recognition_internal();
171 SLOG(LOG_DEBUG, TAG_STTD, "=====");
172 SLOG(LOG_DEBUG, TAG_STTD, " ");
175 void __cancel_by_no_record(void *data)
177 SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by no record");
179 __cancel_recognition_internal();
181 SLOG(LOG_DEBUG, TAG_STTD, "=====");
182 SLOG(LOG_DEBUG, TAG_STTD, " ");
187 int __server_recognition_result_callback(stte_result_event_e event, const char* type,
188 const char** data, int data_count, const char* msg, void *user_data)
191 pthread_mutex_lock(&stte_result_mutex);
193 SLOG(LOG_DEBUG, TAG_STTD, "===== RESULT event[%d] type[%s] data[%p] data_count[%d]", event, type, data, data_count);
196 int uid = stt_client_get_current_recognition();
199 if (0 == uid || 0 != sttd_client_get_state(uid, &state)) {
200 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
201 SLOG(LOG_DEBUG, TAG_STTD, "=====");
202 SLOG(LOG_DEBUG, TAG_STTD, " ");
203 pthread_mutex_unlock(&stte_result_mutex);
204 return STTD_ERROR_OPERATION_FAILED;
207 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid (%d), event(%d)", uid, event);
209 /* send result to client */
210 if (STTE_RESULT_EVENT_FINAL_RESULT == event) {
211 if (APP_STATE_PROCESSING != state) {
212 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is NOT 'Processing'.");
214 SLOG(LOG_DEBUG, TAG_STTD, "[Server] the size of result from engine is '%d'", data_count);
216 /* Delete timer for processing time out */
217 if (NULL != g_processing_timer) {
218 ecore_timer_del(g_processing_timer);
219 g_processing_timer = NULL;
222 sttd_config_time_save();
223 sttd_config_time_reset();
225 sttd_recorder_clear();
227 sttd_client_set_state(uid, APP_STATE_READY);
228 stt_client_unset_current_recognition();
230 if (NULL == data || 0 == data_count) {
231 if (0 != sttdc_send_result(uid, event, NULL, 0, msg)) {
232 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
233 int reason = (int)STTD_ERROR_OPERATION_FAILED;
235 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
236 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
240 if (0 != sttdc_send_result(uid, event, data, data_count, msg)) {
241 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
242 int reason = (int)STTD_ERROR_OPERATION_FAILED;
244 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
245 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
250 /* change state of uid */
251 // sttd_client_set_state(uid, APP_STATE_READY);
252 // stt_client_unset_current_recognition();
254 } else if (STTE_RESULT_EVENT_PARTIAL_RESULT == event) {
255 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The partial result from engine is event[%d] data_count[%d]", event, data_count);
257 sttd_config_time_save();
258 sttd_config_time_reset();
260 if (0 != sttdc_send_result(uid, event, data, data_count, msg)) {
261 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
262 int reason = (int)STTD_ERROR_OPERATION_FAILED;
264 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
265 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
269 } else if (STTE_RESULT_EVENT_ERROR == event) {
270 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The event of recognition result is ERROR");
272 /* Delete timer for processing time out */
273 if (NULL != g_processing_timer) {
274 ecore_timer_del(g_processing_timer);
275 g_processing_timer = NULL;
277 sttd_config_time_reset();
280 if (APP_STATE_RECORDING == state) {
281 ret = sttd_engine_agent_recognize_cancel();
283 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel: result(%d)", ret);
287 sttd_client_set_state(uid, APP_STATE_READY);
288 stt_client_unset_current_recognition();
290 if (0 != sttdc_send_result(uid, event, NULL, 0, msg)) {
291 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
294 int reason = (int)STTD_ERROR_INVALID_STATE;
295 if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
296 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
300 /* change state of uid */
301 // sttd_client_set_state(uid, APP_STATE_READY);
302 // stt_client_unset_current_recognition();
307 SLOG(LOG_DEBUG, TAG_STTD, "=====");
308 SLOG(LOG_DEBUG, TAG_STTD, " ");
309 pthread_mutex_unlock(&stte_result_mutex);
311 return STTD_ERROR_NONE;
314 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)
316 pthread_mutex_lock(&stte_result_time_mutex);
318 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] index(%d) event(%d) text(%s) start(%ld) end(%ld)",
319 index, event, text, start_time, end_time);
322 ret = sttd_config_time_add(index, (int)event, text, start_time, end_time);
324 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add time info");
325 pthread_mutex_unlock(&stte_result_time_mutex);
329 pthread_mutex_unlock(&stte_result_time_mutex);
334 int __server_speech_status_callback(stte_speech_status_e status, void *user_param)
336 SLOG(LOG_DEBUG, TAG_STTD, "===== Speech status detected Callback");
338 int uid = stt_client_get_current_recognition();
341 if (0 != sttd_client_get_state(uid, &state)) {
342 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is not valid ");
343 return STTD_ERROR_OPERATION_FAILED;
346 if (APP_STATE_RECORDING != state && APP_STATE_PROCESSING != state) {
347 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording, state(%d), status(%d)", state, status);
348 return STTD_ERROR_INVALID_STATE;
351 if (STTE_SPEECH_STATUS_BEGINNING_POINT_DETECTED == status) {
352 SLOG(LOG_DEBUG, TAG_STTD, "Begin Speech detected");
353 sttdc_send_speech_status(uid, status);
354 } else if (STTE_SPEECH_STATUS_END_POINT_DETECTED == status) {
355 SLOG(LOG_DEBUG, TAG_STTD, "End Speech detected");
356 ecore_main_loop_thread_safe_call_async(__stop_by_silence, NULL);
359 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current recognition uid is not valid ");
362 SLOG(LOG_DEBUG, TAG_STTD, "=====");
363 SLOG(LOG_DEBUG, TAG_STTD, " ");
365 return STTD_ERROR_NONE;
368 int __server_error_callback(stte_error_e error, const char* msg)
370 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Error Callback is called");
371 ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
373 return STTD_ERROR_NONE;
376 void __sttd_server_engine_changed_cb(const char* engine_id, const char* language, bool support_silence, bool need_credential, void* user_data)
378 if (NULL == engine_id) {
379 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Engine id is NULL");
382 SLOG(LOG_DEBUG, TAG_STTD, "[Server] New default engine : %s", engine_id);
386 /* need to change state of app to ready */
388 uid = stt_client_get_current_recognition();
391 SLOG(LOG_ERROR, TAG_STTD, "[Server] Set ready state of uid(%d)", uid);
393 sttd_server_cancel(uid);
394 sttdc_send_set_state(uid, (int)APP_STATE_READY);
396 stt_client_unset_current_recognition();
400 int ret = sttd_engine_agent_set_default_engine(engine_id);
402 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : result(%d)", ret);
404 if (NULL != language) {
405 ret = sttd_engine_agent_set_default_language(language);
407 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%d)", ret);
410 ret = sttd_engine_agent_set_silence_detection(support_silence);
412 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 g_check_client_timer = ecore_timer_add(CLIENT_CLEAN_UP_TIME, sttd_cleanup_client, NULL);
488 if (NULL == g_check_client_timer) {
489 SLOG(LOG_WARN, TAG_STTD, "[Main Warning] Fail to create timer of client check");
492 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] initialize");
499 if (0 != pthread_mutex_destroy(&stte_result_mutex)) {
500 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy stte result mutex.");
503 if (0 != pthread_mutex_destroy(&stte_result_time_mutex)) {
504 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy stte_result_time_mutex.");
508 if (0 < g_list_length(g_proc_list)) {
509 iter = g_list_first(g_proc_list);
510 while (NULL != iter) {
511 g_proc_list = g_list_remove_link(g_proc_list, iter);
512 iter = g_list_first(g_proc_list);
516 sttd_recorder_deinitialize();
518 sttd_config_finalize();
520 sttd_engine_agent_release();
522 if (NULL != g_check_client_timer) {
523 ecore_timer_del(g_check_client_timer);
524 g_check_client_timer = NULL;
526 SLOG(LOG_INFO, TAG_STTD, "[INFO] Delete ecore timer handle");
529 return STTD_ERROR_NONE;
532 static void __read_proc()
535 struct dirent *dirp = NULL;
539 if (0 < g_list_length(g_proc_list)) {
540 iter = g_list_first(g_proc_list);
541 while (NULL != iter) {
542 g_proc_list = g_list_remove_link(g_proc_list, iter);
543 iter = g_list_first(g_proc_list);
547 dp = opendir("/proc");
549 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to open proc");
555 tmp = atoi(dirp->d_name);
556 if (0 >= tmp) continue;
557 g_proc_list = g_list_append(g_proc_list, GINT_TO_POINTER(tmp));
559 } while (NULL != dirp);
565 Eina_Bool sttd_cleanup_client(void *data)
567 int* client_list = NULL;
568 int client_count = 0;
573 if (0 != sttd_client_get_list(&client_list, &client_count)) {
574 if (NULL != client_list)
580 if (NULL != client_list) {
581 SLOG(LOG_DEBUG, TAG_STTD, "===== Clean up client ");
585 for (i = 0; i < client_count; i++) {
586 int pid = sttd_client_get_pid(client_list[i]);
588 SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Invalid pid");
594 for (j = 0; j < g_list_length(g_proc_list); j++) {
595 iter = g_list_nth(g_proc_list, j);
597 if (pid == GPOINTER_TO_INT(iter->data)) {
598 SLOG(LOG_DEBUG, TAG_STTD, "uid (%d) is running", client_list[i]);
605 if (false == exist) {
606 SLOG(LOG_ERROR, TAG_STTD, "uid (%d) should be removed", client_list[i]);
607 sttd_server_finalize(client_list[i]);
610 result = sttdc_send_hello(client_list[i]);
613 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", client_list[i]);
614 sttd_server_finalize(client_list[i]);
615 } else if (-1 == result) {
616 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Hello result has error");
621 SLOG(LOG_DEBUG, TAG_STTD, "=====");
622 SLOG(LOG_DEBUG, TAG_STTD, " ");
631 * STT Server Functions for Client
634 int sttd_server_initialize(int pid, int uid, bool* silence, bool* credential)
636 int ret = STTD_ERROR_NONE;
638 /* check if uid is valid */
640 if (0 == sttd_client_get_state(uid, &state)) {
641 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid has already been registered");
642 return STTD_ERROR_NONE;
645 ret = sttd_engine_agent_get_option_supported(silence);
647 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine options supported");
651 ret = sttd_engine_agent_is_credential_needed(uid, credential);
653 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get credential necessity");
657 /* Add client information to client manager */
658 ret = sttd_client_add(pid, uid);
660 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add client info");
664 return STTD_ERROR_NONE;
667 static Eina_Bool __quit_ecore_loop(void *data)
669 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Quit");
671 stt_network_finalize();
673 sttd_dbus_close_connection();
674 ecore_main_loop_quit();
676 SLOG(LOG_DEBUG, TAG_STTD, "");
681 int sttd_server_finalize(int uid)
683 SLOG(LOG_INFO, TAG_STTD, "[Server INFO] Enter Finalize");
685 /* check if uid is valid */
687 if (0 != sttd_client_get_state(uid, &state)) {
688 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
689 return STTD_ERROR_INVALID_PARAMETER;
692 /* release recorder */
693 if (APP_STATE_RECORDING == state || APP_STATE_PROCESSING == state) {
694 if (APP_STATE_RECORDING == state) {
695 if (NULL != g_recording_timer) {
696 ecore_timer_del(g_recording_timer);
697 g_recording_timer = NULL;
701 if (APP_STATE_PROCESSING == state) {
702 if (NULL != g_processing_timer) {
703 ecore_timer_del(g_processing_timer);
704 g_processing_timer = NULL;
708 SLOG(LOG_INFO, TAG_STTD, "[Server INFO] stt_cancel is invoked while state is (%d)", state);
710 if (0 != sttd_engine_agent_recognize_cancel(uid)) {
711 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognition");
714 stt_client_unset_current_recognition();
717 /* Remove client information */
718 if (0 != sttd_client_delete(uid)) {
719 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to delete client");
722 /* unload engine, if ref count of client is 0 */
723 if (0 == sttd_client_get_ref_count()) {
724 // sttd_dbus_close_connection();
725 ecore_timer_add(0, __quit_ecore_loop, NULL);
728 SLOG(LOG_INFO, TAG_STTD, "[Server INFO] End Finalize");
730 return STTD_ERROR_NONE;
733 int sttd_server_get_supported_engines(int uid, GSList** engine_list)
735 /* Check if uid is valid */
737 if (0 != sttd_client_get_state(uid, &state)) {
738 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
739 return STTD_ERROR_INVALID_PARAMETER;
742 /* Check state of uid */
743 if (APP_STATE_READY != state) {
744 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
745 return STTD_ERROR_INVALID_STATE;
749 ret = sttd_engine_agent_get_engine_list(engine_list);
751 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine list");
755 return STTD_ERROR_NONE;
758 int sttd_server_set_current_engine(int uid, const char* engine_id, bool* silence, bool* credential)
760 /* Check if uid is valid */
762 if (0 != sttd_client_get_state(uid, &state)) {
763 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
764 return STTD_ERROR_INVALID_PARAMETER;
767 /* Check state of uid */
768 if (APP_STATE_READY != state) {
769 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
770 return STTD_ERROR_INVALID_STATE;
774 ret = sttd_engine_agent_load_current_engine(NULL);
776 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : %d", ret);
780 ret = sttd_engine_agent_get_option_supported(silence);
782 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine options : %d", ret);
786 if (0 != sttd_engine_agent_is_credential_needed(uid, credential)) {
787 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get credential necessity");
791 return STTD_ERROR_NONE;
794 int sttd_server_get_current_engine(int uid, char** engine_id)
796 /* Check if uid is valid */
798 if (0 != sttd_client_get_state(uid, &state)) {
799 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
800 return STTD_ERROR_INVALID_PARAMETER;
803 /* Check state of uid */
804 if (APP_STATE_READY != state) {
805 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
806 return STTD_ERROR_INVALID_STATE;
810 ret = sttd_engine_agent_get_current_engine(engine_id);
812 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine : %d", ret);
816 return STTD_ERROR_NONE;
819 int sttd_server_check_app_agreed(int uid, const char* appid, bool* available)
821 /* Check if uid is valid */
823 if (0 != sttd_client_get_state(uid, &state)) {
824 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
825 return STTD_ERROR_INVALID_PARAMETER;
828 /* Check state of uid */
829 if (APP_STATE_READY != state) {
830 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
831 return STTD_ERROR_INVALID_STATE;
834 /* Ask engine available */
837 ret = sttd_engine_agent_check_app_agreed(appid, &temp);
839 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
844 stt_client_set_app_agreed(uid);
845 SLOG(LOG_DEBUG, TAG_STTD, "[Server] App(%s) confirmed that engine is available", appid);
850 return STTD_ERROR_NONE;
854 int sttd_server_get_supported_languages(int uid, GSList** lang_list)
856 /* check if uid is valid */
858 if (0 != sttd_client_get_state(uid, &state)) {
859 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
860 return STTD_ERROR_INVALID_PARAMETER;
863 /* get language list from engine */
864 int ret = sttd_engine_agent_supported_langs(lang_list);
866 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get supported languages");
870 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] sttd_server_get_supported_languages");
872 return STTD_ERROR_NONE;
875 int sttd_server_get_current_langauage(int uid, char** current_lang)
877 /* check if uid is valid */
879 if (0 != sttd_client_get_state(uid, &state)) {
880 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
881 return STTD_ERROR_INVALID_PARAMETER;
884 if (NULL == current_lang) {
885 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
886 return STTD_ERROR_INVALID_PARAMETER;
889 /*get current language from engine */
890 int ret = sttd_engine_agent_get_default_lang(current_lang);
892 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get default language :result(%d)", ret);
896 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Get default language");
898 return STTD_ERROR_NONE;
901 int sttd_server_set_private_data(int uid, const char* key, const char* data)
903 /* check if uid is valid */
905 if (0 != sttd_client_get_state(uid, &state)) {
906 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
907 return STTD_ERROR_INVALID_PARAMETER;
910 if (NULL == key || NULL == data) {
911 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
912 return STTD_ERROR_INVALID_PARAMETER;
915 /* set private data to engine */
917 ret = sttd_engine_agent_set_private_data(key, data);
919 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set private data :result(%d)", ret);
923 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Set private data");
925 return STTD_ERROR_NONE;
928 int sttd_server_get_private_data(int uid, const char* key, char** data)
930 /* check if uid is valid */
932 if (0 != sttd_client_get_state(uid, &state)) {
933 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
934 return STTD_ERROR_INVALID_PARAMETER;
937 if (NULL == key || NULL == data) {
938 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
939 return STTD_ERROR_INVALID_PARAMETER;
942 /* get private data to engine */
944 ret = sttd_engine_agent_get_private_data(key, data);
946 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get private data :result(%d)", ret);
950 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Get private data, key(%s), data(%s)", key, *data);
952 return STTD_ERROR_NONE;
955 int sttd_server_is_recognition_type_supported(int uid, const char* type, int* support)
957 /* check if uid is valid */
959 if (0 != sttd_client_get_state(uid, &state)) {
960 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
961 return STTD_ERROR_INVALID_PARAMETER;
964 if (NULL == type || NULL == support) {
965 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
966 return STTD_ERROR_INVALID_PARAMETER;
970 int ret = sttd_engine_agent_is_recognition_type_supported(type, &temp);
972 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get recognition type supported : result(%d)", ret);
976 *support = (int)temp;
978 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] recognition type supporting is %s", *support ? "true" : "false");
980 return STTD_ERROR_NONE;
983 int sttd_server_set_start_sound(int uid, const char* file)
985 /* check if uid is valid */
987 if (0 != sttd_client_get_state(uid, &state)) {
988 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
989 return STTD_ERROR_INVALID_PARAMETER;
992 int ret = sttd_client_set_start_sound(uid, file);
994 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
1001 int sttd_server_set_stop_sound(int uid, const char* file)
1003 /* check if uid is valid */
1005 if (0 != sttd_client_get_state(uid, &state)) {
1006 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1007 return STTD_ERROR_INVALID_PARAMETER;
1010 int ret = sttd_client_set_stop_sound(uid, file);
1012 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
1020 Eina_Bool __check_recording_state(void *data)
1023 int uid = stt_client_get_current_recognition();
1028 if (0 != sttdc_send_get_state(uid, (int*)&state)) {
1029 /* client is removed */
1030 SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", uid);
1031 sttd_server_finalize(uid);
1035 if (APP_STATE_READY == state) {
1037 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Ready'. The STT service should cancel recording", uid);
1038 sttd_server_cancel(uid);
1039 } else if (APP_STATE_PROCESSING == state) {
1040 /* Cancel stt and send change state */
1041 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Processing'. The STT service should cancel recording", uid);
1042 sttd_server_cancel(uid);
1043 sttdc_send_set_state(uid, (int)APP_STATE_READY);
1046 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The states of STT service and client are identical");
1054 Eina_Bool __stop_by_recording_timeout(void *data)
1056 SLOG(LOG_DEBUG, TAG_STTD, "===== Stop by timeout");
1058 if (NULL != g_recording_timer) {
1059 ecore_timer_del(g_recording_timer);
1060 g_recording_timer = NULL;
1064 uid = stt_client_get_current_recognition();
1066 /* cancel engine recognition */
1067 int ret = sttd_server_stop(uid);
1069 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop : result(%d)", ret);
1073 SLOG(LOG_DEBUG, TAG_STTD, "=====");
1074 SLOG(LOG_DEBUG, TAG_STTD, " ");
1079 void __sttd_server_recorder_start(void* data)
1081 intptr_t puid = (intptr_t)data;
1082 int uid = (int)puid;
1083 int current_uid = stt_client_get_current_recognition();
1085 if (uid != current_uid) {
1086 stt_client_unset_current_recognition();
1090 int ret = sttd_engine_agent_recognize_start_recorder(uid);
1092 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1096 app_state_e temp_app_state;
1097 if (0 != sttd_client_get_state(uid, &temp_app_state)) {
1098 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1101 if (APP_STATE_READY != temp_app_state && 0 != stt_client_get_current_recognition()) {
1102 /* Notify uid state change */
1103 sttdc_send_set_state(uid, APP_STATE_RECORDING);
1104 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
1108 void __sttd_start_sound_completed_cb(int id, void *user_data)
1110 SLOG(LOG_DEBUG, TAG_STTD, "===== Start sound completed");
1112 /* After wav play callback, recorder start */
1113 ecore_main_loop_thread_safe_call_async(__sttd_server_recorder_start, user_data);
1115 SLOG(LOG_DEBUG, TAG_STTD, "=====");
1116 SLOG(LOG_DEBUG, TAG_STTD, " ");
1120 int sttd_server_start(int uid, const char* lang, const char* recognition_type, int silence, const char* appid, const char* credential)
1122 if (NULL == lang || NULL == recognition_type) {
1123 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
1124 return STTD_ERROR_INVALID_PARAMETER;
1127 /* check if uid is valid */
1129 if (0 != sttd_client_get_state(uid, &state)) {
1130 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1131 return STTD_ERROR_INVALID_PARAMETER;
1134 /* check uid state */
1135 if (APP_STATE_READY != state) {
1136 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] sttd_server_start : current state is not ready");
1137 return STTD_ERROR_INVALID_STATE;
1141 if (false == stt_client_get_app_agreed(uid)) {
1143 ret = sttd_engine_agent_check_app_agreed(appid, &temp);
1145 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
1149 if (false == temp) {
1150 SLOG(LOG_ERROR, TAG_STTD, "[Server] App(%s) NOT confirmed that engine is available", appid);
1151 return STTD_ERROR_PERMISSION_DENIED;
1154 stt_client_set_app_agreed(uid);
1157 /* check if engine use network */
1158 if (true == sttd_engine_agent_need_network()) {
1159 if (false == stt_network_is_connected()) {
1160 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Disconnect network. Current engine needs to network connection.");
1161 return STTD_ERROR_OUT_OF_NETWORK;
1165 if (NULL != g_recording_timer) {
1166 ecore_timer_del(g_recording_timer);
1167 g_recording_timer = NULL;
1170 if (NULL != g_processing_timer) {
1171 ecore_timer_del(g_processing_timer);
1172 g_processing_timer = NULL;
1176 ret = sttd_client_get_start_sound(uid, &sound);
1178 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
1182 if (0 != stt_client_set_current_recognition(uid)) {
1183 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT is busy because of recording or processing");
1184 if (NULL != sound) free(sound);
1185 return STTD_ERROR_RECORDER_BUSY;
1188 /* engine start recognition */
1189 SLOG(LOG_DEBUG, TAG_STTD, "[Server] start : uid(%d), lang(%s), recog_type(%s)",
1190 uid, lang, recognition_type);
1192 SLOG(LOG_DEBUG, TAG_STTD, "[Server] start sound : %s", sound);
1194 /* 1. Set audio session */
1195 ret = sttd_recorder_set_audio_session();
1197 stt_client_unset_current_recognition();
1198 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set session : %d", ret);
1199 if (NULL != sound) free(sound);
1203 bool is_sound_done = false;
1205 /* 2. Request wav play */
1206 if (NULL != sound) {
1208 intptr_t puid = (intptr_t)uid;
1209 sound_stream_info_h wav_stream_info_h;
1210 if (0 != sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, NULL, NULL, &wav_stream_info_h)) {
1211 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to create stream info for playing wav");
1212 is_sound_done = true;
1214 ret = wav_player_start_new(sound, wav_stream_info_h, __sttd_start_sound_completed_cb, (void*)puid, &id);
1215 if (WAV_PLAYER_ERROR_NONE != ret) {
1216 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
1217 is_sound_done = true;
1220 if (0 != sound_manager_destroy_stream_information(wav_stream_info_h)) {
1221 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy stream info for playing wav");
1227 is_sound_done = true;
1230 /* 3. Create recorder & engine initialize */
1231 ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, appid, credential, NULL);
1233 stt_client_unset_current_recognition();
1234 sttd_recorder_unset_audio_session();
1235 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1239 if (0 != strcmp(STTE_RECOGNITION_TYPE_FREE_PARTIAL, recognition_type)) {
1240 g_recording_timer = ecore_timer_add(g_recording_timeout, __stop_by_recording_timeout, NULL);
1243 /* change uid state */
1244 sttd_client_set_state(uid, APP_STATE_RECORDING);
1246 g_recording_log_count = 0;
1248 app_state_e temp_app_state;
1250 if (true == is_sound_done) {
1251 SLOG(LOG_DEBUG, TAG_STTD, "[Server] No sound play");
1253 ret = sttd_engine_agent_recognize_start_recorder(uid);
1255 stt_client_unset_current_recognition();
1256 sttd_recorder_unset_audio_session();
1258 sttd_engine_agent_recognize_cancel();
1259 if (NULL != g_recording_timer) {
1260 ecore_timer_del(g_recording_timer);
1261 g_recording_timer = NULL;
1263 sttd_client_set_state(uid, APP_STATE_READY);
1265 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
1269 if (0 != sttd_client_get_state(uid, &temp_app_state)) {
1270 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid");
1271 return STTD_ERROR_INVALID_PARAMETER;
1273 if (APP_STATE_READY != temp_app_state && 0 != stt_client_get_current_recognition()) {
1274 /* Notify uid state change */
1275 sttdc_send_set_state(uid, APP_STATE_RECORDING);
1278 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
1279 return STTD_RESULT_STATE_DONE;
1282 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Wait sound finish");
1284 return STTD_RESULT_STATE_NOT_DONE;
1287 Eina_Bool __time_out_for_processing(void *data)
1289 if (NULL != g_processing_timer) {
1290 ecore_timer_del(g_processing_timer);
1291 g_processing_timer = NULL;
1294 SLOG(LOG_INFO, TAG_STTD, "[Server INFO] Enter __time_out_for_processing");
1297 int uid = stt_client_get_current_recognition();
1298 if (0 == uid) return EINA_FALSE;
1300 SLOG(LOG_INFO, TAG_STTD, "[Server Info] stt cancel is invoked by timeout for processing");
1303 int ret = sttd_engine_agent_recognize_cancel();
1305 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1308 if (0 != sttdc_send_result(uid, STTE_RESULT_EVENT_FINAL_RESULT, NULL, 0, "Time out not to receive recognition result.")) {
1309 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
1311 /* send error msg */
1312 int reason = (int)STTD_ERROR_TIMED_OUT;
1313 if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
1314 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
1318 /* Change uid state */
1319 sttd_client_set_state(uid, APP_STATE_READY);
1321 stt_client_unset_current_recognition();
1323 SLOG(LOG_INFO, TAG_STTD, "[Server INFO] End __time_out_for_processing");
1328 void __sttd_server_engine_stop(void* data)
1330 intptr_t puid = (intptr_t)data;
1331 int uid = (int)puid;
1332 /* change uid state */
1333 sttd_client_set_state(uid, APP_STATE_PROCESSING);
1335 /* Notify uid state change */
1336 sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1338 /* Unset audio session */
1339 int ret = sttd_recorder_unset_audio_session();
1341 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1346 ret = sttd_engine_agent_recognize_stop_engine();
1348 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1352 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1355 void __sttd_stop_sound_completed_cb(int id, void *user_data)
1357 SLOG(LOG_DEBUG, TAG_STTD, "===== Stop sound completed");
1359 /* After wav play callback, engine stop */
1360 ecore_main_loop_thread_safe_call_async(__sttd_server_engine_stop, user_data);
1362 SLOG(LOG_DEBUG, TAG_STTD, "=====");
1363 SLOG(LOG_DEBUG, TAG_STTD, " ");
1367 int sttd_server_stop(int uid)
1369 /* check if uid is valid */
1371 if (0 != sttd_client_get_state(uid, &state)) {
1372 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1373 return STTD_ERROR_INVALID_PARAMETER;
1376 /* check uid state */
1377 if (APP_STATE_RECORDING != state) {
1378 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
1379 return STTD_ERROR_INVALID_STATE;
1382 if (NULL != g_recording_timer) {
1383 ecore_timer_del(g_recording_timer);
1384 g_recording_timer = NULL;
1387 if (NULL != g_processing_timer) {
1388 ecore_timer_del(g_processing_timer);
1389 g_processing_timer = NULL;
1393 if (0 != sttd_client_get_stop_sound(uid, &sound)) {
1394 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
1395 return STTD_ERROR_OPERATION_FAILED;
1398 SLOG(LOG_DEBUG, TAG_STTD, "[Server] stop sound path : %s", sound);
1401 /* 1. Stop recorder */
1402 ret = sttd_engine_agent_recognize_stop_recorder();
1404 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop recorder : result(%d)", ret);
1405 if (0 != sttd_engine_agent_recognize_cancel()) {
1406 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognize");
1408 if (NULL != sound) free(sound);
1412 /* 2. Request wav play */
1413 if (NULL != sound) {
1415 intptr_t puid = (intptr_t)uid;
1416 sound_stream_info_h wav_stream_info_h;
1417 if (0 != sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, NULL, NULL, &wav_stream_info_h)) {
1418 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to create stream info for playing wav");
1420 ret = wav_player_start_new(sound, wav_stream_info_h, __sttd_stop_sound_completed_cb, (void*)puid, &id);
1421 if (WAV_PLAYER_ERROR_NONE != ret) {
1422 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
1424 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Play wav : %s", sound);
1427 if (0 != sound_manager_destroy_stream_information(wav_stream_info_h)) {
1428 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy stream info for playing wav");
1433 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1435 return STTD_RESULT_STATE_NOT_DONE;
1437 SLOG(LOG_DEBUG, TAG_STTD, "[Server] No sound play");
1439 /* Unset audio session */
1440 ret = sttd_recorder_unset_audio_session();
1442 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1447 ret = sttd_engine_agent_recognize_stop_engine();
1449 stt_client_unset_current_recognition();
1450 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1454 /* change uid state */
1455 sttd_client_set_state(uid, APP_STATE_PROCESSING);
1457 /* Notify uid state change */
1458 sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1460 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1462 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1464 return STTD_RESULT_STATE_DONE;
1467 return STTD_ERROR_NONE;
1470 int sttd_server_cancel(int uid)
1472 SLOG(LOG_INFO, TAG_STTD, "[Server INFO] Enter sttd_server_cancel");
1474 /* check if uid is valid */
1476 if (0 != sttd_client_get_state(uid, &state)) {
1477 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1478 return STTD_ERROR_INVALID_PARAMETER;
1481 /* check uid state */
1482 if (APP_STATE_READY == state) {
1483 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is ready");
1484 return STTD_ERROR_NONE;
1487 stt_client_unset_current_recognition();
1489 if (NULL != g_recording_timer) {
1490 ecore_timer_del(g_recording_timer);
1491 g_recording_timer = NULL;
1494 if (NULL != g_processing_timer) {
1495 ecore_timer_del(g_processing_timer);
1496 g_processing_timer = NULL;
1499 if (APP_STATE_RECORDING == state) {
1500 /* Unset audio session */
1501 int ret = sttd_recorder_unset_audio_session();
1503 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1508 /* change uid state */
1509 sttd_client_set_state(uid, APP_STATE_READY);
1511 SLOG(LOG_INFO, TAG_STTD, "[Server Info] stt cancel is invoked by app's request");
1513 /* cancel engine recognition */
1514 int ret = sttd_engine_agent_recognize_cancel();
1516 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1520 /* Notify uid state change */
1521 sttdc_send_set_state(uid, APP_STATE_READY);
1523 SLOG(LOG_INFO, TAG_STTD, "[Server INFO] End sttd_server_cancel");
1525 return STTD_ERROR_NONE;
1528 int sttd_server_start_file(int uid, const char* lang, const char* recognition_type, int silence, const char* appid, const char* credential,
1529 const char* filepath, stte_audio_type_e audio_type, int sample_rate)
1531 if (NULL == lang || NULL == recognition_type || NULL == filepath) {
1532 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
1533 return STTD_ERROR_INVALID_PARAMETER;
1536 /* check if uid is valid */
1538 if (0 != sttd_client_get_state(uid, &state)) {
1539 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1540 return STTD_ERROR_INVALID_PARAMETER;
1543 /* check uid state */
1544 if (APP_STATE_READY != state) {
1545 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] sttd_server_start : current state is not ready");
1546 return STTD_ERROR_INVALID_STATE;
1550 if (false == stt_client_get_app_agreed(uid)) {
1552 ret = sttd_engine_agent_check_app_agreed(appid, &temp);
1554 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
1558 if (false == temp) {
1559 SLOG(LOG_ERROR, TAG_STTD, "[Server] App(%s) NOT confirmed that engine is available", appid);
1560 return STTD_ERROR_PERMISSION_DENIED;
1563 stt_client_set_app_agreed(uid);
1566 /* check if engine use network */
1567 if (true == sttd_engine_agent_need_network()) {
1568 if (false == stt_network_is_connected()) {
1569 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Disconnect network. Current engine needs to network connection.");
1570 return STTD_ERROR_OUT_OF_NETWORK;
1574 if (0 != stt_client_set_current_recognition(uid)) {
1575 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT is busy because of recording or processing");
1576 return STTD_ERROR_RECORDER_BUSY;
1579 /* engine start recognition */
1580 SLOG(LOG_DEBUG, TAG_STTD, "[Server] start : uid(%d), lang(%s), recog_type(%s), appid(%s), file(%s), audio_type(%d), sample_rate(%d)", uid, lang, recognition_type, appid, filepath, audio_type, sample_rate);
1582 /* 1. Set audio session */
1583 ret = sttd_recorder_set_audio_session();
1585 stt_client_unset_current_recognition();
1586 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set session : %d", ret);
1590 /* 2. Start engine to recognize */
1591 ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, appid, credential, NULL);
1593 stt_client_unset_current_recognition();
1594 sttd_recorder_unset_audio_session();
1595 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start engine : result(%d)", ret);
1599 sttd_client_set_state(uid, APP_STATE_RECORDING);
1600 sttdc_send_set_state(uid, APP_STATE_RECORDING);
1602 /* 3. Start to send pcm from file to engine */
1603 ret = sttd_engine_agent_recognize_start_file(uid, filepath);
1605 stt_client_unset_current_recognition();
1606 sttd_recorder_unset_audio_session();
1607 sttd_engine_agent_recognize_cancel();
1608 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start file : result(%d)", ret);
1612 /* 4. Stop to send pcm from file */
1613 ret = sttd_engine_agent_recognize_stop_file();
1615 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop recorder : result(%d)", ret);
1616 stt_client_unset_current_recognition();
1617 sttd_recorder_unset_audio_session();
1618 sttd_engine_agent_recognize_cancel();
1622 /* 5. change & notify uid state */
1623 sttd_client_set_state(uid, APP_STATE_PROCESSING);
1624 sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1626 /* 6. Unset audio session */
1627 ret = sttd_recorder_unset_audio_session();
1629 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1630 stt_client_unset_current_recognition();
1634 /* 7. Stop engine */
1635 ret = sttd_engine_agent_recognize_stop_engine();
1637 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1638 stt_client_unset_current_recognition();
1642 return STTD_ERROR_NONE;
1645 int sttd_server_cancel_file(int uid)
1647 /* check if uid is valid */
1649 if (0 != sttd_client_get_state(uid, &state)) {
1650 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1651 return STTD_ERROR_INVALID_PARAMETER;
1654 /* check uid state */
1655 if (APP_STATE_READY == state) {
1656 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is ready");
1657 return STTD_ERROR_NONE;
1660 stt_client_unset_current_recognition();
1662 if (NULL != g_recording_timer) {
1663 ecore_timer_del(g_recording_timer);
1664 g_recording_timer = NULL;
1667 if (NULL != g_processing_timer) {
1668 ecore_timer_del(g_processing_timer);
1669 g_processing_timer = NULL;
1672 if (APP_STATE_RECORDING == state) {
1673 /* Unset audio session */
1674 int ret = sttd_recorder_unset_audio_session();
1676 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1681 /* change uid state */
1682 sttd_client_set_state(uid, APP_STATE_READY);
1684 /* cancel engine recognition */
1685 int ret = sttd_engine_agent_recognize_cancel();
1687 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1691 /* Notify uid state change */
1692 sttdc_send_set_state(uid, APP_STATE_READY);
1694 return STTD_ERROR_NONE;