Delete processing timer at main thread
[platform/core/uifw/stt.git] / server / sttd_server.c
old mode 100755 (executable)
new mode 100644 (file)
index d5511b9..ccaf29d
@@ -1,5 +1,5 @@
 /*
-*  Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd All Rights Reserved 
+*  Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *  limitations under the License.
 */
 
+#include <pthread.h>
+#include <sound_manager.h>
+#include <wav_player.h>
 
-#include "sttd_main.h"
-#include "sttd_server.h"
-
+#include "stt_network.h"
 #include "sttd_client_data.h"
-#include "sttd_engine_agent.h"
 #include "sttd_config.h"
-#include "sttd_recorder.h"
-#include "sttd_network.h"
 #include "sttd_dbus.h"
+#include "sttd_engine_agent.h"
+#include "sttd_main.h"
+#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;
+
 
 /*
 * STT Server static variable
 */
-static bool g_is_engine;
+static double g_processing_timeout = 30;
+
+static double g_recording_timeout = 60;
 
-static double g_state_check_time = 15.5;
+static Ecore_Timer* g_check_client_timer = NULL;
+Ecore_Timer*   g_recording_timer = NULL;
+Ecore_Timer*   g_processing_timer = NULL;
+
+static int g_recording_log_count = 0;
+
+static GList *g_proc_list = NULL;
 
 /*
-* STT Server Callback Functions                                                                                        `                                 *
+* STT Server Callback Functions
 */
+void __stop_by_silence(void *data)
+{
+       SLOG(LOG_INFO, TAG_STTD, "===== Stop by silence detection");
+
+       int uid = 0;
+
+       uid = stt_client_get_current_recognition();
+
+       int ret;
+       if (0 != uid) {
+               ret = sttd_server_stop(uid);
+               if (0 > ret) {
+                       return;
+               }
+
+               if (STTD_RESULT_STATE_DONE == ret) {
+                       ret = sttdc_send_set_state(uid, (int)APP_STATE_PROCESSING);
+                       if (0 != ret) {
+                               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send state : result(%d)", ret);
+
+                               /* Remove client */
+                               sttd_server_finalize(uid);
+                               stt_client_unset_current_recognition();
+                       }
+               }
+       } else {
+               SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid is NOT valid");
+       }
+
+       SLOG(LOG_INFO, TAG_STTD, "=====");
+       SLOG(LOG_DEBUG, TAG_STTD, "  ");
+
+       return;
+}
 
-Eina_Bool __stop_by_silence(void *data)
+static void __cancel_recognition_internal()
 {
-       SLOG(LOG_DEBUG, TAG_STTD, "===== Stop by silence detection");
+       if (NULL != g_recording_timer)  {
+               ecore_timer_del(g_recording_timer);
+               g_recording_timer = NULL;
+       }
 
+       int ret = 0;
        int uid = 0;
+       uid = stt_client_get_current_recognition();
 
-       uid = sttd_client_get_current_recording();
+       app_state_e state = 0;
+       ret = sttd_client_get_state(uid, &state);
 
-       if (uid > 0) {
-               if (0 != sttd_server_stop(uid))
-                       return EINA_FALSE;
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
+               return;
+       }
 
-               int ret = sttdc_send_set_state(uid, (int)APP_STATE_PROCESSING);
+       if (0 != uid && (APP_STATE_PROCESSING == state || APP_STATE_RECORDING == state)) {
+               SLOG(LOG_INFO, TAG_STTD, "===== cancel by internal");
+               /* cancel engine recognition */
+               ret = sttd_server_cancel(uid);
                if (0 != ret) {
-                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send state : result(%d)", ret); 
-
-                       /* Remove client */
-                       sttd_server_finalize(uid);
-               }       
+                       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");
        }
+}
+
+static void __cancel_by_error(void *data)
+{
+       SLOG(LOG_INFO, TAG_STTD, "===== Cancel by error");
+
+       __cancel_recognition_internal();
 
        SLOG(LOG_DEBUG, TAG_STTD, "=====");
        SLOG(LOG_DEBUG, TAG_STTD, "  ");
 
-       return EINA_FALSE;
+       return;
 }
 
-int audio_recorder_callback(const void* data, const unsigned int length)
+int __server_audio_recorder_callback(const void* data, const unsigned int length)
 {
-       if (0 != sttd_engine_recognize_audio(data, length)) {
-               int uid = sttd_client_get_current_recording();
+       int uid = -1;
+       int ret;
 
-               app_state_e state;
-               if (0 != sttd_client_get_state(uid, &state)) {
-                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is not valid "); 
-                       return -1;
-               }
+       if (NULL == data || 0 == length) {
+               SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Recording data is not valid");
+               ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
+               return -1;
+       }
 
-               if (APP_STATE_RECORDING != state) {
-                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording"); 
+       uid = stt_client_get_current_recognition();
+       if (0 != uid) {
+               ret = sttd_engine_agent_set_recording_data(data, length);
+               if (ret < 0) {
+                       ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
                        return -1;
                }
-
-               ecore_timer_add(0, __stop_by_silence, NULL);
-
-               /*if (0 != sttd_send_stop_recognition_by_daemon(uid)) {
-                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail "); 
-               } else {
-                       SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] <<<< stop message : uid(%d)", uid); 
-               }*/
-               
+               g_recording_log_count++;
+               if (200 <= g_recording_log_count) {
+                       SLOG(LOG_DEBUG, TAG_STTD, "=== Set recording data ===");
+                       g_recording_log_count = 0;
+               }
+       } else {
+               if (NULL != g_recording_timer)  {
+                       ecore_timer_del(g_recording_timer);
+                       g_recording_timer = NULL;
+               }
+               SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current uid in recording is is not valid");
                return -1;
        }
 
        return 0;
 }
 
-void sttd_server_recognition_result_callback(sttp_result_event_e event, const char* type, 
+void __server_audio_interrupt_callback()
+{
+       SLOG(LOG_INFO, TAG_STTD, "===== Cancel by sound interrupt");
+
+       __cancel_recognition_internal();
+
+       SLOG(LOG_DEBUG, TAG_STTD, "=====");
+       SLOG(LOG_DEBUG, TAG_STTD, "  ");
+}
+
+void __cancel_by_no_record(void *data)
+{
+       SLOG(LOG_INFO, TAG_STTD, "===== Cancel by no record");
+
+       __cancel_recognition_internal();
+
+       SLOG(LOG_DEBUG, TAG_STTD, "=====");
+       SLOG(LOG_DEBUG, TAG_STTD, "  ");
+
+       return;
+}
+
+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)
 {
-       SLOG(LOG_DEBUG, TAG_STTD, "===== Recognition Result Callback");
+       // critical section
+       pthread_mutex_lock(&stte_result_mutex);
 
-       if (NULL == user_data) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] user data is NULL"); 
-               SLOG(LOG_DEBUG, TAG_STTD, "=====");
-               SLOG(LOG_DEBUG, TAG_STTD, "  ");
-               return;
-       }
+       SLOG(LOG_INFO, TAG_STTD, "===== RESULT event[%d] type[%s] data[%p] data_count[%d]", event, type, data, data_count);
 
        /* check uid */
-       int *uid = (int*)user_data;
-
-       SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid (%d), event(%d)", *uid, event); 
+       int uid = stt_client_get_current_recognition();
 
        app_state_e state;
-       if (0 != sttd_client_get_state(*uid, &state)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid "); 
+       if (0 == uid || 0 != sttd_client_get_state(uid, &state)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
                SLOG(LOG_DEBUG, TAG_STTD, "=====");
                SLOG(LOG_DEBUG, TAG_STTD, "  ");
-               return;
+               pthread_mutex_unlock(&stte_result_mutex);
+               return STTD_ERROR_OPERATION_FAILED;
        }
 
-       /* Delete timer for processing time out */
-       Ecore_Timer* timer;
-       sttd_cliet_get_timer(*uid, &timer);
-
-       if (NULL != timer)
-               ecore_timer_del(timer);
+       SLOG(LOG_INFO, TAG_STTD, "[Server] uid (%d), event(%d)", uid, event);
 
        /* send result to client */
-       if (STTP_RESULT_EVENT_SUCCESS == event && 0 < data_count && NULL != data) {
+       if (STTE_RESULT_EVENT_FINAL_RESULT == event) {
+               if (APP_STATE_PROCESSING != state) {
+                       SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is NOT 'Processing'.");
+               }
+               SLOG(LOG_INFO, TAG_STTD, "[Server] the size of result from engine is '%d'", data_count);
+
+               /* Delete timer for processing time out */
+               if (NULL != g_processing_timer) {
+                       ecore_thread_main_loop_begin();
+                       SLOG(LOG_INFO, TAG_STTD, "[INFO] Delete g_processing_timer");
+                       ecore_timer_del(g_processing_timer);
+                       g_processing_timer = NULL;
+                       ecore_thread_main_loop_end();
+               }
+
+               sttd_config_time_save();
+               sttd_config_time_reset();
 
-               if (APP_STATE_PROCESSING == state ) {
-                       SLOG(LOG_DEBUG, TAG_STTD, "[Server] the size of result from engine is '%d' %s", data_count); 
+               sttd_recorder_clear();
 
-                       if (0 != sttdc_send_result(*uid, type, data, data_count, msg)) {
-                               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");        
+               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");
                                int reason = (int)STTD_ERROR_OPERATION_FAILED;
 
-                               if (0 != sttdc_send_error_signal(*uid, reason, "Fail to send recognition result")) {
-                                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data"); 
+                               if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
+                                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
                                }
                        }
                } else {
-                       SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is NOT thinking."); 
+                       if (0 != sttdc_send_result(uid, event, data, data_count, msg)) {
+                               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
+                               int reason = (int)STTD_ERROR_OPERATION_FAILED;
+
+                               if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
+                                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
+                               }
+                       }
                }
-       } else if (STTP_RESULT_EVENT_NO_RESULT == event || STTP_RESULT_EVENT_ERROR == event) {
 
-               if (APP_STATE_PROCESSING == state ) {
-                       if (0 != sttdc_send_result(*uid, type, 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();
 
-                               /* send error msg */
-                               int reason = (int)STTD_ERROR_INVALID_STATE;     
-                               if (0 != sttdc_send_error_signal(*uid, reason, "[ERROR] Fail to send recognition result")) {
-                                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info "); 
-                               }
+       } else if (STTE_RESULT_EVENT_PARTIAL_RESULT == event) {
+               SLOG(LOG_INFO, TAG_STTD, "[Server] The partial result from engine is event[%d] data_count[%d]", event,  data_count);
+
+               sttd_config_time_save();
+               sttd_config_time_reset();
+
+               if (0 != sttdc_send_result(uid, event, data, data_count, msg)) {
+                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result");
+                       int reason = (int)STTD_ERROR_OPERATION_FAILED;
+
+                       if (0 != sttdc_send_error_signal(uid, reason, "Fail to send recognition result")) {
+                               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info . Remove client data");
                        }
-               } else {
-                       SLOG(LOG_WARN, TAG_STTD, "[Server ERROR] Current state is NOT thinking."); 
                }
+
+       } else if (STTE_RESULT_EVENT_ERROR == event) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The event of recognition result is ERROR");
+
+               /* Delete timer for processing time out */
+               if (NULL != g_processing_timer) {
+                       ecore_thread_main_loop_begin();
+                       SLOG(LOG_INFO, TAG_STTD, "[INFO] Delete g_processing_timer");
+                       ecore_timer_del(g_processing_timer);
+                       g_processing_timer = NULL;
+                       ecore_thread_main_loop_end();
+               }
+               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 ");
+
+                       /* send error msg */
+                       int reason = (int)STTD_ERROR_INVALID_STATE;
+                       if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
+                               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
+                       }
+               }
+
+               /* change state of uid */
+//             sttd_client_set_state(uid, APP_STATE_READY);
+//             stt_client_unset_current_recognition();
        } else {
                /* nothing */
        }
 
-       /* change state of uid */
-       sttd_client_set_state(*uid, APP_STATE_READY);
-
-       if (NULL != user_data)  
-               free(user_data);
-
-       SLOG(LOG_DEBUG, TAG_STTD, "=====");
+       SLOG(LOG_INFO, TAG_STTD, "=====");
        SLOG(LOG_DEBUG, TAG_STTD, "  ");
+       pthread_mutex_unlock(&stte_result_mutex);
 
-       return;
+       return STTD_ERROR_NONE;
 }
 
-void sttd_server_partial_result_callback(sttp_result_event_e event, const char* data, void *user_data)
+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)
 {
-       SLOG(LOG_DEBUG, TAG_STTD, "===== Partial Result Callback");
-
-       /* check uid */
-       int *uid = (int*)user_data;
+       pthread_mutex_lock(&stte_result_time_mutex);
 
-       SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid (%d), event(%d)", uid, event); 
+       SECURE_SLOG(LOG_INFO, TAG_STTD, "[Server] index(%d) event(%d) text(%s) start(%ld) end(%ld)",
+               index, event, text, start_time, end_time);
 
-       app_state_e state;
-       if (0 != sttd_client_get_state(*uid, &state)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid "); 
-               SLOG(LOG_DEBUG, TAG_STTD, "=====");
-               SLOG(LOG_DEBUG, TAG_STTD, "  ");
-               return;
+       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;
        }
 
-       /* send result to client */
-       if (STTP_RESULT_EVENT_SUCCESS == event && NULL != data) {
-               if (0 != sttdc_send_partial_result(*uid, data)) {
-                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send partial result");        
+       pthread_mutex_unlock(&stte_result_time_mutex);
+
+       return true;
+}
+
+int __server_speech_status_callback(stte_speech_status_e status, void *user_param)
+{
+       SLOG(LOG_INFO, TAG_STTD, "===== Speech status detected Callback");
+
+       int uid = stt_client_get_current_recognition();
+       if (0 != uid) {
+               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_OPERATION_FAILED;
                }
-       } 
 
-       SLOG(LOG_DEBUG, TAG_STTD, "=====");
+               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);
+               }
+       } else {
+               SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current recognition uid is not valid ");
+       }
+
+       SLOG(LOG_INFO, TAG_STTD, "=====");
        SLOG(LOG_DEBUG, TAG_STTD, "  ");
+
+       return STTD_ERROR_NONE;
 }
 
-void sttd_server_silence_dectection_callback(void *user_param)
+int __server_error_callback(stte_error_e error, const char* msg)
 {
-       SLOG(LOG_DEBUG, TAG_STTD, "===== Silence Detection Callback");
+       SLOG(LOG_INFO, TAG_STTD, "[Server] Error Callback is called");
+       ecore_main_loop_thread_safe_call_async(__cancel_by_error, NULL);
 
-       int uid = sttd_client_get_current_recording();
+       return STTD_ERROR_NONE;
+}
 
-       app_state_e state;
-       if (0 != sttd_client_get_state(uid, &state)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is not valid "); 
+void __sttd_server_engine_changed_cb(const char* engine_id, const char* language, bool support_silence, bool need_credential, void* user_data)
+{
+       if (NULL == engine_id) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Engine id is NULL");
                return;
+       } else {
+               SLOG(LOG_INFO, TAG_STTD, "[Server] New default engine : %s", engine_id);
        }
 
-       if (APP_STATE_RECORDING != state) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording"); 
+#if 0
+       /* need to change state of app to ready */
+       int uid;
+       uid = stt_client_get_current_recognition();
+
+       if (0 != uid) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server] Set ready state of uid(%d)", uid);
+
+               sttd_server_cancel(uid);
+               sttdc_send_set_state(uid, (int)APP_STATE_READY);
+
+               stt_client_unset_current_recognition();
+       }
+
+       /* set engine */
+       int ret = sttd_engine_agent_set_default_engine(engine_id);
+       if (0 != ret)
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : result(%d)", ret);
+
+       if (NULL != language) {
+               ret = sttd_engine_agent_set_default_language(language);
+               if (0 != ret)
+                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%d)", ret);
+       }
+
+       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;
+}
+
+void __sttd_server_language_changed_cb(const char* language, void* user_data)
+{
+       if (NULL == language) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] language is NULL");
                return;
+       } else {
+               SLOG(LOG_INFO, TAG_STTD, "[Server] Get language changed : %s", language);
        }
 
-       ecore_timer_add(0, __stop_by_silence, NULL);
+       int ret = sttd_engine_agent_set_default_language(language);
+       if (0 != ret)
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%d)", ret);
 
-       SLOG(LOG_DEBUG, TAG_STTD, "=====");
-       SLOG(LOG_DEBUG, TAG_STTD, "  ");
+       return;
+}
+
+void __sttd_server_silence_changed_cb(bool value, void* user_data)
+{
+       SLOG(LOG_INFO, TAG_STTD, "[Server] Get silence detection changed : %s", value ? "on" : "off");
+
+       int ret = 0;
+       ret = sttd_engine_agent_set_silence_detection(value);
+       if (0 != ret)
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret);
 
        return;
 }
@@ -226,73 +453,185 @@ void sttd_server_silence_dectection_callback(void *user_param)
 /*
 * Daemon function
 */
-
-int sttd_initialize()
+int sttd_initialize(stte_request_callback_s *callback)
 {
        int ret = 0;
 
-       if (sttd_config_initialize()) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server WARNING] Fail to initialize config.");
+       if (0 != pthread_mutex_init(&stte_result_mutex, NULL)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize stte result mutex.");
+       }
+
+       if (0 != pthread_mutex_init(&stte_result_time_mutex, NULL)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize stte stte_result_time_mutex.");
+       }
+
+       if (sttd_config_initialize(__sttd_server_engine_changed_cb, __sttd_server_language_changed_cb,
+               __sttd_server_silence_changed_cb, NULL)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize config.");
        }
 
-       /* recoder init */
-       ret = sttd_recorder_init();
+       ret = sttd_recorder_initialize(__server_audio_recorder_callback, __server_audio_interrupt_callback);
        if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize recorder : result(%d)", ret); 
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to initialize recorder : result(%d)", ret);
                return ret;
        }
 
        /* Engine Agent initialize */
-       ret = sttd_engine_agent_init(sttd_server_recognition_result_callback, sttd_server_partial_result_callback, 
-                               sttd_server_silence_dectection_callback);
+       ret = sttd_engine_agent_init(__server_recognition_result_callback, __server_result_time_callback,
+               __server_speech_status_callback, __server_error_callback);
        if (0 != ret) {
                SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine agent initialize : result(%d)", ret);
                return ret;
        }
-       
-       if (0 != sttd_engine_agent_initialize_current_engine()) {
-               SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] There is No STT-Engine !!!!!"); 
-               g_is_engine = false;
-       } else {
-               g_is_engine = true;
+
+       /* load engine */
+       ret = sttd_engine_agent_load_current_engine(callback);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to load default engine");
+               return ret;
        }
 
-       SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] initialize"); 
+       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_INFO, TAG_STTD, "[Server SUCCESS] initialize");
 
        return 0;
 }
 
+int sttd_finalize()
+{
+       if (0 != pthread_mutex_destroy(&stte_result_mutex)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy stte result mutex.");
+       }
+
+       if (0 != pthread_mutex_destroy(&stte_result_time_mutex)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy stte_result_time_mutex.");
+       }
+
+       GList *iter = NULL;
+       if (0 < g_list_length(g_proc_list)) {
+               iter = g_list_first(g_proc_list);
+               while (NULL != iter) {
+                       g_proc_list = g_list_remove_link(g_proc_list, iter);
+                       iter = g_list_first(g_proc_list);
+               }
+       }
+
+       sttd_recorder_deinitialize();
+
+       sttd_config_finalize();
+
+       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");
+       }
+
+       SLOG(LOG_INFO, TAG_STTD, "[Server SUCCESS] finalize");
+
+       return STTD_ERROR_NONE;
+}
+
+static void __read_proc()
+{
+       DIR *dp = NULL;
+       struct dirent *dirp = NULL;
+       int tmp;
+
+       GList *iter = NULL;
+       if (0 < g_list_length(g_proc_list)) {
+               iter = g_list_first(g_proc_list);
+               while (NULL != iter) {
+                       g_proc_list = g_list_remove_link(g_proc_list, iter);
+                       iter = g_list_first(g_proc_list);
+               }
+       }
+
+       dp = opendir("/proc");
+       if (NULL == dp) {
+               SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Fail to open proc");
+       } else {
+               do {
+                       dirp = readdir(dp);
+
+                       if (NULL != dirp) {
+                               tmp = atoi(dirp->d_name);
+                               if (0 >= tmp)   continue;
+                               g_proc_list = g_list_append(g_proc_list, GINT_TO_POINTER(tmp));
+                       }
+               } while (NULL != dirp);
+               closedir(dp);
+       }
+       return;
+}
+
 Eina_Bool sttd_cleanup_client(void *data)
 {
        int* client_list = NULL;
        int client_count = 0;
+       int i = 0;
+       int j = 0;
+       bool exist = false;
+
+       if (0 != sttd_client_get_list(&client_list, &client_count)) {
+               if (NULL != client_list)
+                       free(client_list);
 
-       if (0 != sttd_client_get_list(&client_list, &client_count)) 
-               return EINA_TRUE;
-       
-       if (NULL == client_list)
                return EINA_TRUE;
+       }
 
-       int result;
-       int i = 0;
+       if (NULL != client_list) {
+               SLOG(LOG_INFO, TAG_STTD, "===== Clean up client ");
 
-       SLOG(LOG_DEBUG, TAG_STTD, "===== Clean up client ");
+               __read_proc();
 
-       for (i = 0;i < client_count;i++) {
-               result = sttdc_send_hello(client_list[i]);
+               for (i = 0; i < client_count; i++) {
+                       int pid = sttd_client_get_pid(client_list[i]);
+                       if (0 > pid) {
+                               SLOG(LOG_ERROR, TAG_STTD, "[ERROR] Invalid pid");
+                               continue;
+                       }
 
-               if (0 == result) {
-                       SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", client_list[i]); 
-                       sttd_server_finalize(client_list[i]);
-               } else if (-1 == result) {
-                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Hello result has error"); 
+                       exist = false;
+                       GList *iter = NULL;
+                       for (j = 0; j < g_list_length(g_proc_list); j++) {
+                               iter = g_list_nth(g_proc_list, j);
+                               if (NULL != iter) {
+                                       if (pid == GPOINTER_TO_INT(iter->data)) {
+                                               SLOG(LOG_DEBUG, TAG_STTD, "uid (%d) is running", client_list[i]);
+                                               exist = true;
+                                               break;
+                                       }
+                               }
+                       }
+
+                       if (false == exist) {
+                               SLOG(LOG_ERROR, TAG_STTD, "uid (%d) should be removed", client_list[i]);
+                               sttd_server_finalize(client_list[i]);
+                       }
+#if 0
+                       result = sttdc_send_hello(client_list[i]);
+
+                       if (0 == result) {
+                               SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", client_list[i]);
+                               sttd_server_finalize(client_list[i]);
+                       } else if (-1 == result) {
+                               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Hello result has error");
+                       }
+#endif
                }
-       }
 
-       SLOG(LOG_DEBUG, TAG_STTD, "=====");
-       SLOG(LOG_DEBUG, TAG_STTD, "  ");
+               SLOG(LOG_INFO, TAG_STTD, "=====");
+               SLOG(LOG_DEBUG, TAG_STTD, "  ");
 
-       free(client_list);
+               free(client_list);
+       }
 
        return EINA_TRUE;
 }
@@ -301,775 +640,1088 @@ Eina_Bool sttd_cleanup_client(void *data)
 * STT Server Functions for Client
 */
 
-int sttd_server_initialize(int pid, int uid, bool* silence, bool* profanity, bool* punctuation)
+int sttd_server_initialize(int pid, int uid, bool* silence, bool* credential)
 {
-       if (false == g_is_engine) {
-               if (0 != sttd_engine_agent_initialize_current_engine()) {
-                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] No Engine"); 
-                       g_is_engine = false;
-                       return STTD_ERROR_ENGINE_NOT_FOUND;
-               } else {
-                       g_is_engine = true;
-               }
-       }
+       int ret = STTD_ERROR_NONE;
+
+       SLOG(LOG_INFO, TAG_STTD, "[Server] server initialize");
 
        /* 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 has already been registered"); 
+               SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] uid has already been registered");
+               return STTD_ERROR_NONE;
+       }
+
+       ret = sttd_engine_agent_get_option_supported(silence);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine options supported");
+               return ret;
+       }
+
+       ret = sttd_engine_agent_is_credential_needed(uid, credential);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get credential necessity");
+               return ret;
+       }
+
+       /* Add client information to client manager */
+       ret = sttd_client_add(pid, uid);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add client info");
+               return ret;
+       }
+
+       SLOG(LOG_INFO, TAG_STTD, "[Server Success] server initialize");
+
+       return STTD_ERROR_NONE;
+}
+
+static Eina_Bool __quit_ecore_loop(void *data)
+{
+       SLOG(LOG_INFO, TAG_STTD, "[Server] Quit");
+
+       stt_network_finalize();
+       sttd_finalize();
+       sttd_dbus_close_connection();
+       ecore_main_loop_quit();
+
+       SLOG(LOG_INFO, TAG_STTD, "");
+
+       return EINA_FALSE;
+}
+
+int sttd_server_finalize(int uid)
+{
+       SLOG(LOG_INFO, TAG_STTD, "[Server INFO] Enter Finalize");
+
+       /* 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;
        }
-       
-       /* load if engine is unloaded */
-       if (0 == sttd_client_get_ref_count()) {
-               if (0 != sttd_engine_agent_load_current_engine()) {
-                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to load current engine"); 
-                       return STTD_ERROR_OPERATION_FAILED;
+
+       /* release recorder */
+       if (APP_STATE_RECORDING == state || APP_STATE_PROCESSING == state) {
+               if (APP_STATE_RECORDING == state) {
+                       if (NULL != g_recording_timer)  {
+                               ecore_timer_del(g_recording_timer);
+                               g_recording_timer = NULL;
+                       }
+               }
+
+               if (APP_STATE_PROCESSING == state) {
+                       if (NULL != g_processing_timer) {
+                               SLOG(LOG_INFO, TAG_STTD, "[INFO] Delete g_processing_timer");
+                               ecore_timer_del(g_processing_timer);
+                               g_processing_timer = NULL;
+                       }
                }
+
+               SLOG(LOG_INFO, TAG_STTD, "[Server INFO] stt_cancel is invoked while state is (%d)", state);
+
+               if (0 != sttd_engine_agent_recognize_cancel(uid)) {
+                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognition");
+               }
+
+               stt_client_unset_current_recognition();
        }
 
-       /* initialize recorder using audio format from engine */
-       sttp_audio_type_e atype;
-       int rate;
-       int channels;
+       /* Remove client information */
+       if (0 != sttd_client_delete(uid)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to delete client");
+       }
 
-       if (0 != sttd_engine_get_audio_format(&atype, &rate, &channels)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get audio format of engine."); 
-               return STTD_ERROR_OPERATION_FAILED;
+       /* unload engine, if ref count of client is 0 */
+       if (0 == sttd_client_get_ref_count()) {
+//             sttd_dbus_close_connection();
+               ecore_timer_add(0, __quit_ecore_loop, NULL);
        }
 
-       sttd_recorder_channel           sttchannel = STTD_RECORDER_CHANNEL_MONO;
-       sttd_recorder_audio_type        sttatype = STTD_RECORDER_PCM_S16;
+       SLOG(LOG_INFO, TAG_STTD, "[Server INFO] End Finalize");
 
-       switch (atype) {
-       case STTP_AUDIO_TYPE_PCM_S16_LE:        sttatype = STTD_RECORDER_PCM_S16;       break;
-       case STTP_AUDIO_TYPE_PCM_U8:            sttatype = STTD_RECORDER_PCM_U8;        break;
-       case STTP_AUDIO_TYPE_AMR:               sttatype = STTD_RECORDER_AMR;           break;
-       default:        
-               /* engine error */
-               sttd_engine_agent_unload_current_engine();
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Invalid Audio Type"); 
-               return STTD_ERROR_OPERATION_FAILED;
-               break;
+       return STTD_ERROR_NONE;
+}
+
+int sttd_server_get_supported_engines(int uid, GSList** engine_list)
+{
+       /* 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;
        }
 
-       switch (channels) {
-       case 1:         sttchannel = STTD_RECORDER_CHANNEL_MONO;        break;
-       case 2:         sttchannel = STTD_RECORDER_CHANNEL_STEREO;      break;
-       default:        sttchannel = STTD_RECORDER_CHANNEL_MONO;        break;
+       /* Check state of uid */
+       if (APP_STATE_READY != state) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
+               return STTD_ERROR_INVALID_STATE;
        }
 
-       if (0 != sttd_recorder_set(sttatype, sttchannel, rate, 60, audio_recorder_callback)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set recorder"); 
-               return STTD_ERROR_OPERATION_FAILED;
+       SLOG(LOG_INFO, TAG_STTD, "[Server INFO] get supported egnines");
+
+       int ret;
+       ret = sttd_engine_agent_get_engine_list(engine_list);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine list");
+               return ret;
        }
-       
-       SLOG(LOG_DEBUG, TAG_STTD, "[Server] audio type(%d), channel(%d)", (int)atype, (int)sttchannel); 
 
-       /* Add client information to client manager */
-       if (0 != sttd_client_add(pid, uid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add client info"); 
-               return STTD_ERROR_OPERATION_FAILED;
+       return STTD_ERROR_NONE;
+}
+
+int sttd_server_set_current_engine(int uid, const char* engine_id, bool* silence, bool* credential)
+{
+       /* 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;
        }
 
-       if (0 != sttd_engine_get_option_supported(silence, profanity, punctuation)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine options supported"); 
-               return STTD_ERROR_OPERATION_FAILED;
+       /* Check state of uid */
+       if (APP_STATE_READY != state) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
+               return STTD_ERROR_INVALID_STATE;
+       }
+
+       SLOG(LOG_INFO, TAG_STTD, "[Server INFO] set current egnines, uid(%d), engine_id(%s)", uid, engine_id);
+
+       int ret;
+       ret = sttd_engine_agent_load_current_engine(NULL);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : %d", ret);
+               return ret;
+       }
+
+       ret = sttd_engine_agent_get_option_supported(silence);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to engine options : %d", ret);
+               return ret;
        }
 
-       SLOG(LOG_DEBUG, TAG_STTD, "[Server Success] Initialize"); 
+       if (0 != sttd_engine_agent_is_credential_needed(uid, credential)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get credential necessity");
+               return ret;
+       }
 
        return STTD_ERROR_NONE;
 }
 
-int sttd_server_finalize(const int uid)
+int sttd_server_get_current_engine(int uid, char** engine_id)
 {
-       /* check if uid is valid */
+       /* 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 "); 
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
                return STTD_ERROR_INVALID_PARAMETER;
        }
 
-       /* release recorder */
-       if (APP_STATE_RECORDING == state || APP_STATE_PROCESSING == state) {
-               sttd_recorder_cancel();
-               sttd_engine_recognize_cancel();
+       /* Check state of uid */
+       if (APP_STATE_READY != state) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
+               return STTD_ERROR_INVALID_STATE;
        }
-       
-       /* Remove client information */
-       if (0 != sttd_client_delete(uid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to delete client"); 
+
+       SLOG(LOG_INFO, TAG_STTD, "[Server INFO] get current egnines, uid(%d)", uid);
+
+       int ret;
+       ret = sttd_engine_agent_get_current_engine(engine_id);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine : %d", ret);
+               return ret;
        }
 
-       /* unload engine, if ref count of client is 0 */
-       if (0 == sttd_client_get_ref_count()) {
-               if (0 != sttd_engine_agent_unload_current_engine()) {
-                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unload current engine"); 
-               } else {
-                       SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] unload current engine"); 
-               }
+       return STTD_ERROR_NONE;
+}
+
+int sttd_server_check_app_agreed(int uid, const char* appid, bool* available)
+{
+       /* 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 state of uid */
+       if (APP_STATE_READY != state) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] The state of uid(%d) is not Ready", uid);
+               return STTD_ERROR_INVALID_STATE;
+       }
+
+       SLOG(LOG_INFO, TAG_STTD, "[Server INFO] check app agreed");
+
+       /* Ask engine available */
+       int ret;
+       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 (true == temp) {
+               stt_client_set_app_agreed(uid);
+               SLOG(LOG_DEBUG, TAG_STTD, "[Server] App(%s) confirmed that engine is available", appid);
+       }
+
+       *available = temp;
+
        return STTD_ERROR_NONE;
 }
 
-int sttd_server_get_supported_languages(const int uid, GList** lang_list)
+
+int sttd_server_get_supported_languages(int uid, GSList** lang_list)
 {
        /* 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 "); 
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
                return STTD_ERROR_INVALID_PARAMETER;
        }
 
+       SLOG(LOG_INFO, TAG_STTD, "[Server INFO] get supported languages");
+
        /* get language list from engine */
-       int ret = sttd_engine_supported_langs(lang_list);
+       int ret = sttd_engine_agent_supported_langs(lang_list);
        if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get supported languages"); 
-               return STTD_ERROR_OPERATION_FAILED;
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get supported languages");
+               return ret;
        }
 
-       SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] sttd_server_get_supported_languages"); 
+       SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] sttd_server_get_supported_languages");
 
        return STTD_ERROR_NONE;
 }
 
-int sttd_server_get_current_langauage(const int uid, char** current_lang)
+int sttd_server_get_current_langauage(int uid, char** current_lang)
 {
        /* 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 "); 
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
                return STTD_ERROR_INVALID_PARAMETER;
        }
 
        if (NULL == current_lang) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL"); 
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
                return STTD_ERROR_INVALID_PARAMETER;
        }
 
        /*get current language from engine */
-       int ret = sttd_engine_get_default_lang(current_lang);
-       if (0 != ret) { 
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get default language :result(%d)", ret); 
-               return STTD_ERROR_OPERATION_FAILED;
+       int ret = sttd_engine_agent_get_default_lang(current_lang);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get default language :result(%d)", ret);
+               return ret;
        }
 
-       SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] sttd_engine_get_default_lang"); 
+       SLOG(LOG_INFO, TAG_STTD, "[Server SUCCESS] Get default language, current_lang(%s)", *current_lang);
 
        return STTD_ERROR_NONE;
 }
 
-int sttd_server_is_partial_result_supported(int uid, int* partial_result)
+int sttd_server_set_private_data(int uid, const char* key, const char* data)
 {
        /* 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 "); 
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
                return STTD_ERROR_INVALID_PARAMETER;
        }
 
-       if (NULL == partial_result) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL"); 
+       if (NULL == key || NULL == data) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
                return STTD_ERROR_INVALID_PARAMETER;
        }
 
-       bool temp;
-       int ret = sttd_engine_is_partial_result_supported(&temp);
-       if (0 != ret) { 
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get partial result supported : result(%d)", ret); 
-               return STTD_ERROR_OPERATION_FAILED;
+       /* set private data to engine */
+       int ret = -1;
+       ret = sttd_engine_agent_set_private_data(key, data);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set private data :result(%d)", ret);
+               return ret;
        }
 
-       SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Partial result supporting is %s", temp ? "true" : "false"); 
+       SLOG(LOG_INFO, TAG_STTD, "[Server SUCCESS] Set private data");
 
        return STTD_ERROR_NONE;
 }
 
-int sttd_server_get_audio_volume( const int uid, float* current_volume)
+int sttd_server_get_private_data(int uid, const char* key, char** data)
 {
        /* 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 "); 
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
                return STTD_ERROR_INVALID_PARAMETER;
        }
 
-       /* check uid state */
-       if (APP_STATE_RECORDING != state) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording"); 
-               return STTD_ERROR_INVALID_STATE;
+       if (NULL == key || NULL == data) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
+               return STTD_ERROR_INVALID_PARAMETER;
+       }
+
+       /* get private data to engine */
+       int ret = -1;
+       ret = sttd_engine_agent_get_private_data(key, data);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get private data :result(%d)", ret);
+               return ret;
        }
 
-       if (NULL == current_volume) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL"); 
+       SLOG(LOG_INFO, TAG_STTD, "[Server SUCCESS] Get private data, key(%s), data(%s)", key, *data);
+
+       return STTD_ERROR_NONE;
+}
+
+int sttd_server_is_recognition_type_supported(int uid, const char* type, int* support)
+{
+       /* 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;
        }
 
-       /* get audio volume from recorder */
-       int ret = sttd_recorder_get_volume(current_volume);
+       if (NULL == type || NULL == support) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
+               return STTD_ERROR_INVALID_PARAMETER;
+       }
+
+       bool temp;
+       int ret = sttd_engine_agent_is_recognition_type_supported(type, &temp);
        if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get volume : result(%d)", ret); 
-               return STTD_ERROR_OPERATION_FAILED;
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get recognition type supported : result(%d)", ret);
+               return ret;
        }
 
+       *support = (int)temp;
+
+       SLOG(LOG_INFO, TAG_STTD, "[Server SUCCESS] recognition type supporting is %s", *support ? "true" : "false");
+
        return STTD_ERROR_NONE;
 }
 
+int sttd_server_set_start_sound(int uid, const char* file)
+{
+       /* 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;
+       }
+
+       int ret = sttd_client_set_start_sound(uid, file);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int sttd_server_set_stop_sound(int uid, const char* file)
+{
+       /* 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;
+       }
+
+       int ret = sttd_client_set_stop_sound(uid, file);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set start sound file : result(%d)", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+#if 0
 Eina_Bool __check_recording_state(void *data)
-{      
+{
        /* current uid */
-       int uid = sttd_client_get_current_recording();
-       if (-1 == uid)
+       int uid = stt_client_get_current_recognition();
+       if (0 == uid)
                return EINA_FALSE;
 
        app_state_e state;
        if (0 != sttdc_send_get_state(uid, (int*)&state)) {
                /* client is removed */
-               SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", uid); 
+               SLOG(LOG_DEBUG, TAG_STTD, "[Server] uid(%d) should be removed.", uid);
                sttd_server_finalize(uid);
                return EINA_FALSE;
        }
 
        if (APP_STATE_READY == state) {
                /* Cancel stt */
-               SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Ready'. The daemon should cancel recording", uid); 
+               SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Ready'. The STT service should cancel recording", uid);
                sttd_server_cancel(uid);
        } else if (APP_STATE_PROCESSING == state) {
                /* Cancel stt and send change state */
-               SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Processing'. The daemon should cancel recording", uid); 
+               SLOG(LOG_DEBUG, TAG_STTD, "[Server] The state of uid(%d) is 'Processing'. The STT service should cancel recording", uid);
                sttd_server_cancel(uid);
                sttdc_send_set_state(uid, (int)APP_STATE_READY);
        } else {
                /* Normal state */
-               SLOG(LOG_DEBUG, TAG_STTD, "[Server] The states of daemon and client are identical"); 
+               SLOG(LOG_DEBUG, TAG_STTD, "[Server] The states of STT service and client are identical");
                return EINA_TRUE;
        }
 
        return EINA_FALSE;
 }
+#endif
+
+Eina_Bool __stop_by_recording_timeout(void *data)
+{
+       SLOG(LOG_INFO, TAG_STTD, "===== Stop by timeout");
+
+       if (NULL != g_recording_timer)  {
+               ecore_timer_del(g_recording_timer);
+               g_recording_timer = NULL;
+       }
+
+       int uid = 0;
+       uid = stt_client_get_current_recognition();
+       if (0 != uid) {
+               /* cancel engine recognition */
+               int ret = sttd_server_stop(uid);
+               if (0 != ret) {
+                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop : result(%d)", ret);
+               }
+       }
+
+       SLOG(LOG_INFO, TAG_STTD, "=====");
+       SLOG(LOG_DEBUG, TAG_STTD, "  ");
+
+       return EINA_FALSE;
+}
 
-int sttd_server_start(const int uid, const char* lang, const char* recognition_type, 
-                     int profanity, int punctuation, int silence)
+void __sttd_server_recorder_start(void* data)
 {
+       intptr_t puid = (intptr_t)data;
+       int uid = (int)puid;
+       int current_uid = stt_client_get_current_recognition();
+
+       if (uid != current_uid) {
+               stt_client_unset_current_recognition();
+               return;
+       }
+
+       int ret = sttd_engine_agent_recognize_start_recorder(uid);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
+               return;
+       }
+
+       app_state_e temp_app_state;
+       if (0 != sttd_client_get_state(uid, &temp_app_state)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid ");
+               return;
+       }
+       if (APP_STATE_READY != temp_app_state && 0 != stt_client_get_current_recognition()) {
+               /* Notify uid state change */
+               sttdc_send_set_state(uid, APP_STATE_RECORDING);
+               SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Start recognition");
+       }
+}
+
+void __sttd_start_sound_completed_cb(int id, void *user_data)
+{
+       SLOG(LOG_INFO, TAG_STTD, "===== Start sound completed");
+
+       /* After wav play callback, recorder start */
+       ecore_main_loop_thread_safe_call_async(__sttd_server_recorder_start, user_data);
+
+       SLOG(LOG_INFO, TAG_STTD, "=====");
+       SLOG(LOG_DEBUG, TAG_STTD, "  ");
+       return;
+}
+
+int sttd_server_start(int uid, const char* lang, const char* recognition_type, int silence, const char* appid, const char* credential)
+{
+       if (NULL == lang || NULL == recognition_type) {
+               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 "); 
+               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"); 
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] sttd_server_start : current state is not ready");
                return STTD_ERROR_INVALID_STATE;
        }
 
-       if (0 < sttd_client_get_current_recording()) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT Engine is busy because of recording");
-               return STTD_ERROR_RECORDER_BUSY;
-       }
+       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 (0 < sttd_client_get_current_thinking()) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT Engine is busy because of thinking");
-               return STTD_ERROR_RECORDER_BUSY;
+               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 == sttd_network_is_connected()) {
+               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 (NULL != g_recording_timer) {
+               ecore_timer_del(g_recording_timer);
+               g_recording_timer = NULL;
+       }
+
+       if (NULL != g_processing_timer) {
+               SLOG(LOG_INFO, TAG_STTD, "[INFO] Delete g_processing_timer");
+               ecore_timer_del(g_processing_timer);
+               g_processing_timer = NULL;
+       }
+
+       char* sound = NULL;
+       ret = sttd_client_get_start_sound(uid, &sound);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
+               return ret;
+       }
+
+       if (0 != stt_client_set_current_recognition(uid)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current STT is busy because of recording or processing");
+               if (NULL != sound)      free(sound);
+               return STTD_ERROR_RECORDER_BUSY;
+       }
+
        /* engine start recognition */
-       int* user_data;
-       user_data = (int*)malloc( sizeof(int) * 1);
-       
-       /* free on result callback */
-       *user_data = uid;
+       SLOG(LOG_INFO, TAG_STTD, "[Server] start : uid(%d), lang(%s), recog_type(%s)",
+                       uid, lang, recognition_type);
+       if (NULL != sound)
+               SLOG(LOG_INFO, TAG_STTD, "[Server] start sound : %s", sound);
 
-       SLOG(LOG_DEBUG, TAG_STTD, "[Server] start : uid(%d), lang(%s), recog_type(%s)", *user_data, lang, recognition_type ); 
-
-       int ret = sttd_engine_recognize_start((char*)lang, recognition_type, profanity, punctuation, silence, (void*)user_data);
+       /* 1. Set audio session */
+       ret = sttd_recorder_set_audio_session();
        if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret); 
-               return STTD_ERROR_OPERATION_FAILED;
+               stt_client_unset_current_recognition();
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set session : %d", ret);
+               if (NULL != sound)      free(sound);
+               return ret;
+       }
+
+       bool is_sound_done = false;
+
+       /* 2. Request wav play */
+       if (NULL != sound) {
+               int id = 0;
+               intptr_t puid = (intptr_t)uid;
+               sound_stream_info_h wav_stream_info_h;
+               if (0 != sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, NULL, NULL, &wav_stream_info_h)) {
+                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to create stream info for playing wav");
+                       is_sound_done = true;
+               } else {
+                       ret = wav_player_start_new(sound, wav_stream_info_h, __sttd_start_sound_completed_cb, (void*)puid, &id);
+                       if (WAV_PLAYER_ERROR_NONE != ret) {
+                               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
+                               is_sound_done = true;
+                       }
+
+                       if (0 != sound_manager_destroy_stream_information(wav_stream_info_h)) {
+                               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy stream info for playing wav");
+                       }
+               }
+               free(sound);
+               sound = NULL;
+       } else {
+               is_sound_done = true;
        }
 
-       /* recorder start */
-       ret = sttd_recorder_start();
+       /* 3. Create recorder & engine initialize */
+       ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, appid, credential, NULL);
        if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recorder : result(%d)", ret); 
-               sttd_engine_recognize_cancel();
-               return STTD_ERROR_OPERATION_FAILED;
+               stt_client_unset_current_recognition();
+               sttd_recorder_unset_audio_session();
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
+               return ret;
        }
 
-       SLOG(LOG_DEBUG, TAG_STTD, "[Server] start recording"); 
+       if (0 != strcmp(STTE_RECOGNITION_TYPE_FREE_PARTIAL, recognition_type)) {
+               g_recording_timer = ecore_timer_add(g_recording_timeout, __stop_by_recording_timeout, NULL);
+       }
 
        /* change uid state */
        sttd_client_set_state(uid, APP_STATE_RECORDING);
 
-       Ecore_Timer* timer = ecore_timer_add(g_state_check_time, __check_recording_state, NULL);
-       sttd_cliet_set_timer(uid, timer);
+       g_recording_log_count = 0;
 
-       return STTD_ERROR_NONE;
+       app_state_e temp_app_state;
+
+       if (true == is_sound_done) {
+               SLOG(LOG_INFO, TAG_STTD, "[Server] No sound play");
+
+               ret = sttd_engine_agent_recognize_start_recorder(uid);
+               if (0 != ret) {
+                       stt_client_unset_current_recognition();
+                       sttd_recorder_unset_audio_session();
+
+                       sttd_engine_agent_recognize_cancel();
+                       if (NULL != g_recording_timer)  {
+                               ecore_timer_del(g_recording_timer);
+                               g_recording_timer = NULL;
+                       }
+                       sttd_client_set_state(uid, APP_STATE_READY);
+
+                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
+                       return ret;
+               }
+
+               if (0 != sttd_client_get_state(uid, &temp_app_state)) {
+                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] uid is NOT valid");
+                       return STTD_ERROR_INVALID_PARAMETER;
+               }
+               if (APP_STATE_READY != temp_app_state && 0 != stt_client_get_current_recognition()) {
+                       /* Notify uid state change */
+                       sttdc_send_set_state(uid, APP_STATE_RECORDING);
+               }
+
+               SLOG(LOG_INFO, TAG_STTD, "[Server SUCCESS] Start recognition");
+               return STTD_RESULT_STATE_DONE;
+       }
+
+       SLOG(LOG_INFO, TAG_STTD, "[Server] Wait sound finish");
+
+       return STTD_RESULT_STATE_NOT_DONE;
 }
 
 Eina_Bool __time_out_for_processing(void *data)
-{      
+{
+       if (NULL != g_processing_timer) {
+               SLOG(LOG_INFO, TAG_STTD, "[INFO] Delete g_processing_timer");
+               ecore_timer_del(g_processing_timer);
+               g_processing_timer = NULL;
+       }
+
+       SLOG(LOG_INFO, TAG_STTD, "[Server INFO] Enter __time_out_for_processing");
+
        /* current uid */
-       int uid = sttd_client_get_current_thinking();
-       if (-1 == uid)
-               return EINA_FALSE;
+       int uid = stt_client_get_current_recognition();
+       if (0 == uid)   return EINA_FALSE;
+
+       SLOG(LOG_INFO, TAG_STTD, "[Server Info] stt cancel is invoked by timeout for processing");
 
        /* Cancel engine */
-       int ret = sttd_engine_recognize_cancel();
+       int ret = sttd_engine_agent_recognize_cancel();
        if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret); 
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret);
        }
 
-       if (0 != sttdc_send_result(uid, STTP_RECOGNITION_TYPE_FREE, NULL, 0, "Time out not to receive recognition result.")) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result "); 
+       if (0 != sttdc_send_result(uid, STTE_RESULT_EVENT_FINAL_RESULT, NULL, 0, "Time out not to receive recognition result.")) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send result ");
 
                /* send error msg */
-               int reason = (int)STTD_ERROR_TIMED_OUT; 
+               int reason = (int)STTD_ERROR_TIMED_OUT;
                if (0 != sttdc_send_error_signal(uid, reason, "[ERROR] Fail to send recognition result")) {
-                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info "); 
+                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to send error info ");
                }
        }
 
        /* Change uid state */
        sttd_client_set_state(uid, APP_STATE_READY);
 
+       stt_client_unset_current_recognition();
+
+       SLOG(LOG_INFO, TAG_STTD, "[Server INFO] End __time_out_for_processing");
+
        return EINA_FALSE;
 }
 
-
-int sttd_server_stop(const int uid)
+void __sttd_server_engine_stop(void* data)
 {
-       /* 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;
-       }
+       intptr_t puid = (intptr_t)data;
+       int uid = (int)puid;
+       /* change uid state */
+       sttd_client_set_state(uid, APP_STATE_PROCESSING);
 
-       /* check uid state */
-       if (APP_STATE_RECORDING != state) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording"); 
-               return STTD_ERROR_INVALID_STATE;
-       }
+       /* Notify uid state change */
+       sttdc_send_set_state(uid, APP_STATE_PROCESSING);
 
-       /* stop recorder */
-       sttd_recorder_stop();
+       /* 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;
+       }
 
-       /* stop engine recognition */
-       int ret = sttd_engine_recognize_stop();
+       /* Stop engine */
+       ret = sttd_engine_agent_recognize_stop_engine();
        if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop : result(%d)", ret); 
-               sttd_client_set_state(uid, APP_STATE_READY);            
-       
-               return STTD_ERROR_OPERATION_FAILED;
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
+               return;
        }
-       
-       Ecore_Timer* timer;
-       sttd_cliet_get_timer(uid, &timer);
 
-       if (NULL != timer)
-               ecore_timer_del(timer);
+       SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] Stop recognition");
+}
 
-       /* change uid state */
-       sttd_client_set_state(uid, APP_STATE_PROCESSING);
+void __sttd_stop_sound_completed_cb(int id, void *user_data)
+{
+       SLOG(LOG_INFO, TAG_STTD, "===== Stop sound completed");
 
-       timer = ecore_timer_add(g_state_check_time, __time_out_for_processing, NULL);
-       sttd_cliet_set_timer(uid, timer);
+       /* After wav play callback, engine stop */
+       ecore_main_loop_thread_safe_call_async(__sttd_server_engine_stop, user_data);
 
-       return STTD_ERROR_NONE;
+       SLOG(LOG_DEBUG, TAG_STTD, "=====");
+       SLOG(LOG_DEBUG, TAG_STTD, "  ");
+       return;
 }
 
-int sttd_server_cancel(const int uid)
+int sttd_server_stop(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 "); 
+               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"); 
+       /* check uid state */
+       if (APP_STATE_RECORDING != state) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Current state is not recording");
                return STTD_ERROR_INVALID_STATE;
        }
 
-       /* stop recorder */
-       if (APP_STATE_RECORDING == state) 
-               sttd_recorder_cancel();
-
-       /* cancel engine recognition */
-       int ret = sttd_engine_recognize_cancel();
-       if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel : result(%d)", ret); 
-               return STTD_ERROR_OPERATION_FAILED;
+       if (NULL != g_recording_timer)  {
+               ecore_timer_del(g_recording_timer);
+               g_recording_timer = NULL;
        }
 
-       Ecore_Timer* timer;
-       sttd_cliet_get_timer(uid, &timer);
-       ecore_timer_del(timer);
-
-       /* change uid state */
-       sttd_client_set_state(uid, APP_STATE_READY);
-
-       return STTD_ERROR_NONE;
-}
+       if (NULL != g_processing_timer) {
+               SLOG(LOG_INFO, TAG_STTD, "[INFO] Delete g_processing_timer");
+               ecore_timer_del(g_processing_timer);
+               g_processing_timer = NULL;
+       }
 
+       char* sound = NULL;
+       if (0 != sttd_client_get_stop_sound(uid, &sound)) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get start beep sound");
+               return STTD_ERROR_OPERATION_FAILED;
+       }
 
-/******************************************************************************************
-* STT Server Functions for setting
-*******************************************************************************************/
+       SLOG(LOG_INFO, TAG_STTD, "[Server] stop sound path : %s", sound);
 
-int sttd_server_setting_initialize(int pid)
-{
-       if (false == g_is_engine) {
-               if (0 != sttd_engine_agent_initialize_current_engine()) {
-                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] No Engine"); 
-                       g_is_engine = false;
-                       return STTD_ERROR_ENGINE_NOT_FOUND;
-               } else {
-                       g_is_engine = true;
+       int ret;
+       /* 1. Stop recorder */
+       ret = sttd_engine_agent_recognize_stop_recorder();
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop recorder : result(%d)", ret);
+               if (0 != sttd_engine_agent_recognize_cancel()) {
+                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to cancel recognize");
                }
+               if (NULL != sound)      free(sound);
+               return ret;
        }
 
-       /* check whether pid is valid */
-       if (true == sttd_setting_client_is(pid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
-               return STTD_ERROR_INVALID_PARAMETER;
-       }
+       /* 2. Request wav play */
+       if (NULL != sound) {
+               int id = 0;
+               intptr_t puid = (intptr_t)uid;
+               sound_stream_info_h wav_stream_info_h;
+               if (0 != sound_manager_create_stream_information(SOUND_STREAM_TYPE_MEDIA, NULL, NULL, &wav_stream_info_h)) {
+                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to create stream info for playing wav");
+               } else {
+                       ret = wav_player_start_new(sound, wav_stream_info_h, __sttd_stop_sound_completed_cb, (void*)puid, &id);
+                       if (WAV_PLAYER_ERROR_NONE != ret) {
+                               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to play wav");
+                       } else {
+                               SLOG(LOG_DEBUG, TAG_STTD, "[Server] Play wav : %s", sound);
+                       }
 
-       /* load if engine is unloaded */
-       if (0 == sttd_client_get_ref_count()) {
-               if (0 != sttd_engine_agent_load_current_engine()) {
-                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to load current engine"); 
-                       return STTD_ERROR_OPERATION_FAILED;
+                       if (0 != sound_manager_destroy_stream_information(wav_stream_info_h)) {
+                               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to destroy stream info for playing wav");
+                       }
                }
-       }
+               free(sound);
 
-       /* Add setting client information to client manager (For internal use) */
-       if (0 != sttd_setting_client_add(pid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to add setting client"); 
-               return STTD_ERROR_OPERATION_FAILED;
-       }
+               SLOG(LOG_INFO, TAG_STTD, "[INFO] Add g_processing_timer");
+               g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
 
-       return STTD_ERROR_NONE;
-}
+               return STTD_RESULT_STATE_NOT_DONE;
+       } else {
+               SLOG(LOG_INFO, TAG_STTD, "[Server] No sound play");
 
-int sttd_server_setting_finalize(int pid)
-{
-       /* Remove client information */
-       if (0 != sttd_setting_client_delete(pid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to delete setting client"); 
-       }
+               /* 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);
+                       return ret;
+               }
 
-       /* unload engine, if ref count of client is 0 */
-       if (0 == sttd_client_get_ref_count()) {
-               if (0 != sttd_engine_agent_unload_current_engine()) {
-                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to unload current engine"); 
-               } else {
-                       SLOG(LOG_DEBUG, TAG_STTD, "[Server SUCCESS] unload current engine"); 
+               /* Stop engine */
+               ret = sttd_engine_agent_recognize_stop_engine();
+               if (0 != ret) {
+                       stt_client_unset_current_recognition();
+                       SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to stop engine : result(%d)", ret);
+                       return ret;
                }
-       }
 
-       return STTD_ERROR_NONE;
-}
+               /* change uid state */
+               sttd_client_set_state(uid, APP_STATE_PROCESSING);
 
-int sttd_server_setting_get_engine_list(int pid, GList** engine_list)
-{
-       /* check whether pid is valid */
-       if (true != sttd_setting_client_is(pid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
-               return STTD_ERROR_INVALID_PARAMETER;
-       }
+               /* Notify uid state change */
+               sttdc_send_set_state(uid, APP_STATE_PROCESSING);
 
-       if (NULL == engine_list) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL"); 
-               return STTD_ERROR_INVALID_PARAMETER;
-       }
+               SLOG(LOG_INFO, TAG_STTD, "[Server SUCCESS] Stop recognition");
 
-       int ret = sttd_engine_setting_get_engine_list(engine_list); 
-       if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine list : result(%d)", ret); 
-               return ret;
+               SLOG(LOG_INFO, TAG_STTD, "[INFO] Add g_processing_timer");
+               g_processing_timer = ecore_timer_add(g_processing_timeout, __time_out_for_processing, NULL);
+
+               return STTD_RESULT_STATE_DONE;
        }
 
        return STTD_ERROR_NONE;
 }
 
-int sttd_server_setting_get_engine(int pid, char** engine_id)
+int sttd_server_cancel(int uid)
 {
-       /* check whether pid is valid */
-       if (true != sttd_setting_client_is(pid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
-               return STTD_ERROR_INVALID_PARAMETER;
-       }
+       SLOG(LOG_INFO, TAG_STTD, "[Server INFO] Enter sttd_server_cancel");
 
-       if (NULL == engine_id) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL"); 
+       /* 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;
        }
 
-       /* get engine */
-       int ret = sttd_engine_setting_get_engine(engine_id); 
-       if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine : result(%d)", ret); 
-               return ret;
+       /* check uid state */
+       if (APP_STATE_READY == state) {
+               SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is ready");
+               return STTD_ERROR_NONE;
        }
 
-       return STTD_ERROR_NONE;
-}
+       stt_client_unset_current_recognition();
 
-int sttd_server_setting_set_engine(int pid, const char* engine_id)
-{
-       /* check whether pid is valid */
-       if (true != sttd_setting_client_is(pid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
-               return STTD_ERROR_INVALID_PARAMETER;
+       if (NULL != g_recording_timer) {
+               ecore_timer_del(g_recording_timer);
+               g_recording_timer = NULL;
        }
 
-       if (NULL == engine_id) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL"); 
-               return STTD_ERROR_INVALID_PARAMETER;
+       if (NULL != g_processing_timer) {
+               SLOG(LOG_INFO, TAG_STTD, "[INFO] Delete g_processing_timer");
+               ecore_timer_del(g_processing_timer);
+               g_processing_timer = NULL;
        }
 
-       /* set engine */
-       int ret = sttd_engine_setting_set_engine(engine_id); 
-       if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine : result(%d)", ret); 
-               return ret;
+       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;
+               }
        }
 
-       return STTD_ERROR_NONE;
-}
+       /* change uid state */
+       sttd_client_set_state(uid, APP_STATE_READY);
 
-int sttd_server_setting_get_lang_list(int pid, char** engine_id, GList** lang_list)
-{
-       /* check whether pid is valid */
-       if (true != sttd_setting_client_is(pid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
-               return STTD_ERROR_INVALID_PARAMETER;
-       }
-       
-       if (NULL == lang_list) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] language is NULL"); 
-               return STTD_ERROR_INVALID_PARAMETER;
-       }
-       
-       int ret = sttd_engine_setting_get_lang_list(engine_id, lang_list); 
+       SLOG(LOG_INFO, TAG_STTD, "[Server Info] stt cancel is invoked by app's request");
+
+       /* cancel engine recognition */
+       int ret = sttd_engine_agent_recognize_cancel();
        if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get language list : result(%d)", 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);
+
+       SLOG(LOG_INFO, TAG_STTD, "[Server INFO] End sttd_server_cancel");
+
        return STTD_ERROR_NONE;
 }
 
-int sttd_server_setting_get_default_language(int pid, char** language)
+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)
 {
-       /* check whether pid is valid */
-       if (true != sttd_setting_client_is(pid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
+       if (NULL == lang || NULL == recognition_type || NULL == filepath) {
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL");
                return STTD_ERROR_INVALID_PARAMETER;
        }
 
-       if (NULL == language) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] language is NULL"); 
+       /* 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;
        }
 
-       int ret = sttd_engine_setting_get_default_lang(language); 
-       if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get default language : result(%d)", ret); 
-               return ret;
-       }       
-
-       return STTD_ERROR_NONE;
-}
-
-int sttd_server_setting_set_default_language(int pid, const char* language)
-{
-       /* check whether pid is valid */
-       if (true != sttd_setting_client_is(pid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid 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;
        }
 
-       if (NULL == language) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] language is NULL"); 
-               return STTD_ERROR_INVALID_PARAMETER;
-       }
+       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;
+               }
 
-       int ret = sttd_engine_setting_set_default_lang((char*)language); 
-       if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set default lang : result(%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;
+               }
 
-       return STTD_ERROR_NONE;
-}
+               stt_client_set_app_agreed(uid);
+       }
 
-int sttd_server_setting_get_profanity_filter(int pid, bool* value)
-{
-       /* check whether pid is valid */
-       if (true != sttd_setting_client_is(pid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
-               return STTD_ERROR_INVALID_PARAMETER;
+       /* 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 (NULL == value) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL"); 
-               return STTD_ERROR_INVALID_PARAMETER;
+       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;
        }
 
-       int ret = 0;
-       ret = sttd_engine_setting_get_profanity_filter(value);
+       /* 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) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get profanity filter : result(%d)", ret); 
+               stt_client_unset_current_recognition();
+               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set session : %d", ret);
                return ret;
-       }       
-
-       return STTD_ERROR_NONE;
-}
-
-int sttd_server_setting_set_profanity_filter(int pid, bool value)
-{
-       /* check whether pid is valid */
-       if (true != sttd_setting_client_is(pid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
-               return STTD_ERROR_INVALID_PARAMETER;
        }
 
-       int ret = 0;
-       ret = sttd_engine_setting_set_profanity_filter(value);
+       /* 2. Start engine to recognize */
+       ret = sttd_engine_agent_recognize_start_engine(uid, lang, recognition_type, silence, appid, credential, NULL);
        if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set profanity filter: result(%d)", 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;
-       }       
-
-       return STTD_ERROR_NONE;
-}
-
-int sttd_server_setting_get_punctuation_override(int pid, bool* value)
-{
-       /* check whether pid is valid */
-       if (true != sttd_setting_client_is(pid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
-               return STTD_ERROR_INVALID_PARAMETER;
        }
 
-       if (NULL == value) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL"); 
-               return STTD_ERROR_INVALID_PARAMETER;
-       }
+       sttd_client_set_state(uid, APP_STATE_RECORDING);
+       sttdc_send_set_state(uid, APP_STATE_RECORDING);
 
-       int ret = 0;
-       ret = sttd_engine_setting_get_punctuation_override(value);
+       /* 3. Start to send pcm from file to engine */
+       ret = sttd_engine_agent_recognize_start_file(uid, filepath);
        if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get punctuation override : result(%d)", 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;
-       }       
-
-       return STTD_ERROR_NONE;
-}
-
-int sttd_server_setting_set_punctuation_override(int pid, bool value)
-{
-       /* check whether pid is valid */
-       if (true != sttd_setting_client_is(pid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
-               return STTD_ERROR_INVALID_PARAMETER;
        }
 
-       int ret = 0;
-       ret = sttd_engine_setting_set_punctuation_override(value);
+       /* 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 set punctuation override : result(%d)", 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;
-       }       
-
-       return STTD_ERROR_NONE;
-}
-
-int sttd_server_setting_get_silence_detection(int pid, bool* value)
-{
-       /* check whether pid is valid */
-       if (true != sttd_setting_client_is(pid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
-               return STTD_ERROR_INVALID_PARAMETER;
        }
 
-       if (NULL == value) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Input parameter is NULL"); 
-               return STTD_ERROR_INVALID_PARAMETER;
+       /* 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;
        }
 
-       int ret = 0;
-       ret = sttd_engine_setting_get_silence_detection(value);
+       /* 7. Stop engine */
+       ret = sttd_engine_agent_recognize_stop_engine();
        if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get silence detection : result(%d)", 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_setting_set_silence_detection(int pid, bool value)
+int sttd_server_cancel_file(int uid)
 {
-       /* check whether pid is valid */
-       if (true != sttd_setting_client_is(pid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
+       /* 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;
        }
 
-       int ret = 0;
-       ret = sttd_engine_setting_set_silence_detection(value);
-       if (0 != ret) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to Result(%d)", ret); 
-               return ret;
-       }       
+       /* check uid state */
+       if (APP_STATE_READY == state) {
+               SLOG(LOG_WARN, TAG_STTD, "[Server WARNING] Current state is ready");
+               return STTD_ERROR_NONE;
+       }
 
-       return STTD_ERROR_NONE;
-}
+       stt_client_unset_current_recognition();
 
-int sttd_server_setting_get_engine_setting(int pid, char** engine_id, GList** lang_list)
-{      
-       /* check whether pid is valid */
-       if (true != sttd_setting_client_is(pid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
-               return STTD_ERROR_INVALID_PARAMETER;
+       if (NULL != g_recording_timer) {
+               ecore_timer_del(g_recording_timer);
+               g_recording_timer = NULL;
        }
 
-       if (0 != sttd_engine_setting_get_engine_setting_info(engine_id, lang_list)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to get engine setting info"); 
-               return STTD_ERROR_OPERATION_FAILED;
+       if (NULL != g_processing_timer) {
+               SLOG(LOG_INFO, TAG_STTD, "[INFO] Delete g_processing_timer");
+               ecore_timer_del(g_processing_timer);
+               g_processing_timer = NULL;
        }
 
-       return STTD_ERROR_NONE;
-}
-
-int sttd_server_setting_set_engine_setting(int pid, const char* key, const char* value)
-{      
-       /* check whether pid is valid */
-       if (true != sttd_setting_client_is(pid)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Setting pid is NOT valid "); 
-               return STTD_ERROR_INVALID_PARAMETER;
+       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;
+               }
        }
 
-       if (0 != sttd_engine_setting_set_engine_setting(key, value)) {
-               SLOG(LOG_ERROR, TAG_STTD, "[Server ERROR] Fail to set engine setting info"); 
-               return STTD_ERROR_OPERATION_FAILED;
+       /* 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;
 }
+