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 Eina_Bool g_stt_daemon_exist = EINA_TRUE;
39 static int g_recording_log_count = 0;
42 * STT Server Callback Functions
45 Eina_Bool sttd_get_daemon_exist()
47 return g_stt_daemon_exist;
50 Eina_Bool __stop_by_silence(void *data)
52 SLOG(LOG_DEBUG, TAG_STTD, "===== Stop by silence detection");
56 uid = stt_client_get_current_recognition();
60 ret = sttd_server_stop(uid);
65 if (STTD_RESULT_STATE_DONE == ret) {
66 ret = sttdc_send_set_state(uid, (int)APP_STATE_PROCESSING);
68 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send state : result(%d)", ret);
71 sttd_server_finalize(uid);
72 stt_client_unset_current_recognition();
76 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid is NOT valid");
79 SLOG(LOG_DEBUG, TAG_STTD, "=====");
80 SLOG(LOG_DEBUG, TAG_STTD, " ");
85 static void __cancel_recognition_internal()
87 if (NULL != g_recording_timer) {
88 ecore_timer_del(g_recording_timer);
89 g_recording_timer = NULL;
93 uid = stt_client_get_current_recognition();
96 /* cancel engine recognition */
97 int ret = sttd_engine_agent_recognize_cancel(uid);
99 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
102 /* change uid state */
103 sttd_client_set_state(uid, APP_STATE_READY);
104 stt_client_unset_current_recognition();
106 ret = sttdc_send_set_state(uid, (int)APP_STATE_READY);
108 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send state change : result(%d)", ret);
111 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid is NOT valid");
115 Eina_Bool __cancel_by_error(void *data)
117 SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by error");
119 __cancel_recognition_internal();
121 SLOG(LOG_DEBUG, TAG_STTD, "=====");
122 SLOG(LOG_DEBUG, TAG_STTD, " ");
127 int __server_audio_recorder_callback(const void* data, const unsigned int length)
132 if (NULL == data || 0 == length) {
133 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Recording data is not valid");
134 ecore_timer_add(0, __cancel_by_error, NULL);
138 uid = stt_client_get_current_recognition();
140 ret = sttd_engine_agent_set_recording_data(uid, data, length);
142 ecore_timer_add(0, __cancel_by_error, NULL);
145 g_recording_log_count++;
146 if (200 <= g_recording_log_count) {
147 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "=== Set recording data ===");
148 g_recording_log_count = 0;
151 if (NULL != g_recording_timer) {
152 ecore_timer_del(g_recording_timer);
153 g_recording_timer = NULL;
155 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current uid in recording is is not valid");
162 void __server_audio_interrupt_callback()
164 SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by sound interrupt");
166 __cancel_recognition_internal();
168 SLOG(LOG_DEBUG, TAG_STTD, "=====");
169 SLOG(LOG_DEBUG, TAG_STTD, " ");
172 Eina_Bool __cancel_by_no_record(void *data)
174 SLOG(LOG_DEBUG, TAG_STTD, "===== Cancel by no record");
176 __cancel_recognition_internal();
178 SLOG(LOG_DEBUG, TAG_STTD, "=====");
179 SLOG(LOG_DEBUG, TAG_STTD, " ");
184 void __server_recognition_result_callback(sttp_result_event_e event, const char* type,
185 const char** data, int data_count, const char* msg, void *user_data)
187 SLOG(LOG_DEBUG, TAG_STTD, "===== Recognition Result Callback");
190 int uid = stt_client_get_current_recognition();
193 if (0 == uid || 0 != sttd_client_get_state(uid, &state)) {
194 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
195 SLOG(LOG_DEBUG, TAG_STTD, "=====");
196 SLOG(LOG_DEBUG, TAG_STTD, " ");
200 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid (%d), event(%d)", uid, event);
202 /* send result to client */
203 if (STTP_RESULT_EVENT_FINAL_RESULT == event) {
204 if (APP_STATE_PROCESSING != state ) {
205 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is NOT 'Processing'.");
207 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] the size of result from engine is '%d'", data_count);
209 /* Delete timer for processing time out */
210 if (NULL != g_processing_timer) {
211 ecore_timer_del(g_processing_timer);
212 g_processing_timer = NULL;
215 sttd_config_time_save();
216 sttd_config_time_reset();
218 if (NULL == data || 0 == data_count) {
219 if (0 != sttdc_send_result(uid, event, NULL, 0, msg)) {
220 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
221 int reason = (int)STTD_ERROR_OPERATION_FAILED;
223 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
224 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
228 if (0 != sttdc_send_result(uid, event, data, data_count, msg)) {
229 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
230 int reason = (int)STTD_ERROR_OPERATION_FAILED;
232 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
233 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
238 /* change state of uid */
239 sttd_client_set_state(uid, APP_STATE_READY);
240 stt_client_unset_current_recognition();
242 } else if (STTP_RESULT_EVENT_PARTIAL_RESULT == event) {
243 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] The partial result from engine is event[%d] data_count[%d]", event, data_count);
245 sttd_config_time_save();
246 sttd_config_time_reset();
248 if (0 != sttdc_send_result(uid, event, data, data_count, msg)) {
249 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
250 int reason = (int)STTD_ERROR_OPERATION_FAILED;
252 if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
253 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
257 } else if (STTP_RESULT_EVENT_ERROR == event) {
258 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The event of recognition result is ERROR");
260 /* Delete timer for processing time out */
261 if (NULL != g_processing_timer) {
262 ecore_timer_del(g_processing_timer);
263 g_processing_timer = NULL;
265 sttd_config_time_reset();
267 if (0 != sttdc_send_result(uid, event, NULL, 0, msg)) {
268 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
271 int reason = (int)STTD_ERROR_INVALID_STATE;
272 if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
273 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
277 /* change state of uid */
278 sttd_client_set_state(uid, APP_STATE_READY);
279 stt_client_unset_current_recognition();
284 SLOG(LOG_DEBUG, TAG_STTD, "=====");
285 SLOG(LOG_DEBUG, TAG_STTD, " ");
290 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)
292 SLOG(LOG_DEBUG, TAG_STTD, "[Server] index(%d) event(%d) text(%s) start(%ld) end(%ld)",
293 index, event, text, start_time, end_time);
297 ret = sttd_config_time_add(index, (int)event, text, start_time, end_time);
299 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add time info");
309 void __server_silence_dectection_callback(sttp_silence_type_e type, void *user_param)
311 SLOG(LOG_DEBUG, TAG_STTD, "===== Silence Detection Callback");
313 int uid = stt_client_get_current_recognition();
316 if (0 != sttd_client_get_state(uid, &state)) {
317 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is not valid ");
321 if (APP_STATE_RECORDING != state) {
322 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
326 if (STTP_SILENCE_TYPE_NO_RECORD_TIMEOUT == type) {
327 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "Silence Detection type - No Record");
328 ecore_timer_add(0, __cancel_by_no_record, NULL);
329 } else if (STTP_SILENCE_TYPE_END_OF_SPEECH_DETECTED == type) {
330 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "Silence Detection type - End of Speech");
331 ecore_timer_add(0, __stop_by_silence, NULL);
334 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current recogntion uid is not valid ");
337 SLOG(LOG_DEBUG, TAG_STTD, "=====");
338 SLOG(LOG_DEBUG, TAG_STTD, " ");
343 void __sttd_server_engine_changed_cb(const char* engine_id, const char* language, bool support_silence, void* user_data)
345 if (NULL == engine_id) {
346 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Engine id is NULL");
349 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] New default engine : %s", engine_id);
352 /* need to change state of app to ready */
354 uid = stt_client_get_current_recognition();
357 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Server] Set ready state of uid(%d)", uid);
359 sttd_server_cancel(uid);
360 sttdc_send_set_state(uid, (int)APP_STATE_READY);
362 stt_client_unset_current_recognition();
366 int ret = sttd_engine_agent_set_default_engine(engine_id);
368 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : result(%d)", ret);
370 if (NULL != language) {
371 ret = sttd_engine_agent_set_default_language(language);
373 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%d)", ret);
376 ret = sttd_engine_agent_set_silence_detection(support_silence);
378 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret);
383 void __sttd_server_language_changed_cb(const char* language, void* user_data)
385 if (NULL == language) {
386 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] language is NULL");
389 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] Get language changed : %s", language);
392 int ret = sttd_engine_agent_set_default_language(language);
394 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%d)", ret);
399 void __sttd_server_silence_changed_cb(bool value, void* user_data)
401 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] Get silence detection changed : %s", value ? "on" : "off");
404 ret = sttd_engine_agent_set_silence_detection(value);
406 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret);
415 int sttd_initialize()
419 if (sttd_config_initialize(__sttd_server_engine_changed_cb, __sttd_server_language_changed_cb,
420 __sttd_server_silence_changed_cb, NULL)) {
421 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize config.");
424 ret = sttd_recorder_initialize(__server_audio_recorder_callback, __server_audio_interrupt_callback);
426 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize recorder : result(%d)", ret);
429 /* Engine Agent initialize */
430 ret = sttd_engine_agent_init(__server_recognition_result_callback, __server_result_time_callback,
431 __server_silence_dectection_callback);
433 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine agent initialize : result(%d)", ret);
437 /* Update engine list */
438 ret = sttd_engine_agent_initialize_engine_list();
440 if (STTD_ERROR_ENGINE_NOT_FOUND == ret) {
441 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] There is no stt engine");
443 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to update engine list : %d", ret);
448 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] initialize");
455 sttd_recorder_deinitialize();
457 sttd_config_finalize();
459 sttd_engine_agent_release();
461 return STTD_ERROR_NONE;
464 Eina_Bool sttd_cleanup_client(void *data)
466 int* client_list = NULL;
467 int client_count = 0;
471 if (0 != sttd_client_get_list(&client_list, &client_count)) {
472 if (NULL != client_list)
478 if (NULL != client_list) {
479 SLOG(LOG_DEBUG, TAG_STTD, "===== Clean up client ");
481 for (i = 0;i < client_count;i++) {
482 result = sttdc_send_hello(client_list[i]);
485 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", client_list[i]);
486 sttd_server_finalize(client_list[i]);
487 } else if (-1 == result) {
488 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Hello result has error");
492 SLOG(LOG_DEBUG, TAG_STTD, "=====");
493 SLOG(LOG_DEBUG, TAG_STTD, " ");
502 * STT Server Functions for Client
505 int sttd_server_initialize(int pid, int uid, bool* silence)
507 if (false == sttd_engine_agent_is_default_engine()) {
508 /* Update installed engine */
509 sttd_engine_agent_initialize_engine_list();
511 if (false == sttd_engine_agent_is_default_engine()) {
512 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] No stt-engine");
513 return STTD_ERROR_ENGINE_NOT_FOUND;
517 /* check if uid is valid */
519 if (0 == sttd_client_get_state(uid, &state)) {
520 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid has already been registered");
521 return STTD_ERROR_NONE;
525 if (0 != sttd_engine_agent_load_current_engine(uid, NULL)) {
526 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to load default engine");
527 return STTD_ERROR_OPERATION_FAILED;
530 if (0 != sttd_engine_agent_get_option_supported(uid, silence)) {
531 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine options supported");
532 return STTD_ERROR_OPERATION_FAILED;
535 /* Add client information to client manager */
536 if (0 != sttd_client_add(pid, uid)) {
537 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add client info");
538 return STTD_ERROR_OPERATION_FAILED;
541 return STTD_ERROR_NONE;
544 static Eina_Bool __quit_ecore_loop(void *data)
546 ecore_main_loop_quit();
550 int sttd_server_finalize(int uid)
552 /* check if uid is valid */
554 if (0 != sttd_client_get_state(uid, &state)) {
555 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
556 return STTD_ERROR_INVALID_PARAMETER;
559 /* release recorder */
560 if (APP_STATE_RECORDING == state || APP_STATE_PROCESSING == state) {
561 if (APP_STATE_RECORDING == state) {
562 if (NULL != g_recording_timer) {
563 ecore_timer_del(g_recording_timer);
564 g_recording_timer = NULL;
568 if (APP_STATE_PROCESSING == state) {
569 if (NULL != g_processing_timer) {
570 ecore_timer_del(g_processing_timer);
571 g_processing_timer = NULL;
575 if (0 != sttd_engine_agent_recognize_cancel(uid)) {
576 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognition");
579 stt_client_unset_current_recognition();
582 if (0 != sttd_engine_agent_unload_current_engine(uid)) {
583 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unload engine");
586 /* Remove client information */
587 if (0 != sttd_client_delete(uid)) {
588 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to delete client");
591 /* unload engine, if ref count of client is 0 */
592 if (0 == sttd_client_get_ref_count()) {
593 g_stt_daemon_exist = EINA_FALSE;
594 ecore_timer_add(0, __quit_ecore_loop, NULL);
597 return STTD_ERROR_NONE;
600 int sttd_server_get_supported_engines(int uid, GSList** engine_list)
602 /* Check if uid is valid */
604 if (0 != sttd_client_get_state(uid, &state)) {
605 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
606 return STTD_ERROR_INVALID_PARAMETER;
609 /* Check state of uid */
610 if (APP_STATE_READY != state) {
611 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
612 return STTD_ERROR_INVALID_STATE;
616 ret = sttd_engine_agent_get_engine_list(engine_list);
618 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine list");
619 return STTD_ERROR_OPERATION_FAILED;
622 return STTD_ERROR_NONE;
625 int sttd_server_set_current_engine(int uid, const char* engine_id, bool* silence)
627 /* Check if uid is valid */
629 if (0 != sttd_client_get_state(uid, &state)) {
630 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
631 return STTD_ERROR_INVALID_PARAMETER;
634 /* Check state of uid */
635 if (APP_STATE_READY != state) {
636 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
637 return STTD_ERROR_INVALID_STATE;
641 ret = sttd_engine_agent_load_current_engine(uid, engine_id);
643 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : %d", ret);
644 return STTD_ERROR_OPERATION_FAILED;
647 ret = sttd_engine_agent_get_option_supported(uid, silence);
649 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine options : %d", ret);
650 return STTD_ERROR_OPERATION_FAILED;
653 return STTD_ERROR_NONE;
656 int sttd_server_get_current_engine(int uid, char** engine_id)
658 /* Check if uid is valid */
660 if (0 != sttd_client_get_state(uid, &state)) {
661 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
662 return STTD_ERROR_INVALID_PARAMETER;
665 /* Check state of uid */
666 if (APP_STATE_READY != state) {
667 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
668 return STTD_ERROR_INVALID_STATE;
672 ret = sttd_engine_agent_get_current_engine(uid, engine_id);
674 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine : %d", ret);
675 return STTD_ERROR_OPERATION_FAILED;
678 return STTD_ERROR_NONE;
681 int sttd_server_check_agg_agreed(int uid, const char* appid, bool* available)
683 /* Check if uid is valid */
685 if (0 != sttd_client_get_state(uid, &state)) {
686 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
687 return STTD_ERROR_INVALID_PARAMETER;
690 /* Check state of uid */
691 if (APP_STATE_READY != state) {
692 SECURE_SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
693 return STTD_ERROR_INVALID_STATE;
696 /* Ask engine available */
699 ret = sttd_engine_agent_check_app_agreed(uid, appid, &temp);
701 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
702 return STTD_ERROR_OPERATION_FAILED;
706 stt_client_set_app_agreed(uid);
707 SLOG(LOG_DEBUG, TAG_STTD, "[Server] App(%s) confirmed that engine is available", appid);
712 return STTD_ERROR_NONE;
716 int sttd_server_get_supported_languages(int uid, GSList** lang_list)
718 /* check if uid is valid */
720 if (0 != sttd_client_get_state(uid, &state)) {
721 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
722 return STTD_ERROR_INVALID_PARAMETER;
725 /* get language list from engine */
726 int ret = sttd_engine_agent_supported_langs(uid, lang_list);
728 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get supported languages");
729 return STTD_ERROR_OPERATION_FAILED;
732 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] sttd_server_get_supported_languages");
734 return STTD_ERROR_NONE;
737 int sttd_server_get_current_langauage(int uid, char** current_lang)
739 /* check if uid is valid */
741 if (0 != sttd_client_get_state(uid, &state)) {
742 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
743 return STTD_ERROR_INVALID_PARAMETER;
746 if (NULL == current_lang) {
747 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
748 return STTD_ERROR_INVALID_PARAMETER;
751 /*get current language from engine */
752 int ret = sttd_engine_agent_get_default_lang(uid, current_lang);
754 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get default language :result(%d)", ret);
755 return STTD_ERROR_OPERATION_FAILED;
758 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Get default language");
760 return STTD_ERROR_NONE;
763 int sttd_server_is_recognition_type_supported(int uid, const char* type, int* support)
765 /* check if uid is valid */
767 if (0 != sttd_client_get_state(uid, &state)) {
768 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
769 return STTD_ERROR_INVALID_PARAMETER;
772 if (NULL == type || NULL == support) {
773 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
774 return STTD_ERROR_INVALID_PARAMETER;
778 int ret = sttd_engine_agent_is_recognition_type_supported(uid, type, &temp);
780 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get recognition type supported : result(%d)", ret);
781 return STTD_ERROR_OPERATION_FAILED;
784 *support = (int)temp;
786 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] recognition type supporting is %s", *support ? "true" : "false");
788 return STTD_ERROR_NONE;
791 int sttd_server_set_start_sound(int uid, const char* file)
793 /* check if uid is valid */
795 if (0 != sttd_client_get_state(uid, &state)) {
796 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
797 return STTD_ERROR_INVALID_PARAMETER;
800 int ret = sttd_client_set_start_sound(uid, file);
802 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
803 return STTD_ERROR_OPERATION_FAILED;
809 int sttd_server_set_stop_sound(int uid, const char* file)
811 /* check if uid is valid */
813 if (0 != sttd_client_get_state(uid, &state)) {
814 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
815 return STTD_ERROR_INVALID_PARAMETER;
818 int ret = sttd_client_set_stop_sound(uid, file);
820 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
821 return STTD_ERROR_OPERATION_FAILED;
827 Eina_Bool __check_recording_state(void *data)
830 int uid = stt_client_get_current_recognition();
835 if (0 != sttdc_send_get_state(uid, (int*)&state)) {
836 /* client is removed */
837 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", uid);
838 sttd_server_finalize(uid);
842 if (APP_STATE_READY == state) {
844 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Ready'. The daemon should cancel recording", uid);
845 sttd_server_cancel(uid);
846 } else if (APP_STATE_PROCESSING == state) {
847 /* Cancel stt and send change state */
848 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Processing'. The daemon should cancel recording", uid);
849 sttd_server_cancel(uid);
850 sttdc_send_set_state(uid, (int)APP_STATE_READY);
853 SLOG(LOG_DEBUG, TAG_STTD, "[Server] The states of daemon and client are identical");
860 Eina_Bool __stop_by_recording_timeout(void *data)
862 SLOG(LOG_DEBUG, TAG_STTD, "===== Stop by timeout");
864 g_recording_timer = NULL;
867 uid = stt_client_get_current_recognition();
869 /* cancel engine recognition */
870 int ret = sttd_server_stop(uid);
872 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop : result(%d)", ret);
876 SLOG(LOG_DEBUG, TAG_STTD, "=====");
877 SLOG(LOG_DEBUG, TAG_STTD, " ");
882 void __sttd_server_recorder_start(int uid)
884 int current_uid = stt_client_get_current_recognition();
886 if (uid != current_uid) {
887 stt_client_unset_current_recognition();
891 int ret = sttd_engine_agent_recognize_start_recorder(uid);
893 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
897 /* Notify uid state change */
898 sttdc_send_set_state(uid, APP_STATE_RECORDING);
900 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
903 void __sttd_start_sound_completed_cb(int id, void *user_data)
905 SLOG(LOG_DEBUG, TAG_STTD, "===== Start sound completed");
907 int uid = (int)user_data;
908 /* 4. after wav play callback, recorder start */
909 __sttd_server_recorder_start(uid);
911 SLOG(LOG_DEBUG, TAG_STTD, "=====");
912 SLOG(LOG_DEBUG, TAG_STTD, " ");
916 int sttd_server_start(int uid, const char* lang, const char* recognition_type, int silence, const char* appid)
918 if (NULL == lang || NULL == recognition_type) {
919 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
920 return STTD_ERROR_INVALID_PARAMETER;
923 /* check if uid is valid */
925 if (0 != sttd_client_get_state(uid, &state)) {
926 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
927 return STTD_ERROR_INVALID_PARAMETER;
930 /* check uid state */
931 if (APP_STATE_READY != state) {
932 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] sttd_server_start : current state is not ready");
933 return STTD_ERROR_INVALID_STATE;
937 if (false == stt_client_get_app_agreed(uid)) {
939 ret = sttd_engine_agent_check_app_agreed(uid, appid, &temp);
941 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
942 return STTD_ERROR_OPERATION_FAILED;
946 SLOG(LOG_ERROR, TAG_STTD, "[Server] App(%s) NOT confirmed that engine is available", appid);
947 return STTD_ERROR_PERMISSION_DENIED;
950 stt_client_set_app_agreed(uid);
953 /* check if engine use network */
954 if (true == sttd_engine_agent_need_network(uid)) {
955 if (false == stt_network_is_connected()) {
956 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Disconnect network. Current engine needs to network connection.");
957 return STTD_ERROR_OUT_OF_NETWORK;
962 if (0 != sttd_client_get_start_sound(uid, &sound)) {
963 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
964 return STTD_ERROR_OPERATION_FAILED;
967 if (0 != stt_client_set_current_recognition(uid)) {
968 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT is busy because of recording or processing");
969 if (NULL != sound) free(sound);
970 return STTD_ERROR_RECORDER_BUSY;
973 /* engine start recognition */
974 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] start : uid(%d), lang(%s), recog_type(%s)",
975 uid, lang, recognition_type);
977 SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] start sound : %s", sound);
979 /* 1. Set audio session */
980 ret = sttd_recorder_set_audio_session();
982 stt_client_unset_current_recognition();
983 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set session : %d", ret);
984 if (NULL != sound) free(sound);
988 bool is_sound_done = false;
990 /* 2. Request wav play */
993 ret = wav_player_start(sound, SOUND_TYPE_MEDIA, __sttd_start_sound_completed_cb, (void*)uid, &id);
994 if (WAV_PLAYER_ERROR_NONE != ret) {
995 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
996 is_sound_done = true;
1001 is_sound_done = true;
1004 /* 3. Create recorder & engine initialize */
1005 ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, NULL);
1007 stt_client_unset_current_recognition();
1008 sttd_recorder_unset_audio_session();
1009 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
1013 if (0 != strcmp(STTP_RECOGNITION_TYPE_FREE_PARTIAL, recognition_type)) {
1014 g_recording_timer = ecore_timer_add(g_recording_timeout, __stop_by_recording_timeout, NULL);
1017 /* change uid state */
1018 sttd_client_set_state(uid, APP_STATE_RECORDING);
1020 g_recording_log_count = 0;
1022 if (true == is_sound_done) {
1023 SLOG(LOG_DEBUG, TAG_STTD, "[Server] No sound play");
1025 ret = sttd_engine_agent_recognize_start_recorder(uid);
1027 stt_client_unset_current_recognition();
1028 sttd_recorder_unset_audio_session();
1030 sttd_engine_agent_recognize_cancel(uid);
1031 ecore_timer_del(g_recording_timer);
1032 sttd_client_set_state(uid, APP_STATE_READY);
1034 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
1035 return STTD_ERROR_OPERATION_FAILED;
1038 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
1039 return STTD_RESULT_STATE_DONE;
1042 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Wait sound finish");
1044 return STTD_RESULT_STATE_NOT_DONE;
1047 Eina_Bool __time_out_for_processing(void *data)
1049 g_processing_timer = NULL;
1052 int uid = stt_client_get_current_recognition();
1053 if (0 == uid) return EINA_FALSE;
1056 int ret = sttd_engine_agent_recognize_cancel(uid);
1058 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1061 if (0 != sttdc_send_result(uid, STTP_RESULT_EVENT_FINAL_RESULT, NULL, 0, "Time out not to receive recognition result.")) {
1062 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
1064 /* send error msg */
1065 int reason = (int)STTD_ERROR_TIMED_OUT;
1066 if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
1067 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
1071 /* Change uid state */
1072 sttd_client_set_state(uid, APP_STATE_READY);
1074 stt_client_unset_current_recognition();
1079 void __sttd_server_engine_stop(int uid)
1081 /* change uid state */
1082 sttd_client_set_state(uid, APP_STATE_PROCESSING);
1084 /* Notify uid state change */
1085 sttdc_send_set_state(uid, APP_STATE_PROCESSING);
1087 /* Unset audio session */
1088 int ret = sttd_recorder_unset_audio_session();
1090 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1095 ret = sttd_engine_agent_recognize_stop_engine(uid);
1097 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1101 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1104 void __sttd_stop_sound_completed_cb(int id, void *user_data)
1106 SLOG(LOG_DEBUG, TAG_STTD, "===== Stop sound completed");
1108 int uid = (int)user_data;
1109 /* After wav play callback, engine stop */
1110 __sttd_server_engine_stop(uid);
1112 SLOG(LOG_DEBUG, TAG_STTD, "=====");
1113 SLOG(LOG_DEBUG, TAG_STTD, " ");
1117 int sttd_server_stop(int uid)
1119 /* check if uid is valid */
1121 if (0 != sttd_client_get_state(uid, &state)) {
1122 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1123 return STTD_ERROR_INVALID_PARAMETER;
1126 /* check uid state */
1127 if (APP_STATE_RECORDING != state) {
1128 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
1129 return STTD_ERROR_INVALID_STATE;
1132 if (NULL != g_recording_timer) {
1133 ecore_timer_del(g_recording_timer);
1134 g_recording_timer = NULL;
1138 if (0 != sttd_client_get_stop_sound(uid, &sound)) {
1139 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
1140 return STTD_ERROR_OPERATION_FAILED;
1143 SLOG(LOG_DEBUG, TAG_STTD, "[Server] stop sound path : %s", sound);
1146 /* 1. Stop recorder */
1147 ret = sttd_engine_agent_recognize_stop_recorder(uid);
1149 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop recorder : result(%d)", ret);
1150 if (0 != sttd_engine_agent_recognize_cancel(uid)) {
1151 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognize");
1153 if (NULL != sound) free(sound);
1154 return STTD_ERROR_OPERATION_FAILED;
1157 /* 2. Request wav play */
1158 if (NULL != sound) {
1160 ret = wav_player_start(sound, SOUND_TYPE_MEDIA, __sttd_stop_sound_completed_cb, (void*)uid, &id);
1161 if (WAV_PLAYER_ERROR_NONE != ret) {
1162 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
1164 SLOG(LOG_DEBUG, TAG_STTD, "[Server] Play wav : %s", sound);
1169 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1171 return STTD_RESULT_STATE_NOT_DONE;
1173 SLOG(LOG_DEBUG, TAG_STTD, "[Server] No sound play");
1175 /* Unset audio session */
1176 ret = sttd_recorder_unset_audio_session();
1178 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1179 return STTD_ERROR_OPERATION_FAILED;
1183 ret = sttd_engine_agent_recognize_stop_engine(uid);
1185 stt_client_unset_current_recognition();
1186 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
1187 return STTD_ERROR_OPERATION_FAILED;
1190 /* change uid state */
1191 sttd_client_set_state(uid, APP_STATE_PROCESSING);
1193 SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
1195 g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
1197 return STTD_RESULT_STATE_DONE;
1200 return STTD_ERROR_NONE;
1203 int sttd_server_cancel(int uid)
1205 /* check if uid is valid */
1207 if (0 != sttd_client_get_state(uid, &state)) {
1208 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
1209 return STTD_ERROR_INVALID_PARAMETER;
1212 /* check uid state */
1213 if (APP_STATE_READY == state) {
1214 SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is ready");
1215 return STTD_ERROR_NONE;
1218 stt_client_unset_current_recognition();
1220 if (NULL != g_recording_timer) {
1221 ecore_timer_del(g_recording_timer);
1222 g_recording_timer = NULL;
1225 if (NULL != g_processing_timer) {
1226 ecore_timer_del(g_processing_timer);
1227 g_processing_timer = NULL;
1230 if (APP_STATE_RECORDING == state) {
1231 /* Unset audio session */
1232 int ret = sttd_recorder_unset_audio_session();
1234 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
1235 return STTD_ERROR_OPERATION_FAILED;
1239 /* change uid state */
1240 sttd_client_set_state(uid, APP_STATE_READY);
1242 /* cancel engine recognition */
1243 int ret = sttd_engine_agent_recognize_cancel(uid);
1245 SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
1246 return STTD_ERROR_OPERATION_FAILED;
1249 return STTD_ERROR_NONE;