2 * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd All Rights Reserved
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 * http://www.apache.org/licenses/LICENSE-2.0
7 * Unless required by applicable law or agreed to in writing, software
8 * distributed under the License is distributed on an "AS IS" BASIS,
9 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 * See the License for the specific language governing permissions and
11 * limitations under the License.
14 #include <sound_manager.h>
15 #include <wav_player.h>
17 #include "stt_network.h"
18 #include "sttd_client_data.h"
19 #include "sttd_config.h"
20 #include "sttd_dbus.h"
21 #include "sttd_engine_agent.h"
22 #include "sttd_main.h"
23 #include "sttd_recorder.h"
24 #include "sttd_server.h"
28 * STT Server static variable
30 static double g_processing_timeout = 30;
32 static double g_recording_timeout = 60;
34 Ecore_Timer* g_recording_timer = NULL;
35 Ecore_Timer* g_processing_timer = NULL;
37 static int g_recording_log_count = 0;
40 * STT Server Callback Functions
43 Eina_Bool __stop_by_silence(void *data)
45 SLOG(LOG_DEBUG, TAG_STTD, "===== Stop by silence detection");
49 uid = stt_client_get_current_recognition();
53 ret = sttd_server_stop(uid);
58 if (STTD_RESULT_STATE_DONE == ret) {
59 ret = sttdc_send_set_state(uid, (int)APP_STATE_PROCESSING);
61 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send state : result(%d)", ret);
64 sttd_server_finalize(uid);
65 stt_client_unset_current_recognition();
69 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid is NOT valid");
72 SLOG(LOG_DEBUG, TAG_STTD, "=====");
73 SLOG(LOG_DEBUG, TAG_STTD, " ");
78 static void __cancel_recognition_internal()
80 if (NULL != g_recording_timer) {
81 ecore_timer_del(g_recording_timer);
82 g_recording_timer = NULL;
86 uid = stt_client_get_current_recognition();
89 /* cancel engine recognition */
90 int ret = sttd_engine_agent_recognize_cancel(uid);
92 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
95 /* change uid state */
96 sttd_client_set_state(uid, APP_STATE_READY);
97 stt_client_unset_current_recognition();
99 ret = sttdc_send_set_state(uid, (int)APP_STATE_READY);
101 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send state change : result(%d)", ret);
104 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid is NOT valid");
108 Eina_Bool __cancel_by_error(void *data)
110 SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by error");
112 __cancel_recognition_internal();
114 SLOG(LOG_DEBUG, TAG_STTD, "=====");
115 SLOG(LOG_DEBUG, TAG_STTD, " ");
120 int __server_audio_recorder_callback(const void* data, const unsigned int length)
125 if (NULL == data || 0 == length) {
126 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Recording data is not valid");
127 ecore_timer_add(0, __cancel_by_error, NULL);
131 uid = stt_client_get_current_recognition();
133 ret = sttd_engine_agent_set_recording_data(uid, data, length);
135 ecore_timer_add(0, __cancel_by_error, NULL);
138 g_recording_log_count++;
139 if (200 <= g_recording_log_count) {
140 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "=== Set recording data ===");
141 g_recording_log_count = 0;
144 if (NULL != g_recording_timer) {
145 ecore_timer_del(g_recording_timer);
146 g_recording_timer = NULL;
148 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current uid in recording is is not valid");
155 void __server_audio_interrupt_callback()
157 SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by sound interrupt");
159 __cancel_recognition_internal();
161 SLOG(LOG_DEBUG, TAG_STTD, "=====");
162 SLOG(LOG_DEBUG, TAG_STTD, " ");
165 Eina_Bool __cancel_by_no_record(void *data)
167 SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by no record");
169 __cancel_recognition_internal();
171 SLOG(LOG_DEBUG, TAG_STTD, "=====");
172 SLOG(LOG_DEBUG, TAG_STTD, " ");
177 void __server_recognition_result_callback(sttp_result_event_e event, const char* type,
178 const char** data, int data_count, const char* msg, void *user_data)
180 SLOG(LOG_DEBUG, TAG_STTD, "===== Recognition Result Callback");
183 int uid = stt_client_get_current_recognition();
186 if (0 == uid || 0 != sttd_client_get_state(uid, &state)) {
187 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
188 SLOG(LOG_DEBUG, TAG_STTD, "=====");
189 SLOG(LOG_DEBUG, TAG_STTD, " ");
193 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid (%d), event(%d)", uid, event);
195 /* send result to client */
196 if (STTP_RESULT_EVENT_FINAL_RESULT == event) {
197 if (APP_STATE_PROCESSING != state ) {
198 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is NOT 'Processing'.");
200 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] the size of result from engine is '%d'", data_count);
202 /* Delete timer for processing time out */
203 if (NULL != g_processing_timer) {
204 ecore_timer_del(g_processing_timer);
205 g_processing_timer = NULL;
208 sttd_config_time_save();
209 sttd_config_time_reset();
211 if (NULL == data || 0 == data_count) {
212 if (0 != sttdc_send_result(uid, event, NULL, 0, msg)) {
213 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
214 int reason = (int)STTD_ERROR_OPERATION_FAILED;
216 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
217 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
221 if (0 != sttdc_send_result(uid, event, data, data_count, 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");
231 /* change state of uid */
232 sttd_client_set_state(uid, APP_STATE_READY);
233 stt_client_unset_current_recognition();
235 } else if (STTP_RESULT_EVENT_PARTIAL_RESULT == event) {
236 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] The partial result from engine is event[%d] data_count[%d]", event, data_count);
238 sttd_config_time_save();
239 sttd_config_time_reset();
241 if (0 != sttdc_send_result(uid, event, data, data_count, msg)) {
242 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
243 int reason = (int)STTD_ERROR_OPERATION_FAILED;
245 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
246 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
250 } else if (STTP_RESULT_EVENT_ERROR == event) {
251 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The event of recognition result is ERROR");
253 /* Delete timer for processing time out */
254 if (NULL != g_processing_timer) {
255 ecore_timer_del(g_processing_timer);
256 g_processing_timer = NULL;
258 sttd_config_time_reset();
260 if (0 != sttdc_send_result(uid, event, NULL, 0, msg)) {
261 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
264 int reason = (int)STTD_ERROR_INVALID_STATE;
265 if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
266 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
270 /* change state of uid */
271 sttd_client_set_state(uid, APP_STATE_READY);
272 stt_client_unset_current_recognition();
277 SLOG(LOG_DEBUG, TAG_STTD, "=====");
278 SLOG(LOG_DEBUG, TAG_STTD, " ");
283 bool __server_result_time_callback(int index, sttp_result_time_event_e event, const char* text, long start_time, long end_time, void* user_data)
285 SLOG(LOG_DEBUG, TAG_STTD, "[Server] index(%d) event(%d) text(%s) start(%ld) end(%ld)",
286 index, event, text, start_time, end_time);
290 ret = sttd_config_time_add(index, (int)event, text, start_time, end_time);
292 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add time info");
302 void __server_silence_dectection_callback(sttp_silence_type_e type, void *user_param)
304 SLOG(LOG_DEBUG, TAG_STTD, "===== Silence Detection Callback");
306 int uid = stt_client_get_current_recognition();
309 if (0 != sttd_client_get_state(uid, &state)) {
310 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is not valid ");
314 if (APP_STATE_RECORDING != state) {
315 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
319 if (STTP_SILENCE_TYPE_NO_RECORD_TIMEOUT == type) {
320 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "Silence Detection type - No Record");
321 ecore_timer_add(0, __cancel_by_no_record, NULL);
322 } else if (STTP_SILENCE_TYPE_END_OF_SPEECH_DETECTED == type) {
323 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "Silence Detection type - End of Speech");
324 ecore_timer_add(0, __stop_by_silence, NULL);
327 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current recogntion uid is not valid ");
330 SLOG(LOG_DEBUG, TAG_STTD, "=====");
331 SLOG(LOG_DEBUG, TAG_STTD, " ");
336 void __sttd_server_engine_changed_cb(const char* engine_id, const char* language, bool support_silence, void* user_data)
338 if (NULL == engine_id) {
339 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Engine id is NULL");
342 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] New default engine : %s", engine_id);
345 /* need to change state of app to ready */
347 uid = stt_client_get_current_recognition();
350 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Server] Set ready state of uid(%d)", uid);
352 sttd_server_cancel(uid);
353 sttdc_send_set_state(uid, (int)APP_STATE_READY);
355 stt_client_unset_current_recognition();
359 int ret = sttd_engine_agent_set_default_engine(engine_id);
361 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : result(%d)", ret);
363 if (NULL != language) {
364 ret = sttd_engine_agent_set_default_language(language);
366 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%d)", ret);
369 ret = sttd_engine_agent_set_silence_detection(support_silence);
371 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret);
376 void __sttd_server_language_changed_cb(const char* language, void* user_data)
378 if (NULL == language) {
379 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] language is NULL");
382 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] Get language changed : %s", language);
385 int ret = sttd_engine_agent_set_default_language(language);
387 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%d)", ret);
392 void __sttd_server_silence_changed_cb(bool value, void* user_data)
394 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] Get silence detection changed : %s", value ? "on" : "off");
397 ret = sttd_engine_agent_set_silence_detection(value);
399 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret);
408 int sttd_initialize()
412 if (sttd_config_initialize(__sttd_server_engine_changed_cb, __sttd_server_language_changed_cb,
413 __sttd_server_silence_changed_cb, NULL)) {
414 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize config.");
417 ret = sttd_recorder_initialize(__server_audio_recorder_callback, __server_audio_interrupt_callback);
419 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize recorder : result(%d)", ret);
422 /* Engine Agent initialize */
423 ret = sttd_engine_agent_init(__server_recognition_result_callback, __server_result_time_callback,
424 __server_silence_dectection_callback);
426 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine agent initialize : result(%d)", ret);
430 /* Update engine list */
431 ret = sttd_engine_agent_initialize_engine_list();
433 if (STTD_ERROR_ENGINE_NOT_FOUND == ret) {
434 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] There is no stt engine");
436 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to update engine list : %d", ret);
441 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] initialize");
448 sttd_recorder_deinitialize();
450 sttd_config_finalize();
452 sttd_engine_agent_release();
454 return STTD_ERROR_NONE;
457 Eina_Bool sttd_cleanup_client(void *data)
459 int* client_list = NULL;
460 int client_count = 0;
464 if (0 != sttd_client_get_list(&client_list, &client_count)) {
465 if (NULL != client_list)
471 if (NULL != client_list) {
472 SLOG(LOG_DEBUG, TAG_STTD, "===== Clean up client ");
474 for (i = 0;i < client_count;i++) {
475 result = sttdc_send_hello(client_list[i]);
478 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", client_list[i]);
479 sttd_server_finalize(client_list[i]);
480 } else if (-1 == result) {
481 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Hello result has error");
485 SLOG(LOG_DEBUG, TAG_STTD, "=====");
486 SLOG(LOG_DEBUG, TAG_STTD, " ");
495 * STT Server Functions for Client
498 int sttd_server_initialize(int pid, int uid, bool* silence)
500 if (false == sttd_engine_agent_is_default_engine()) {
501 /* Update installed engine */
502 sttd_engine_agent_initialize_engine_list();
504 if (false == sttd_engine_agent_is_default_engine()) {
505 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] No stt-engine");
506 return STTD_ERROR_ENGINE_NOT_FOUND;
510 /* check if uid is valid */
512 if (0 == sttd_client_get_state(uid, &state)) {
513 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid has already been registered");
514 return STTD_ERROR_NONE;
518 if (0 != sttd_engine_agent_load_current_engine(uid, NULL)) {
519 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to load default engine");
520 return STTD_ERROR_OPERATION_FAILED;
523 if (0 != sttd_engine_agent_get_option_supported(uid, silence)) {
524 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine options supported");
525 return STTD_ERROR_OPERATION_FAILED;
528 /* Add client information to client manager */
529 if (0 != sttd_client_add(pid, uid)) {
530 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add client info");
531 return STTD_ERROR_OPERATION_FAILED;
534 return STTD_ERROR_NONE;
537 static Eina_Bool __quit_ecore_loop(void *data)
539 ecore_main_loop_quit();
543 int sttd_server_finalize(int uid)
545 /* check if uid is valid */
547 if (0 != sttd_client_get_state(uid, &state)) {
548 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
549 return STTD_ERROR_INVALID_PARAMETER;
552 /* release recorder */
553 if (APP_STATE_RECORDING == state || APP_STATE_PROCESSING == state) {
554 if (APP_STATE_RECORDING == state) {
555 if (NULL != g_recording_timer) {
556 ecore_timer_del(g_recording_timer);
557 g_recording_timer = NULL;
561 if (APP_STATE_PROCESSING == state) {
562 if (NULL != g_processing_timer) {
563 ecore_timer_del(g_processing_timer);
564 g_processing_timer = NULL;
568 if (0 != sttd_engine_agent_recognize_cancel(uid)) {
569 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognition");
572 stt_client_unset_current_recognition();
575 if (0 != sttd_engine_agent_unload_current_engine(uid)) {
576 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unload engine");
579 /* Remove client information */
580 if (0 != sttd_client_delete(uid)) {
581 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to delete client");
584 /* unload engine, if ref count of client is 0 */
585 if (0 == sttd_client_get_ref_count()) {
586 sttd_dbus_close_connection();
587 ecore_timer_add(0, __quit_ecore_loop, NULL);
590 return STTD_ERROR_NONE;
593 int sttd_server_get_supported_engines(int uid, GSList** engine_list)
595 /* Check if uid is valid */
597 if (0 != sttd_client_get_state(uid, &state)) {
598 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
599 return STTD_ERROR_INVALID_PARAMETER;
602 /* Check state of uid */
603 if (APP_STATE_READY != state) {
604 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
605 return STTD_ERROR_INVALID_STATE;
609 ret = sttd_engine_agent_get_engine_list(engine_list);
611 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine list");
612 return STTD_ERROR_OPERATION_FAILED;
615 return STTD_ERROR_NONE;
618 int sttd_server_set_current_engine(int uid, const char* engine_id, bool* silence)
620 /* Check if uid is valid */
622 if (0 != sttd_client_get_state(uid, &state)) {
623 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
624 return STTD_ERROR_INVALID_PARAMETER;
627 /* Check state of uid */
628 if (APP_STATE_READY != state) {
629 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
630 return STTD_ERROR_INVALID_STATE;
634 ret = sttd_engine_agent_load_current_engine(uid, engine_id);
636 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : %d", ret);
637 return STTD_ERROR_OPERATION_FAILED;
640 ret = sttd_engine_agent_get_option_supported(uid, silence);
642 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine options : %d", ret);
643 return STTD_ERROR_OPERATION_FAILED;
646 return STTD_ERROR_NONE;
649 int sttd_server_get_current_engine(int uid, char** engine_id)
651 /* Check if uid is valid */
653 if (0 != sttd_client_get_state(uid, &state)) {
654 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
655 return STTD_ERROR_INVALID_PARAMETER;
658 /* Check state of uid */
659 if (APP_STATE_READY != state) {
660 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
661 return STTD_ERROR_INVALID_STATE;
665 ret = sttd_engine_agent_get_current_engine(uid, engine_id);
667 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine : %d", ret);
668 return STTD_ERROR_OPERATION_FAILED;
671 return STTD_ERROR_NONE;
674 int sttd_server_check_agg_agreed(int uid, const char* appid, bool* available)
676 /* Check if uid is valid */
678 if (0 != sttd_client_get_state(uid, &state)) {
679 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
680 return STTD_ERROR_INVALID_PARAMETER;
683 /* Check state of uid */
684 if (APP_STATE_READY != state) {
685 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
686 return STTD_ERROR_INVALID_STATE;
689 /* Ask engine available */
692 ret = sttd_engine_agent_check_app_agreed(uid, appid, &temp);
694 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
695 return STTD_ERROR_OPERATION_FAILED;
699 stt_client_set_app_agreed(uid);
700 SLOG(LOG_DEBUG, TAG_STTD, "[Server] App(%s) confirmed that engine is available", appid);
705 return STTD_ERROR_NONE;
709 int sttd_server_get_supported_languages(int uid, GSList** lang_list)
711 /* check if uid is valid */
713 if (0 != sttd_client_get_state(uid, &state)) {
714 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
715 return STTD_ERROR_INVALID_PARAMETER;
718 /* get language list from engine */
719 int ret = sttd_engine_agent_supported_langs(uid, lang_list);
721 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get supported languages");
722 return STTD_ERROR_OPERATION_FAILED;
725 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] sttd_server_get_supported_languages");
727 return STTD_ERROR_NONE;
730 int sttd_server_get_current_langauage(int uid, char** current_lang)
732 /* check if uid is valid */
734 if (0 != sttd_client_get_state(uid, &state)) {
735 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
736 return STTD_ERROR_INVALID_PARAMETER;
739 if (NULL == current_lang) {
740 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
741 return STTD_ERROR_INVALID_PARAMETER;
744 /*get current language from engine */
745 int ret = sttd_engine_agent_get_default_lang(uid, current_lang);
747 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get default language :result(%d)", ret);
748 return STTD_ERROR_OPERATION_FAILED;
751 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Get default language");
753 return STTD_ERROR_NONE;
756 int sttd_server_is_recognition_type_supported(int uid, const char* type, int* support)
758 /* check if uid is valid */
760 if (0 != sttd_client_get_state(uid, &state)) {
761 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
762 return STTD_ERROR_INVALID_PARAMETER;
765 if (NULL == type || NULL == support) {
766 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
767 return STTD_ERROR_INVALID_PARAMETER;
771 int ret = sttd_engine_agent_is_recognition_type_supported(uid, type, &temp);
773 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get recognition type supported : result(%d)", ret);
774 return STTD_ERROR_OPERATION_FAILED;
777 *support = (int)temp;
779 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] recognition type supporting is %s", *support ? "true" : "false");
781 return STTD_ERROR_NONE;
784 int sttd_server_set_start_sound(int uid, const char* file)
786 /* check if uid is valid */
788 if (0 != sttd_client_get_state(uid, &state)) {
789 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
790 return STTD_ERROR_INVALID_PARAMETER;
793 int ret = sttd_client_set_start_sound(uid, file);
795 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
796 return STTD_ERROR_OPERATION_FAILED;
802 int sttd_server_set_stop_sound(int uid, const char* file)
804 /* check if uid is valid */
806 if (0 != sttd_client_get_state(uid, &state)) {
807 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
808 return STTD_ERROR_INVALID_PARAMETER;
811 int ret = sttd_client_set_stop_sound(uid, file);
813 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
814 return STTD_ERROR_OPERATION_FAILED;
820 Eina_Bool __check_recording_state(void *data)
823 int uid = stt_client_get_current_recognition();
828 if (0 != sttdc_send_get_state(uid, (int*)&state)) {
829 /* client is removed */
830 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", uid);
831 sttd_server_finalize(uid);
835 if (APP_STATE_READY == state) {
837 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Ready'. The daemon should cancel recording", uid);
838 sttd_server_cancel(uid);
839 } else if (APP_STATE_PROCESSING == state) {
840 /* Cancel stt and send change state */
841 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Processing'. The daemon should cancel recording", uid);
842 sttd_server_cancel(uid);
843 sttdc_send_set_state(uid, (int)APP_STATE_READY);
846 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The states of daemon and client are identical");
853 Eina_Bool __stop_by_recording_timeout(void *data)
855 SLOG(LOG_DEBUG, TAG_STTD, "===== Stop by timeout");
857 g_recording_timer = NULL;
860 uid = stt_client_get_current_recognition();
862 /* cancel engine recognition */
863 int ret = sttd_server_stop(uid);
865 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop : result(%d)", ret);
869 SLOG(LOG_DEBUG, TAG_STTD, "=====");
870 SLOG(LOG_DEBUG, TAG_STTD, " ");
875 void __sttd_server_recorder_start(int uid)
877 int current_uid = stt_client_get_current_recognition();
879 if (uid != current_uid) {
880 stt_client_unset_current_recognition();
884 int ret = sttd_engine_agent_recognize_start_recorder(uid);
886 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
890 /* Notify uid state change */
891 sttdc_send_set_state(uid, APP_STATE_RECORDING);
893 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
896 void __sttd_start_sound_completed_cb(int id, void *user_data)
898 SLOG(LOG_DEBUG, TAG_STTD, "===== Start sound completed");
900 int uid = (int)user_data;
901 /* 4. after wav play callback, recorder start */
902 __sttd_server_recorder_start(uid);
904 SLOG(LOG_DEBUG, TAG_STTD, "=====");
905 SLOG(LOG_DEBUG, TAG_STTD, " ");
909 int sttd_server_start(int uid, const char* lang, const char* recognition_type, int silence, const char* appid)
911 if (NULL == lang || NULL == recognition_type) {
912 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
913 return STTD_ERROR_INVALID_PARAMETER;
916 /* check if uid is valid */
918 if (0 != sttd_client_get_state(uid, &state)) {
919 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
920 return STTD_ERROR_INVALID_PARAMETER;
923 /* check uid state */
924 if (APP_STATE_READY != state) {
925 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] sttd_server_start : current state is not ready");
926 return STTD_ERROR_INVALID_STATE;
930 if (false == stt_client_get_app_agreed(uid)) {
932 ret = sttd_engine_agent_check_app_agreed(uid, appid, &temp);
934 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
935 return STTD_ERROR_OPERATION_FAILED;
939 SLOG(LOG_ERROR, TAG_STTD, "[Server] App(%s) NOT confirmed that engine is available", appid);
940 return STTD_ERROR_PERMISSION_DENIED;
943 stt_client_set_app_agreed(uid);
946 /* check if engine use network */
947 if (true == sttd_engine_agent_need_network(uid)) {
948 if (false == stt_network_is_connected()) {
949 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Disconnect network. Current engine needs to network connection.");
950 return STTD_ERROR_OUT_OF_NETWORK;
955 if (0 != sttd_client_get_start_sound(uid, &sound)) {
956 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
957 return STTD_ERROR_OPERATION_FAILED;
960 if (0 != stt_client_set_current_recognition(uid)) {
961 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT is busy because of recording or processing");
962 if (NULL != sound) free(sound);
963 return STTD_ERROR_RECORDER_BUSY;
966 /* engine start recognition */
967 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] start : uid(%d), lang(%s), recog_type(%s)",
968 uid, lang, recognition_type);
970 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] start sound : %s", sound);
972 /* 1. Set audio session */
973 ret = sttd_recorder_set_audio_session();
975 stt_client_unset_current_recognition();
976 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set session : %d", ret);
977 if (NULL != sound) free(sound);
981 bool is_sound_done = false;
983 /* 2. Request wav play */
986 ret = wav_player_start(sound, SOUND_TYPE_MEDIA, __sttd_start_sound_completed_cb, (void*)uid, &id);
987 if (WAV_PLAYER_ERROR_NONE != ret) {
988 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
989 is_sound_done = true;
994 is_sound_done = true;
997 /* 3. Create recorder & engine initialize */
998 ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, NULL);
1000 stt_client_unset_current_recognition();
1001 sttd_recorder_unset_audio_session();
1002 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1006 if (0 != strcmp(STTP_RECOGNITION_TYPE_FREE_PARTIAL, recognition_type)) {
1007 g_recording_timer = ecore_timer_add(g_recording_timeout, __stop_by_recording_timeout, NULL);
1010 /* change uid state */
1011 sttd_client_set_state(uid, APP_STATE_RECORDING);
1013 g_recording_log_count = 0;
1015 if (true == is_sound_done) {
1016 SLOG(LOG_DEBUG, TAG_STTD, "[Server] No sound play");
1018 ret = sttd_engine_agent_recognize_start_recorder(uid);
1020 stt_client_unset_current_recognition();
1021 sttd_recorder_unset_audio_session();
1023 sttd_engine_agent_recognize_cancel(uid);
1024 ecore_timer_del(g_recording_timer);
1025 sttd_client_set_state(uid, APP_STATE_READY);
1027 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
1028 return STTD_ERROR_OPERATION_FAILED;
1031 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
1032 return STTD_RESULT_STATE_DONE;
1035 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Wait sound finish");
1037 return STTD_RESULT_STATE_NOT_DONE;
1040 Eina_Bool __time_out_for_processing(void *data)
1042 g_processing_timer = NULL;
1045 int uid = stt_client_get_current_recognition();
1046 if (0 == uid) return EINA_FALSE;
1049 int ret = sttd_engine_agent_recognize_cancel(uid);
1051 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1054 if (0 != sttdc_send_result(uid, STTP_RESULT_EVENT_FINAL_RESULT, NULL, 0, "Time out not to receive recognition result.")) {
1055 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
1057 /* send error msg */
1058 int reason = (int)STTD_ERROR_TIMED_OUT;
1059 if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
1060 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
1064 /* Change uid state */
1065 sttd_client_set_state(uid, APP_STATE_READY);
1067 stt_client_unset_current_recognition();
1072 void __sttd_server_engine_stop(int uid)
1074 /* change uid state */
1075 sttd_client_set_state(uid, APP_STATE_PROCESSING);
1077 /* Notify uid state change */
1078 sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1080 /* Unset audio session */
1081 int ret = sttd_recorder_unset_audio_session();
1083 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1088 ret = sttd_engine_agent_recognize_stop_engine(uid);
1090 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1094 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1097 void __sttd_stop_sound_completed_cb(int id, void *user_data)
1099 SLOG(LOG_DEBUG, TAG_STTD, "===== Stop sound completed");
1101 int uid = (int)user_data;
1102 /* After wav play callback, engine stop */
1103 __sttd_server_engine_stop(uid);
1105 SLOG(LOG_DEBUG, TAG_STTD, "=====");
1106 SLOG(LOG_DEBUG, TAG_STTD, " ");
1110 int sttd_server_stop(int uid)
1112 /* check if uid is valid */
1114 if (0 != sttd_client_get_state(uid, &state)) {
1115 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1116 return STTD_ERROR_INVALID_PARAMETER;
1119 /* check uid state */
1120 if (APP_STATE_RECORDING != state) {
1121 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
1122 return STTD_ERROR_INVALID_STATE;
1125 if (NULL != g_recording_timer) {
1126 ecore_timer_del(g_recording_timer);
1127 g_recording_timer = NULL;
1131 if (0 != sttd_client_get_stop_sound(uid, &sound)) {
1132 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
1133 return STTD_ERROR_OPERATION_FAILED;
1136 SLOG(LOG_DEBUG, TAG_STTD, "[Server] stop sound path : %s", sound);
1139 /* 1. Stop recorder */
1140 ret = sttd_engine_agent_recognize_stop_recorder(uid);
1142 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop recorder : result(%d)", ret);
1143 if (0 != sttd_engine_agent_recognize_cancel(uid)) {
1144 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognize");
1146 if (NULL != sound) free(sound);
1147 return STTD_ERROR_OPERATION_FAILED;
1150 /* 2. Request wav play */
1151 if (NULL != sound) {
1153 ret = wav_player_start(sound, SOUND_TYPE_MEDIA, __sttd_stop_sound_completed_cb, (void*)uid, &id);
1154 if (WAV_PLAYER_ERROR_NONE != ret) {
1155 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
1157 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Play wav : %s", sound);
1162 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1164 return STTD_RESULT_STATE_NOT_DONE;
1166 SLOG(LOG_DEBUG, TAG_STTD, "[Server] No sound play");
1168 /* Unset audio session */
1169 ret = sttd_recorder_unset_audio_session();
1171 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1172 return STTD_ERROR_OPERATION_FAILED;
1176 ret = sttd_engine_agent_recognize_stop_engine(uid);
1178 stt_client_unset_current_recognition();
1179 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1180 return STTD_ERROR_OPERATION_FAILED;
1183 /* change uid state */
1184 sttd_client_set_state(uid, APP_STATE_PROCESSING);
1186 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1188 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1190 return STTD_RESULT_STATE_DONE;
1193 return STTD_ERROR_NONE;
1196 int sttd_server_cancel(int uid)
1198 /* check if uid is valid */
1200 if (0 != sttd_client_get_state(uid, &state)) {
1201 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1202 return STTD_ERROR_INVALID_PARAMETER;
1205 /* check uid state */
1206 if (APP_STATE_READY == state) {
1207 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is ready");
1208 return STTD_ERROR_NONE;
1211 stt_client_unset_current_recognition();
1213 if (NULL != g_recording_timer) {
1214 ecore_timer_del(g_recording_timer);
1215 g_recording_timer = NULL;
1218 if (NULL != g_processing_timer) {
1219 ecore_timer_del(g_processing_timer);
1220 g_processing_timer = NULL;
1223 if (APP_STATE_RECORDING == state) {
1224 /* Unset audio session */
1225 int ret = sttd_recorder_unset_audio_session();
1227 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1228 return STTD_ERROR_OPERATION_FAILED;
1232 /* change uid state */
1233 sttd_client_set_state(uid, APP_STATE_READY);
1235 /* cancel engine recognition */
1236 int ret = sttd_engine_agent_recognize_cancel(uid);
1238 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1239 return STTD_ERROR_OPERATION_FAILED;
1242 return STTD_ERROR_NONE;