#include "sttd_recorder.h"
#include "sttd_server.h"
+
+#define CLIENT_CLEAN_UP_TIME 500
+
+
static pthread_mutex_t stte_result_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t stte_result_time_mutex = PTHREAD_MUTEX_INITIALIZER;
static double g_recording_timeout = 60;
+static Ecore_Timer* g_check_client_timer = NULL;
Ecore_Timer* g_recording_timer = NULL;
Ecore_Timer* g_processing_timer = NULL;
g_recording_timer = NULL;
}
+ int ret = 0;
int uid = 0;
uid = stt_client_get_current_recognition();
- if (0 != uid) {
- /* cancel engine recognition */
- int ret = sttd_engine_agent_recognize_cancel();
- if (0 != ret) {
- SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
- }
+ app_state_e state = 0;
+ ret = sttd_client_get_state(uid, &state);
- /* change uid state */
- sttd_client_set_state(uid, APP_STATE_READY);
- stt_client_unset_current_recognition();
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
+ return;
+ }
- ret = sttdc_send_set_state(uid, (int)APP_STATE_READY);
+ if (0 != uid && (APP_STATE_PROCESSING == state || APP_STATE_RECORDING == state)) {
+ /* cancel engine recognition */
+ ret = sttd_server_cancel(uid);
if (0 != ret) {
- SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send state change : result(%d)", ret);
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
}
} else {
SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid is NOT valid");
return;
}
-void __server_recognition_result_callback(stte_result_event_e event, const char* type,
+int __server_recognition_result_callback(stte_result_event_e event, const char* type,
const char** data, int data_count, const char* msg, void *user_data)
{
// critical section
SLOG(LOG_DEBUG, TAG_STTD, "=====");
SLOG(LOG_DEBUG, TAG_STTD, " ");
pthread_mutex_unlock(&stte_result_mutex);
- return;
+ return STTD_ERROR_OPERATION_FAILED;
}
SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid (%d), event(%d)", uid, event);
sttd_config_time_save();
sttd_config_time_reset();
+ sttd_recorder_reset();
+
+ sttd_client_set_state(uid, APP_STATE_READY);
+ stt_client_unset_current_recognition();
+
if (NULL == data || 0 == data_count) {
if (0 != sttdc_send_result(uid, event, NULL, 0, msg)) {
SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
}
/* change state of uid */
- sttd_client_set_state(uid, APP_STATE_READY);
- stt_client_unset_current_recognition();
+// sttd_client_set_state(uid, APP_STATE_READY);
+// stt_client_unset_current_recognition();
} else if (STTE_RESULT_EVENT_PARTIAL_RESULT == event) {
SLOG(LOG_DEBUG, TAG_STTD, "[Server] The partial result from engine is event[%d] data_count[%d]", event, data_count);
}
sttd_config_time_reset();
+ int ret = 0;
+ if (APP_STATE_RECORDING == state) {
+ ret = sttd_engine_agent_recognize_cancel();
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel: result(%d)", ret);
+ }
+ }
+
+ sttd_client_set_state(uid, APP_STATE_READY);
+ stt_client_unset_current_recognition();
+
if (0 != sttdc_send_result(uid, event, NULL, 0, msg)) {
SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
}
/* change state of uid */
- sttd_client_set_state(uid, APP_STATE_READY);
- stt_client_unset_current_recognition();
+// sttd_client_set_state(uid, APP_STATE_READY);
+// stt_client_unset_current_recognition();
} else {
/* nothing */
}
SLOG(LOG_DEBUG, TAG_STTD, " ");
pthread_mutex_unlock(&stte_result_mutex);
- return;
+ return STTD_ERROR_NONE;
}
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)
{
pthread_mutex_lock(&stte_result_time_mutex);
- SLOG(LOG_DEBUG, TAG_STTD, "[Server] index(%d) event(%d) text(%s) start(%ld) end(%ld)",
+ SECURE_SLOG(LOG_DEBUG, TAG_STTD, "[Server] index(%d) event(%d) text(%s) start(%ld) end(%ld)",
index, event, text, start_time, end_time);
- if (0 == index) {
- int ret;
- ret = sttd_config_time_add(index, (int)event, text, start_time, end_time);
- if (0 != ret) {
- SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add time info");
- pthread_mutex_unlock(&stte_result_time_mutex);
- return false;
- }
- } else {
+ int ret;
+ ret = sttd_config_time_add(index, (int)event, text, start_time, end_time);
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add time info");
pthread_mutex_unlock(&stte_result_time_mutex);
return false;
}
return true;
}
-void __server_speech_status_callback(stte_speech_status_e status, void *user_param)
+int __server_speech_status_callback(stte_speech_status_e status, void *user_param)
{
SLOG(LOG_DEBUG, TAG_STTD, "===== Speech status detected Callback");
app_state_e state;
if (0 != sttd_client_get_state(uid, &state)) {
SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is not valid ");
- return;
+ return STTD_ERROR_OPERATION_FAILED;
}
- if (APP_STATE_RECORDING != state) {
- SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
- return;
+ if (APP_STATE_RECORDING != state && APP_STATE_PROCESSING != state) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording, state(%d), status(%d)", state, status);
+ return STTD_ERROR_INVALID_STATE;
}
if (STTE_SPEECH_STATUS_BEGINNING_POINT_DETECTED == status) {
SLOG(LOG_DEBUG, TAG_STTD, "Begin Speech detected");
+ sttdc_send_speech_status(uid, status);
} else if (STTE_SPEECH_STATUS_END_POINT_DETECTED == status) {
SLOG(LOG_DEBUG, TAG_STTD, "End Speech detected");
ecore_main_loop_thread_safe_call_async(__stop_by_silence, NULL);
SLOG(LOG_DEBUG, TAG_STTD, "=====");
SLOG(LOG_DEBUG, TAG_STTD, " ");
- return;
+ return STTD_ERROR_NONE;
}
-void __server_error_callback(stte_error_e error, const char* msg)
+int __server_error_callback(stte_error_e error, const char* msg)
{
SLOG(LOG_DEBUG, TAG_STTD, "[Server] Error Callback is called");
- return;
+ ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
+
+ return STTD_ERROR_NONE;
}
void __sttd_server_engine_changed_cb(const char* engine_id, const char* language, bool support_silence, bool need_credential, void* user_data)
SLOG(LOG_DEBUG, TAG_STTD, "[Server] New default engine : %s", engine_id);
}
+#if 0
/* need to change state of app to ready */
int uid;
uid = stt_client_get_current_recognition();
ret = sttd_engine_agent_set_silence_detection(support_silence);
if (0 != ret)
SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret);
+#endif
return;
}
/*
* Daemon function
*/
-
-static void __sig_handler(int signo)
-{
- /* restore signal handler */
- signal(signo, SIG_DFL);
-
- /* Send error signal to clients */
- int* client_list = NULL;
- int client_count = 0;
- int i = 0;
- if (0 != sttd_client_get_list(&client_list, &client_count)) {
- if (NULL != client_list) {
- free(client_list);
- client_list = NULL;
- }
- }
-
- if (NULL != client_list) {
- for (i = 0; i < client_count; i++) {
- sttdc_send_error_signal(client_list[i], STTD_ERROR_SERVICE_RESET, "Service Reset");
- }
-
- free(client_list);
- client_list = NULL;
- }
-
- /* invoke signal again */
- raise(signo);
-}
-
-static void __register_sig_handler()
-{
- signal(SIGSEGV, __sig_handler);
- signal(SIGABRT, __sig_handler);
- signal(SIGTERM, __sig_handler);
- signal(SIGINT, __sig_handler);
- signal(SIGQUIT, __sig_handler);
-}
-
int sttd_initialize(stte_request_callback_s *callback)
{
int ret = 0;
- __register_sig_handler();
-
if (0 != pthread_mutex_init(&stte_result_mutex, NULL)) {
SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize stte result mutex.");
}
return ret;
}
+ g_check_client_timer = ecore_timer_add(CLIENT_CLEAN_UP_TIME, sttd_cleanup_client, NULL);
+ if (NULL == g_check_client_timer) {
+ SLOG(LOG_WARN, TAG_STTD, "[Main Warning] Fail to create timer of client check");
+ }
+
SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] initialize");
return 0;
sttd_engine_agent_release();
+ if (NULL != g_check_client_timer) {
+ ecore_timer_del(g_check_client_timer);
+ g_check_client_timer = NULL;
+
+ SLOG(LOG_INFO, TAG_STTD, "[INFO] Delete ecore timer handle");
+ }
+
return STTD_ERROR_NONE;
}
static void __read_proc()
{
DIR *dp = NULL;
- struct dirent entry;
struct dirent *dirp = NULL;
- int ret = -1;
int tmp;
GList *iter = NULL;
SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to open proc");
} else {
do {
- ret = readdir_r(dp, &entry, &dirp);
- if (0 != ret) {
- SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to readdir");
- break;
- }
+ dirp = readdir(dp);
if (NULL != dirp) {
tmp = atoi(dirp->d_name);
stt_network_finalize();
sttd_finalize();
+ sttd_dbus_close_connection();
ecore_main_loop_quit();
SLOG(LOG_DEBUG, TAG_STTD, "");
return STTD_ERROR_NONE;
}
+
+int sttd_server_start_file(int uid, const char* lang, const char* recognition_type, int silence, const char* appid, const char* credential,
+ const char* filepath, stte_audio_type_e audio_type, int sample_rate)
+{
+ if (NULL == lang || NULL == recognition_type || NULL == filepath) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
+ return STTD_ERROR_INVALID_PARAMETER;
+ }
+
+ /* check if uid is valid */
+ app_state_e state;
+ if (0 != sttd_client_get_state(uid, &state)) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
+ return STTD_ERROR_INVALID_PARAMETER;
+ }
+
+ /* check uid state */
+ if (APP_STATE_READY != state) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] sttd_server_start : current state is not ready");
+ return STTD_ERROR_INVALID_STATE;
+ }
+
+ int ret = 0;
+ if (false == stt_client_get_app_agreed(uid)) {
+ bool temp = false;
+ ret = sttd_engine_agent_check_app_agreed(appid, &temp);
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine available : %d", ret);
+ return ret;
+ }
+
+ if (false == temp) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server] App(%s) NOT confirmed that engine is available", appid);
+ return STTD_ERROR_PERMISSION_DENIED;
+ }
+
+ stt_client_set_app_agreed(uid);
+ }
+
+ /* check if engine use network */
+ if (true == sttd_engine_agent_need_network()) {
+ if (false == stt_network_is_connected()) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Disconnect network. Current engine needs to network connection.");
+ return STTD_ERROR_OUT_OF_NETWORK;
+ }
+ }
+
+ if (0 != stt_client_set_current_recognition(uid)) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT is busy because of recording or processing");
+ return STTD_ERROR_RECORDER_BUSY;
+ }
+
+ /* engine start recognition */
+ 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);
+
+ /* 1. Set audio session */
+ ret = sttd_recorder_set_audio_session();
+ if (0 != ret) {
+ stt_client_unset_current_recognition();
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set session : %d", ret);
+ return ret;
+ }
+
+ /* 2. Start engine to recognize */
+ ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, appid, credential, NULL);
+ if (0 != ret) {
+ stt_client_unset_current_recognition();
+ sttd_recorder_unset_audio_session();
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start engine : result(%d)", ret);
+ return ret;
+ }
+
+ sttd_client_set_state(uid, APP_STATE_RECORDING);
+ sttdc_send_set_state(uid, APP_STATE_RECORDING);
+
+ /* 3. Start to send pcm from file to engine */
+ ret = sttd_engine_agent_recognize_start_file(uid, filepath);
+ if (0 != ret) {
+ stt_client_unset_current_recognition();
+ sttd_recorder_unset_audio_session();
+ sttd_engine_agent_recognize_cancel();
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start file : result(%d)", ret);
+ return ret;
+ }
+
+ /* 4. Stop to send pcm from file */
+ ret = sttd_engine_agent_recognize_stop_file();
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop recorder : result(%d)", ret);
+ stt_client_unset_current_recognition();
+ sttd_recorder_unset_audio_session();
+ sttd_engine_agent_recognize_cancel();
+ return ret;
+ }
+
+ /* 5. change & notify uid state */
+ sttd_client_set_state(uid, APP_STATE_PROCESSING);
+ sttdc_send_set_state(uid, APP_STATE_PROCESSING);
+
+ /* 6. Unset audio session */
+ ret = sttd_recorder_unset_audio_session();
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
+ stt_client_unset_current_recognition();
+ return ret;
+ }
+
+ /* 7. Stop engine */
+ ret = sttd_engine_agent_recognize_stop_engine();
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
+ stt_client_unset_current_recognition();
+ return ret;
+ }
+
+ return STTD_ERROR_NONE;
+}
+
+int sttd_server_cancel_file(int uid)
+{
+ /* check if uid is valid */
+ app_state_e state;
+ if (0 != sttd_client_get_state(uid, &state)) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
+ return STTD_ERROR_INVALID_PARAMETER;
+ }
+
+ /* check uid state */
+ if (APP_STATE_READY == state) {
+ SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is ready");
+ return STTD_ERROR_NONE;
+ }
+
+ stt_client_unset_current_recognition();
+
+ if (NULL != g_recording_timer) {
+ ecore_timer_del(g_recording_timer);
+ g_recording_timer = NULL;
+ }
+
+ if (NULL != g_processing_timer) {
+ ecore_timer_del(g_processing_timer);
+ g_processing_timer = NULL;
+ }
+
+ if (APP_STATE_RECORDING == state) {
+ /* Unset audio session */
+ int ret = sttd_recorder_unset_audio_session();
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unset session : %d", ret);
+ return ret;
+ }
+ }
+
+ /* change uid state */
+ sttd_client_set_state(uid, APP_STATE_READY);
+
+ /* cancel engine recognition */
+ int ret = sttd_engine_agent_recognize_cancel();
+ if (0 != ret) {
+ SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
+ return ret;
+ }
+
+ /* Notify uid state change */
+ sttdc_send_set_state(uid, APP_STATE_READY);
+
+ return STTD_ERROR_NONE;
+}