Add restore logic when daemon get signal
[platform/core/uifw/stt.git] / client / stt.c
1 /*
2 *  Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved
3 *  Licensed under the Apache License, Version 2.0 (the "License");
4 *  you may not use this file except in compliance with the License.
5 *  You may obtain a copy of the License at
6 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14 #include <aul.h>
15 #include <cynara-client.h>
16 #include <cynara-error.h>
17 #include <cynara-session.h>
18 #include <dirent.h>
19 #include <Ecore.h>
20 #include <fcntl.h>
21 #include <pthread.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <sys/wait.h>
25 #include <system_info.h>
26 #include <unistd.h>
27
28 #include "stt.h"
29 #include "stt_client.h"
30 #include "stt_dbus.h"
31 #include "stt_config_mgr.h"
32 #include "stt_main.h"
33
34
35 static void __stt_notify_state_changed(void *data);
36 static Eina_Bool __stt_notify_error(void *data);
37
38 static Ecore_Timer* g_connect_timer = NULL;
39 static float g_volume_db = 0;
40
41 static int g_feature_enabled = -1;
42
43 static int g_privilege_allowed = -1;
44 static cynara *p_cynara = NULL;
45
46 static bool g_err_callback_status = false;
47
48 const char* stt_tag()
49 {
50         return "sttc";
51 }
52
53 static int __stt_get_feature_enabled()
54 {
55         if (0 == g_feature_enabled) {
56                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] STT NOT supported");
57                 return STT_ERROR_NOT_SUPPORTED;
58         } else if (-1 == g_feature_enabled) {
59                 bool stt_supported = false;
60                 bool mic_supported = false;
61                 if (0 == system_info_get_platform_bool(STT_FEATURE_PATH, &stt_supported)) {
62                         if (0 == system_info_get_platform_bool(STT_MIC_FEATURE_PATH, &mic_supported)) {
63                                 if (false == stt_supported || false == mic_supported) {
64                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] STT NOT supported");
65                                         g_feature_enabled = 0;
66                                         return STT_ERROR_NOT_SUPPORTED;
67                                 }
68
69                                 g_feature_enabled = 1;
70                         } else {
71                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get feature value");
72                                 return STT_ERROR_NOT_SUPPORTED;
73                         }
74                 } else {
75                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get feature value");
76                         return STT_ERROR_NOT_SUPPORTED;
77                 }
78         }
79
80         return 0;
81 }
82
83 static int __check_privilege_initialize()
84 {
85         int ret = cynara_initialize(&p_cynara, NULL);
86         if (CYNARA_API_SUCCESS != ret)
87                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] fail to initialize");
88         
89         return ret == CYNARA_API_SUCCESS;
90 }
91
92 static int __check_privilege(const char* uid, const char * privilege)
93 {
94         FILE *fp = NULL;
95         char smack_label[1024] = "/proc/self/attr/current";
96
97         if (!p_cynara) {
98             return false;
99         }
100
101         fp = fopen(smack_label, "r");
102         if (fp != NULL) {
103             if (fread(smack_label, 1, sizeof(smack_label), fp) <= 0)
104                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] fail to fread");
105
106             fclose(fp);
107         }
108
109         pid_t pid = getpid();
110         char *session = cynara_session_from_pid(pid);
111         int ret = cynara_check(p_cynara, smack_label, session, uid, privilege);
112         SLOG(LOG_DEBUG, TAG_STTC, "[Client]cynara_check returned %d(%s)", ret, (CYNARA_API_ACCESS_ALLOWED == ret) ? "Allowed" : "Denied");
113         if (session)
114             free(session);
115
116         if (ret != CYNARA_API_ACCESS_ALLOWED)
117             return false;
118         return true;
119 }
120
121 static void __check_privilege_deinitialize()
122 {
123         if (p_cynara)
124                 cynara_finish(p_cynara);
125         p_cynara = NULL;
126 }
127
128 static int __stt_check_privilege()
129 {
130         char uid[16];
131
132         if (0 == g_privilege_allowed) {
133                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Permission is denied");
134                 return STT_ERROR_PERMISSION_DENIED;
135         } else if (-1 == g_privilege_allowed) {
136                 if (false == __check_privilege_initialize()){
137                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] privilege initialize is failed");
138                         return STT_ERROR_PERMISSION_DENIED;
139                 }
140                 snprintf(uid, 16, "%d", getuid());
141                 if (false == __check_privilege(uid, STT_PRIVILEGE)) {
142                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Permission is denied");
143                         g_privilege_allowed = 0;
144                         __check_privilege_deinitialize();
145                         return STT_ERROR_PERMISSION_DENIED;
146                 }
147                 __check_privilege_deinitialize();
148         }
149
150         g_privilege_allowed = 1;
151         return STT_ERROR_NONE;  
152 }
153
154 static const char* __stt_get_error_code(stt_error_e err)
155 {
156         switch (err) {
157         case STT_ERROR_NONE:                    return "STT_ERROR_NONE";
158         case STT_ERROR_OUT_OF_MEMORY:           return "STT_ERROR_OUT_OF_MEMORY";
159         case STT_ERROR_IO_ERROR:                return "STT_ERROR_IO_ERROR";
160         case STT_ERROR_INVALID_PARAMETER:       return "STT_ERROR_INVALID_PARAMETER";
161         case STT_ERROR_TIMED_OUT:               return "STT_ERROR_TIMED_OUT";
162         case STT_ERROR_RECORDER_BUSY:           return "STT_ERROR_RECORDER_BUSY";
163         case STT_ERROR_OUT_OF_NETWORK:          return "STT_ERROR_OUT_OF_NETWORK";
164         case STT_ERROR_PERMISSION_DENIED:       return "STT_ERROR_PERMISSION_DENIED";
165         case STT_ERROR_NOT_SUPPORTED:           return "STT_ERROR_NOT_SUPPORTED";
166         case STT_ERROR_INVALID_STATE:           return "STT_ERROR_INVALID_STATE";
167         case STT_ERROR_INVALID_LANGUAGE:        return "STT_ERROR_INVALID_LANGUAGE";
168         case STT_ERROR_ENGINE_NOT_FOUND:        return "STT_ERROR_ENGINE_NOT_FOUND";
169         case STT_ERROR_OPERATION_FAILED:        return "STT_ERROR_OPERATION_FAILED";
170         case STT_ERROR_NOT_SUPPORTED_FEATURE:   return "STT_ERROR_NOT_SUPPORTED_FEATURE";
171         case STT_ERROR_SERVICE_RESET:           return "STT_ERROR_SERVICE_RESET";
172         default:
173                 return "Invalid error code";
174         }
175 }
176
177 static int __stt_convert_config_error_code(stt_config_error_e code)
178 {
179         if (code == STT_CONFIG_ERROR_NONE)                      return STT_ERROR_NONE;
180         if (code == STT_CONFIG_ERROR_OUT_OF_MEMORY)             return STT_ERROR_OUT_OF_MEMORY;
181         if (code == STT_CONFIG_ERROR_IO_ERROR)                  return STT_ERROR_IO_ERROR;
182         if (code == STT_CONFIG_ERROR_INVALID_PARAMETER)         return STT_ERROR_INVALID_PARAMETER;
183         if (code == STT_CONFIG_ERROR_PERMISSION_DENIED)         return STT_ERROR_PERMISSION_DENIED;
184         if (code == STT_CONFIG_ERROR_NOT_SUPPORTED)             return STT_ERROR_NOT_SUPPORTED;
185         if (code == STT_CONFIG_ERROR_INVALID_STATE)             return STT_ERROR_INVALID_STATE;
186         if (code == STT_CONFIG_ERROR_INVALID_LANGUAGE)          return STT_ERROR_INVALID_LANGUAGE;
187         if (code == STT_CONFIG_ERROR_ENGINE_NOT_FOUND)          return STT_ERROR_ENGINE_NOT_FOUND;
188         if (code == STT_CONFIG_ERROR_OPERATION_FAILED)          return STT_ERROR_OPERATION_FAILED;
189
190         return code;
191 }
192
193 void __stt_config_lang_changed_cb(const char* before_language, const char* current_language, void* user_data)
194 {
195         SLOG(LOG_DEBUG, TAG_STTC, "Language changed : Before lang(%s) Current lang(%s)",
196                 before_language, current_language);
197
198         if (0 == strcmp(before_language, current_language)) {
199                 return;
200         }
201
202         GList* client_list = NULL;
203         client_list = stt_client_get_client_list();
204
205         GList *iter = NULL;
206         stt_client_s *data = NULL;
207
208         if (g_list_length(client_list) > 0) {
209                 /* Get a first item */
210                 iter = g_list_first(client_list);
211
212                 while (NULL != iter) {
213                         data = iter->data;
214                         if (NULL != data->default_lang_changed_cb) {
215                                 SLOG(LOG_DEBUG, TAG_STTC, "Call default language changed callback : uid(%d)", data->uid);
216                                 data->default_lang_changed_cb(data->stt, before_language, current_language,
217                                         data->default_lang_changed_user_data);
218                         }
219
220                         /* Next item */
221                         iter = g_list_next(iter);
222                 }
223         }
224
225         return;
226 }
227
228 void __stt_config_engine_changed_cb(const char* engine_id, const char* setting, const char* language, bool support_silence, bool need_credential, void* user_data)
229 {
230         stt_h stt = (stt_h)user_data;
231
232         stt_client_s* client = stt_client_get(stt);
233         if (NULL == client) {
234                 SLOG(LOG_ERROR, TAG_STTC, "[WARNING] A handle is not valid");
235                 return;
236         }
237
238         if (NULL != engine_id)  SLOG(LOG_DEBUG, TAG_STTC, "Engine id(%s)", engine_id);
239         if (NULL != setting)    SLOG(LOG_DEBUG, TAG_STTC, "Engine setting(%s)", setting);
240         if (NULL != language)   SLOG(LOG_DEBUG, TAG_STTC, "Language(%s)", language);
241         SLOG(LOG_DEBUG, TAG_STTC, "Silence(%s), Credential(%s)", support_silence ? "on" : "off", need_credential ? "need" : "no need");
242
243         /* call callback function */
244         if (NULL != client->engine_changed_cb) {
245                 client->engine_changed_cb(stt, engine_id, language, support_silence, need_credential, client->engine_changed_user_data);
246         } else {
247                 SLOG(LOG_WARN, TAG_STTC, "No registered callback function of supported languages");
248         }
249         return;
250 }
251
252 static int __stt_check_handle(stt_h stt, stt_client_s** client)
253 {
254         if (NULL == stt) {
255                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input handle is null");
256                 return STT_ERROR_INVALID_PARAMETER;
257         }
258
259         stt_client_s* temp = NULL;
260         temp = stt_client_get(stt);
261
262         /* check handle */
263         if (NULL == temp) {
264                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
265                 return STT_ERROR_INVALID_PARAMETER;
266         }
267         *client = temp;
268
269         return STT_ERROR_NONE;
270 }
271
272 int stt_create(stt_h* stt)
273 {
274         if (0 != __stt_get_feature_enabled()) {
275                 return STT_ERROR_NOT_SUPPORTED;
276         }
277         if (0 != __stt_check_privilege()) {
278                 return STT_ERROR_PERMISSION_DENIED;
279         }
280
281         SLOG(LOG_DEBUG, TAG_STTC, "===== Create STT");
282
283         if (NULL == stt) {
284                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is null");
285                 return STT_ERROR_INVALID_PARAMETER;
286         }
287
288         if (0 == stt_client_get_size()) {
289                 if (0 != stt_dbus_open_connection()) {
290                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to open connection");
291                         return STT_ERROR_OPERATION_FAILED;
292                 }
293         }
294
295         if (0 != stt_client_new(stt)) {
296                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to create client!");
297                 return STT_ERROR_OUT_OF_MEMORY;
298         }
299
300         stt_client_s* client = stt_client_get(*stt);
301         if (NULL == client) {
302                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to create client");
303                 stt_client_destroy(*stt);
304                 return STT_ERROR_OPERATION_FAILED;
305         }
306
307         int ret = stt_config_mgr_initialize(client->uid);
308         ret = __stt_convert_config_error_code(ret);
309         if (0 != ret) {
310                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to init config manager : %s", __stt_get_error_code(ret));
311                 stt_client_destroy(*stt);
312                 return ret;
313         }
314
315         ret = stt_config_mgr_set_callback(client->uid, __stt_config_engine_changed_cb, __stt_config_lang_changed_cb, NULL, client->stt);
316         ret = __stt_convert_config_error_code(ret);
317         if (0 != ret) {
318                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set config changed : %s", __stt_get_error_code(ret));
319                 stt_client_destroy(*stt);
320                 return ret;
321         }
322
323         SLOG(LOG_DEBUG, TAG_STTC, "[Success] uid(%d)", (*stt)->handle);
324
325         SLOG(LOG_DEBUG, TAG_STTC, "=====");
326         SLOG(LOG_DEBUG, TAG_STTC, " ");
327
328         return STT_ERROR_NONE;
329 }
330
331 int stt_destroy(stt_h stt)
332 {
333         stt_client_s* client = NULL;
334         if (0 != __stt_get_feature_enabled()) {
335                 return STT_ERROR_NOT_SUPPORTED;
336         }
337         if (0 != __stt_check_privilege()) {
338                 return STT_ERROR_PERMISSION_DENIED;
339         }
340         if (0 != __stt_check_handle(stt, &client)) {
341                 return STT_ERROR_INVALID_PARAMETER;
342         }
343
344         SLOG(LOG_DEBUG, TAG_STTC, "===== Destroy STT");
345
346         /* check used callback */
347         if (0 != stt_client_get_use_callback(client)) {
348                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Cannot destroy in Callback function");
349                 return STT_ERROR_OPERATION_FAILED;
350         }
351
352         stt_config_mgr_finalize(client->uid);
353
354         int ret = -1;
355
356         /* check state */
357         switch (client->current_state) {
358         case STT_STATE_PROCESSING:
359         case STT_STATE_RECORDING:
360         case STT_STATE_READY:
361                 ret = stt_dbus_request_finalize(client->uid);
362                 if (0 != ret) {
363                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request finalize : %s", __stt_get_error_code(ret));
364                 }
365         case STT_STATE_CREATED:
366                 if (NULL != g_connect_timer) {
367                         SLOG(LOG_DEBUG, TAG_STTC, "Connect Timer is deleted");
368                         ecore_timer_del(g_connect_timer);
369                         g_connect_timer = NULL;
370                 }
371
372                 /* Free resources */
373                 stt_client_destroy(stt);
374                 break;
375         default:
376                 break;
377         }
378
379         if (0 == stt_client_get_size()) {
380                 if (0 != stt_dbus_close_connection()) {
381                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to close connection");
382                 }
383         }
384
385         stt = NULL;
386
387         SLOG(LOG_DEBUG, TAG_STTC, "=====");
388         SLOG(LOG_DEBUG, TAG_STTC, " ");
389
390         return STT_ERROR_NONE;
391 }
392
393 bool __stt_config_supported_engine_cb(const char* engine_id, const char* engine_name,
394                                       const char* setting, bool support_silence, void* user_data)
395 {
396         stt_h stt = (stt_h)user_data;
397
398         stt_client_s* client = stt_client_get(stt);
399         if (NULL == client) {
400                 SLOG(LOG_ERROR, TAG_STTC, "[WARNING] A handle is not valid");
401                 return false;
402         }
403
404         /* call callback function */
405         if (NULL != client->supported_engine_cb) {
406                 return client->supported_engine_cb(stt, engine_id, engine_name, client->supported_engine_user_data);
407         } else {
408                 SLOG(LOG_WARN, TAG_STTC, "No registered callback function of supported engine");
409         }
410
411         return false;
412 }
413
414 int stt_foreach_supported_engines(stt_h stt, stt_supported_engine_cb callback, void* user_data)
415 {
416         stt_client_s* client = NULL;
417         if (0 != __stt_get_feature_enabled()) {
418                 return STT_ERROR_NOT_SUPPORTED;
419         }
420         if (0 != __stt_check_privilege()) {
421                 return STT_ERROR_PERMISSION_DENIED;
422         }
423         if (0 != __stt_check_handle(stt, &client)) {
424                 return STT_ERROR_INVALID_PARAMETER;
425         }
426
427         SLOG(LOG_DEBUG, TAG_STTC, "===== Foreach Supported engine");
428
429         if (NULL == callback) {
430                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
431                 return STT_ERROR_INVALID_PARAMETER;
432         }
433
434         if (client->current_state != STT_STATE_CREATED) {
435                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not CREATED", client->current_state);
436                 return STT_ERROR_INVALID_STATE;
437         }
438
439         client->supported_engine_cb = callback;
440         client->supported_engine_user_data = user_data;
441
442         int ret = 0;
443         ret = stt_config_mgr_get_engine_list(__stt_config_supported_engine_cb, client->stt);
444         ret = __stt_convert_config_error_code(ret);
445         if (0 != ret) {
446                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get engines : %s", __stt_get_error_code(ret));
447         }
448
449         client->supported_engine_cb = NULL;
450         client->supported_engine_user_data = NULL;
451
452         SLOG(LOG_DEBUG, TAG_STTC, "=====");
453         SLOG(LOG_DEBUG, TAG_STTC, " ");
454
455         return ret;
456 }
457
458 int stt_get_engine(stt_h stt, char** engine_id)
459 {
460         stt_client_s* client = NULL;
461         if (0 != __stt_get_feature_enabled()) {
462                 return STT_ERROR_NOT_SUPPORTED;
463         }
464         if (0 != __stt_check_privilege()) {
465                 return STT_ERROR_PERMISSION_DENIED;
466         }
467         if (0 != __stt_check_handle(stt, &client)) {
468                 return STT_ERROR_INVALID_PARAMETER;
469         }
470
471         SLOG(LOG_DEBUG, TAG_STTC, "===== Get current engine");
472
473         if (NULL == engine_id) {
474                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
475                 return STT_ERROR_INVALID_PARAMETER;
476         }
477
478         if (client->current_state != STT_STATE_CREATED) {
479                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not CREATED", client->current_state);
480                 return STT_ERROR_INVALID_STATE;
481         }
482
483         int ret = 0;
484
485         if (NULL != client->current_engine_id) {
486                 *engine_id = strdup(client->current_engine_id);
487                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current engine uuid = %s", *engine_id);
488         } else {
489
490                 ret = stt_config_mgr_get_engine(engine_id);
491                 ret = __stt_convert_config_error_code(ret);
492                 if (0 != ret) {
493                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request get current engine : %s", __stt_get_error_code(ret));
494                 } else {
495                         SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current engine uuid = %s", *engine_id);
496                 }
497         }
498
499         SLOG(LOG_DEBUG, TAG_STTC, "=====");
500         SLOG(LOG_DEBUG, TAG_STTC, " ");
501
502         return ret;
503 }
504
505 int stt_set_engine(stt_h stt, const char* engine_id)
506 {
507         stt_client_s* client = NULL;
508         if (0 != __stt_get_feature_enabled()) {
509                 return STT_ERROR_NOT_SUPPORTED;
510         }
511         if (0 != __stt_check_privilege()) {
512                 return STT_ERROR_PERMISSION_DENIED;
513         }
514         if (0 != __stt_check_handle(stt, &client)) {
515                 return STT_ERROR_INVALID_PARAMETER;
516         }
517
518         SLOG(LOG_DEBUG, TAG_STTC, "===== Set current engine");
519
520         if (NULL == engine_id) {
521                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
522                 return STT_ERROR_INVALID_PARAMETER;
523         }
524
525         /* check state */
526         if (client->current_state != STT_STATE_CREATED) {
527                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not CREATED", client->current_state);
528                 return STT_ERROR_INVALID_STATE;
529         }
530
531         if (NULL != client->current_engine_id) {
532                 free(client->current_engine_id);
533         }
534
535         client->current_engine_id = strdup(engine_id);
536
537         SLOG(LOG_DEBUG, TAG_STTC, "=====");
538         SLOG(LOG_DEBUG, TAG_STTC, " ");
539
540         return 0;
541 }
542
543 int stt_set_credential(stt_h stt, const char* credential)
544 {
545         stt_client_s* client = NULL;
546         if (0 != __stt_get_feature_enabled()) {
547                 return STT_ERROR_NOT_SUPPORTED;
548         }
549         if (0 != __stt_check_privilege()) {
550                 return STT_ERROR_PERMISSION_DENIED;
551         }
552         if (0 != __stt_check_handle(stt, &client)) {
553                 return STT_ERROR_INVALID_PARAMETER;
554         }
555
556         SLOG(LOG_DEBUG, TAG_STTC, "===== Set credential");
557
558         if (NULL == credential) {
559                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
560                 return STT_ERROR_INVALID_PARAMETER;
561         }
562
563         /* check state */
564         if (client->current_state != STT_STATE_CREATED && client->current_state != STT_STATE_READY) {
565                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not CREATED or READY", client->current_state);
566                 return STT_ERROR_INVALID_STATE;
567         }
568
569         client->credential = strdup(credential);
570
571         SLOG(LOG_DEBUG, TAG_STTC, "=====");
572         SLOG(LOG_DEBUG, TAG_STTC, " ");
573
574         return STT_ERROR_NONE;
575 }
576
577 int stt_set_private_data(stt_h stt, const char* key, const char* data)
578 {
579         stt_client_s* client = NULL;
580         if (0 != __stt_get_feature_enabled()) {
581                 return STT_ERROR_NOT_SUPPORTED;
582         }
583         if (0 != __stt_check_privilege()) {
584                 return STT_ERROR_PERMISSION_DENIED;
585         }
586         if (0 != __stt_check_handle(stt, &client)) {
587                 return STT_ERROR_INVALID_PARAMETER;
588         }
589
590         SLOG(LOG_DEBUG, TAG_STTC, "===== Set private data");
591
592         if (NULL == key || NULL == data) {
593                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid parameter");
594                 return STT_ERROR_INVALID_PARAMETER;
595         }
596
597         /* check state */
598         if (STT_STATE_READY != client->current_state) {
599                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
600                 return STT_ERROR_INVALID_STATE;
601         }
602
603         int ret = -1;
604         int count = 0;
605         while (0 != ret) {
606                 ret = stt_dbus_request_set_private_data(client->uid, key, data);
607                 if (0 != ret) {
608                         if (STT_ERROR_TIMED_OUT != ret) {
609                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set private data : %s", __stt_get_error_code(ret));
610                                 return ret;
611                         } else {
612                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry : %s", __stt_get_error_code(ret));
613                                 usleep(10000);
614                                 count++;
615                                 if (STT_RETRY_COUNT == count) {
616                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
617                                         return ret;
618                                 }
619                         }
620                 }
621         }
622
623         SLOG(LOG_DEBUG, TAG_STTC, "=====");
624         SLOG(LOG_DEBUG, TAG_STTC, "");
625
626         return STT_ERROR_NONE;
627
628 }
629 int stt_get_private_data(stt_h stt, const char* key, char** data)
630 {
631         stt_client_s* client = NULL;
632         if (0 != __stt_get_feature_enabled()) {
633                 return STT_ERROR_NOT_SUPPORTED;
634         }
635         if (0 != __stt_check_privilege()) {
636                 return STT_ERROR_PERMISSION_DENIED;
637         }
638         if (0 != __stt_check_handle(stt, &client)) {
639                 return STT_ERROR_INVALID_PARAMETER;
640         }
641
642         SLOG(LOG_DEBUG, TAG_STTC, "===== Get private data");
643
644         if (NULL == key || NULL == data) {
645                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid parameter");
646                 return STT_ERROR_INVALID_PARAMETER;
647         }
648
649         /* check state */
650         if (STT_STATE_READY != client->current_state) {
651                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
652                 return STT_ERROR_INVALID_STATE;
653         }
654
655         int ret = -1;
656         int count = 0;
657         while (0 != ret) {
658                 ret = stt_dbus_request_get_private_data(client->uid, key, data);
659                 if (0 != ret) {
660                         if (STT_ERROR_TIMED_OUT != ret) {
661                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get private data : %s", __stt_get_error_code(ret));
662                                 return ret;
663                         } else {
664                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry : %s", __stt_get_error_code(ret));
665                                 usleep(10000);
666                                 count++;
667                                 if (STT_RETRY_COUNT == count) {
668                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
669                                         return ret;
670                                 }
671                         }
672                 }
673         }
674
675         SLOG(LOG_DEBUG, TAG_STTC, "=====");
676         SLOG(LOG_DEBUG, TAG_STTC, "");
677
678         return STT_ERROR_NONE;
679 }
680 static Eina_Bool __stt_connect_daemon(void *data)
681 {
682         stt_client_s* client = (stt_client_s*)data;
683
684         if (NULL == client) {
685                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] A handle is not available");
686                 g_connect_timer = NULL;
687                 return EINA_FALSE;
688         }
689
690         /* Send hello */
691         int ret = -1;
692         ret = stt_dbus_request_hello();
693
694         if (0 != ret) {
695                 if (STT_ERROR_INVALID_STATE == ret) {
696                         g_connect_timer = NULL;
697                         return EINA_FALSE;
698                 }
699                 return EINA_TRUE;
700         }
701
702         g_connect_timer = NULL;
703         SLOG(LOG_DEBUG, TAG_STTC, "===== Connect daemon");
704
705         /* request initialization */
706         bool silence_supported = false;
707         bool credential_needed = false;
708
709         ret = stt_dbus_request_initialize(client->uid, &silence_supported, &credential_needed);
710
711         if (STT_ERROR_ENGINE_NOT_FOUND == ret) {
712                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to initialize : %s", __stt_get_error_code(ret));
713
714                 client->reason = STT_ERROR_ENGINE_NOT_FOUND;
715                 ecore_timer_add(0, __stt_notify_error, (void*)client);
716
717                 return EINA_FALSE;
718
719         } else if (STT_ERROR_NONE != ret) {
720                 SLOG(LOG_ERROR, TAG_STTC, "[WARNING] Fail to connection. Retry to connect");
721                 return EINA_TRUE;
722         } else {
723                 /* success to connect stt-daemon */
724                 client->silence_supported = silence_supported;
725                 client->credential_needed = credential_needed;
726                 SLOG(LOG_DEBUG, TAG_STTC, "Supported options : silence(%s), credential(%s)", silence_supported ? "support" : "no support", credential_needed ? "need" : "no need");
727         }
728
729         if (NULL != client->current_engine_id) {
730                 ret = -1;
731                 int count = 0;
732                 silence_supported = false;
733                 credential_needed = false;
734                 while (0 != ret) {
735                         ret = stt_dbus_request_set_current_engine(client->uid, client->current_engine_id, &silence_supported, &credential_needed);
736                         if (0 != ret) {
737                                 if (STT_ERROR_TIMED_OUT != ret) {
738                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set current engine : %s", __stt_get_error_code(ret));
739                                         return ret;
740                                 } else {
741                                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
742                                         usleep(10000);
743                                         count++;
744                                         if (STT_RETRY_COUNT == count) {
745                                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
746                                                 return ret;
747                                         }
748                                 }
749                         } else {
750                                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current engine uuid = %s", client->current_engine_id);
751
752                                 /* success to change engine */
753                                 client->silence_supported = silence_supported;
754                                 SLOG(LOG_DEBUG, TAG_STTC, "Supported options : silence(%s), credential(%s)", silence_supported ? "support" : "no support", credential_needed ? "need" : "no need");
755                         }
756                 }
757         }
758
759         SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] uid(%d)", client->uid);
760
761         client->before_state = client->current_state;
762         client->current_state = STT_STATE_READY;
763
764         if (NULL != client->state_changed_cb) {
765                 stt_client_use_callback(client);
766                 client->state_changed_cb(client->stt, client->before_state,
767                         client->current_state, client->state_changed_user_data);
768                 stt_client_not_use_callback(client);
769                 SLOG(LOG_DEBUG, TAG_STTC, "State changed callback is called");
770         } else {
771                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
772         }
773
774         SLOG(LOG_DEBUG, TAG_STTC, "=====");
775         SLOG(LOG_DEBUG, TAG_STTC, "  ");
776
777         return EINA_FALSE;
778 }
779
780 int stt_prepare(stt_h stt)
781 {
782         stt_client_s* client = NULL;
783         if (0 != __stt_get_feature_enabled()) {
784                 return STT_ERROR_NOT_SUPPORTED;
785         }
786         if (0 != __stt_check_privilege()) {
787                 return STT_ERROR_PERMISSION_DENIED;
788         }
789         if (0 != __stt_check_handle(stt, &client)) {
790                 return STT_ERROR_INVALID_PARAMETER;
791         }
792
793         /* check state */
794         if (client->current_state != STT_STATE_CREATED) {
795                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not 'CREATED'", client->current_state);
796                 return STT_ERROR_INVALID_STATE;
797         }
798
799         g_connect_timer = ecore_timer_add(0, __stt_connect_daemon, (void*)client);
800
801         SLOG(LOG_DEBUG, TAG_STTC, "=====");
802         SLOG(LOG_DEBUG, TAG_STTC, " ");
803
804         return STT_ERROR_NONE;
805 }
806
807 int stt_unprepare(stt_h stt)
808 {
809         stt_client_s* client = NULL;
810         if (0 != __stt_get_feature_enabled()) {
811                 return STT_ERROR_NOT_SUPPORTED;
812         }
813         if (0 != __stt_check_privilege()) {
814                 return STT_ERROR_PERMISSION_DENIED;
815         }
816         if (0 != __stt_check_handle(stt, &client)) {
817                 return STT_ERROR_INVALID_PARAMETER;
818         }
819
820         SLOG(LOG_DEBUG, TAG_STTC, "===== Unprepare STT");
821
822         /* check state */
823         if (client->current_state != STT_STATE_READY) {
824                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not 'READY'", client->current_state);
825                 return STT_ERROR_INVALID_STATE;
826         }
827
828         int ret = -1;
829         int count = 0;
830         while (0 != ret) {
831                 ret = stt_dbus_request_finalize(client->uid);
832                 if (0 != ret) {
833                         if (STT_ERROR_TIMED_OUT != ret) {
834                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request finalize : %s", __stt_get_error_code(ret));
835                                 break;
836                         } else {
837                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
838                                 usleep(10000);
839                                 count++;
840                                 if (STT_RETRY_COUNT == count) {
841                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
842                                         break;
843                                 }
844                         }
845                 }
846         }
847
848         client->internal_state = STT_INTERNAL_STATE_NONE;
849
850         client->before_state = client->current_state;
851         client->current_state = STT_STATE_CREATED;
852
853         if (NULL != client->state_changed_cb) {
854                 stt_client_use_callback(client);
855                 client->state_changed_cb(client->stt, client->before_state,
856                         client->current_state, client->state_changed_user_data);
857                 stt_client_not_use_callback(client);
858         } else {
859                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
860         }
861
862         if (g_connect_timer) {
863                 ecore_timer_del(g_connect_timer);
864                 g_connect_timer = NULL;
865         }
866
867         SLOG(LOG_DEBUG, TAG_STTC, "=====");
868         SLOG(LOG_DEBUG, TAG_STTC, " ");
869
870         return STT_ERROR_NONE;
871 }
872
873 bool __stt_config_supported_language_cb(const char* engine_id, const char* language, void* user_data)
874 {
875         stt_h stt = (stt_h)user_data;
876
877         stt_client_s* client = stt_client_get(stt);
878         if (NULL == client) {
879                 SLOG(LOG_ERROR, TAG_STTC, "[WARNING] A handle is not valid");
880                 return false;
881         }
882
883         /* call callback function */
884         if (NULL != client->supported_lang_cb) {
885                 return client->supported_lang_cb(stt, language, client->supported_lang_user_data);
886         } else {
887                 SLOG(LOG_WARN, TAG_STTC, "No registered callback function of supported languages");
888         }
889
890         return false;
891 }
892
893 int stt_foreach_supported_languages(stt_h stt, stt_supported_language_cb callback, void* user_data)
894 {
895         stt_client_s* client = NULL;
896         if (0 != __stt_get_feature_enabled()) {
897                 return STT_ERROR_NOT_SUPPORTED;
898         }
899         if (0 != __stt_check_privilege()) {
900                 return STT_ERROR_PERMISSION_DENIED;
901         }
902         if (0 != __stt_check_handle(stt, &client)) {
903                 return STT_ERROR_INVALID_PARAMETER;
904         }
905
906         SLOG(LOG_DEBUG, TAG_STTC, "===== Foreach Supported Language");
907
908         if (NULL == callback) {
909                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
910                 return STT_ERROR_INVALID_PARAMETER;
911         }
912
913         int ret;
914         char* current_engine_id = NULL;
915
916         if (NULL == client->current_engine_id) {
917                 ret = stt_config_mgr_get_engine(&current_engine_id);
918                 ret = __stt_convert_config_error_code(ret);
919                 if (0 != ret) {
920                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get default engine id : %s", __stt_get_error_code(ret));
921                         return ret;
922                 }
923         } else {
924                 current_engine_id = strdup(client->current_engine_id);
925                 if (NULL == current_engine_id) {
926                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory");
927                         return STT_ERROR_OUT_OF_MEMORY;
928                 }
929         }
930
931         client->supported_lang_cb = callback;
932         client->supported_lang_user_data = user_data;
933
934         ret = stt_config_mgr_get_language_list(current_engine_id, __stt_config_supported_language_cb, client->stt);
935         ret = __stt_convert_config_error_code(ret);
936         if (0 != ret) {
937                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get languages : %s", __stt_get_error_code(ret));
938         }
939
940         if (NULL != current_engine_id) {
941                 free(current_engine_id);
942         }
943
944         client->supported_lang_cb = NULL;
945         client->supported_lang_user_data = NULL;
946
947         SLOG(LOG_DEBUG, TAG_STTC, "=====");
948         SLOG(LOG_DEBUG, TAG_STTC, " ");
949
950         return ret;
951 }
952
953 int stt_get_default_language(stt_h stt, char** language)
954 {
955         stt_client_s* client = NULL;
956         if (0 != __stt_get_feature_enabled()) {
957                 return STT_ERROR_NOT_SUPPORTED;
958         }
959         if (0 != __stt_check_privilege()) {
960                 return STT_ERROR_PERMISSION_DENIED;
961         }
962         if (0 != __stt_check_handle(stt, &client)) {
963                 return STT_ERROR_INVALID_PARAMETER;
964         }
965
966         SLOG(LOG_DEBUG, TAG_STTC, "===== Get Default Language");
967
968         if (NULL == language) {
969                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
970                 return STT_ERROR_INVALID_PARAMETER;
971         }
972
973         int ret = 0;
974         ret = stt_config_mgr_get_default_language(language);
975         ret = __stt_convert_config_error_code(ret);
976         if (0 != ret) {
977                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get default language : %s", __stt_get_error_code(ret));
978         } else {
979                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Current language = %s", *language);
980         }
981
982         SLOG(LOG_DEBUG, TAG_STTC, "=====");
983         SLOG(LOG_DEBUG, TAG_STTC, " ");
984
985         return ret;
986 }
987
988 int stt_get_state(stt_h stt, stt_state_e* state)
989 {
990         stt_client_s* client = NULL;
991         if (0 != __stt_get_feature_enabled()) {
992                 return STT_ERROR_NOT_SUPPORTED;
993         }
994         if (0 != __stt_check_privilege()) {
995                 return STT_ERROR_PERMISSION_DENIED;
996         }
997         if (0 != __stt_check_handle(stt, &client)) {
998                 return STT_ERROR_INVALID_PARAMETER;
999         }
1000
1001         if (NULL == state) {
1002                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1003                 return STT_ERROR_INVALID_PARAMETER;
1004         }
1005
1006         *state = client->current_state;
1007
1008         switch (*state) {
1009         case STT_STATE_CREATED:         SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'CREATED'");        break;
1010         case STT_STATE_READY:           SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Ready'");          break;
1011         case STT_STATE_RECORDING:       SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Recording'");      break;
1012         case STT_STATE_PROCESSING:      SLOG(LOG_DEBUG, TAG_STTC, "Current state is 'Processing'");     break;
1013         default:                        SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid value");             break;
1014         }
1015
1016         return STT_ERROR_NONE;
1017 }
1018
1019 int stt_get_error_message(stt_h stt, char** err_msg)
1020 {
1021         stt_client_s* client = NULL;
1022         if (0 != __stt_get_feature_enabled()) {
1023                 return STT_ERROR_NOT_SUPPORTED;
1024         }
1025         if (0 != __stt_check_privilege()) {
1026                 return STT_ERROR_PERMISSION_DENIED;
1027         }
1028         if (0 != __stt_check_handle(stt, &client)) {
1029                 return STT_ERROR_INVALID_PARAMETER;
1030         }
1031
1032         if (NULL == err_msg) {
1033                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1034                 return STT_ERROR_INVALID_PARAMETER;
1035         }
1036
1037         if (false == g_err_callback_status) {
1038                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] This callback should be called during an err_callback");
1039                 return STT_ERROR_OPERATION_FAILED;
1040         }
1041
1042         if (NULL != client->err_msg) {
1043                 *err_msg = strdup(client->err_msg);
1044                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Error msg (%s)", *err_msg);
1045         } else {
1046                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Error msg (NULL)");
1047         }
1048
1049         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1050         SLOG(LOG_DEBUG, TAG_STTC, " ");
1051
1052         return STT_ERROR_NONE;
1053 }
1054
1055 int stt_is_recognition_type_supported(stt_h stt, const char* type, bool* support)
1056 {
1057         stt_client_s* client = NULL;
1058         if (0 != __stt_get_feature_enabled()) {
1059                 return STT_ERROR_NOT_SUPPORTED;
1060         }
1061         if (0 != __stt_check_privilege()) {
1062                 return STT_ERROR_PERMISSION_DENIED;
1063         }
1064         if (0 != __stt_check_handle(stt, &client)) {
1065                 return STT_ERROR_INVALID_PARAMETER;
1066         }
1067
1068         if (NULL == type || NULL == support) {
1069                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1070                 return STT_ERROR_INVALID_PARAMETER;
1071         }
1072
1073         /* check state */
1074         if (client->current_state != STT_STATE_READY) {
1075                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1076                 return STT_ERROR_INVALID_STATE;
1077         }
1078
1079         int ret = -1;
1080         int count = 0;
1081         while (0 != ret) {
1082                 ret = stt_dbus_request_is_recognition_type_supported(client->uid, type, support);
1083                 if (0 != ret) {
1084                         if (STT_ERROR_TIMED_OUT != ret) {
1085                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get recognition type supported : %s", __stt_get_error_code(ret));
1086                                 return ret;
1087                         } else {
1088                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1089                                 usleep(10000);
1090                                 count++;
1091                                 if (STT_RETRY_COUNT == count) {
1092                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1093                                         return ret;
1094                                 }
1095                         }
1096                 } else {
1097                         SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] recognition type is %s", *support ? "true " : "false");
1098                         break;
1099                 }
1100         }
1101
1102         return STT_ERROR_NONE;
1103 }
1104
1105 int stt_set_silence_detection(stt_h stt, stt_option_silence_detection_e type)
1106 {
1107         stt_client_s* client = NULL;
1108         if (0 != __stt_get_feature_enabled()) {
1109                 return STT_ERROR_NOT_SUPPORTED;
1110         }
1111         if (0 != __stt_check_privilege()) {
1112                 return STT_ERROR_PERMISSION_DENIED;
1113         }
1114         if (0 != __stt_check_handle(stt, &client)) {
1115                 return STT_ERROR_INVALID_PARAMETER;
1116         }
1117
1118         /* check state */
1119         if (client->current_state != STT_STATE_READY) {
1120                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1121                 return STT_ERROR_INVALID_STATE;
1122         }
1123
1124         if (true == client->silence_supported) {
1125                 if (type >= STT_OPTION_SILENCE_DETECTION_FALSE && type <= STT_OPTION_SILENCE_DETECTION_AUTO) {
1126                         client->silence = type;
1127                 } else {
1128                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Type is invalid");
1129                         return STT_ERROR_INVALID_PARAMETER;
1130                 }
1131         } else {
1132                 return STT_ERROR_NOT_SUPPORTED_FEATURE;
1133         }
1134
1135         return STT_ERROR_NONE;
1136 }
1137
1138 int stt_set_start_sound(stt_h stt, const char* filename)
1139 {
1140         stt_client_s* client = NULL;
1141         if (0 != __stt_get_feature_enabled()) {
1142                 return STT_ERROR_NOT_SUPPORTED;
1143         }
1144         if (0 != __stt_check_privilege()) {
1145                 return STT_ERROR_PERMISSION_DENIED;
1146         }
1147         if (0 != __stt_check_handle(stt, &client)) {
1148                 return STT_ERROR_INVALID_PARAMETER;
1149         }
1150
1151         SLOG(LOG_DEBUG, TAG_STTC, "===== STT SET START SOUND");
1152
1153         if (NULL == filename) {
1154                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1155                 return STT_ERROR_INVALID_PARAMETER;
1156         }
1157
1158         if (0 != access(filename, F_OK)) {
1159                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] File does not exist");
1160                 return STT_ERROR_INVALID_PARAMETER;
1161         }
1162
1163         /* check state */
1164         if (client->current_state != STT_STATE_READY) {
1165                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1166                 return STT_ERROR_INVALID_STATE;
1167         }
1168
1169         int ret = -1;
1170         int count = 0;
1171         while (0 != ret) {
1172                 ret = stt_dbus_request_set_start_sound(client->uid, filename);
1173                 if (0 != ret) {
1174                         if (STT_ERROR_TIMED_OUT != ret) {
1175                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set start sound : %s", __stt_get_error_code(ret));
1176                                 return ret;
1177                         } else {
1178                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1179                                 usleep(10000);
1180                                 count++;
1181                                 if (STT_RETRY_COUNT == count) {
1182                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1183                                         return ret;
1184                                 }
1185                         }
1186                 } else {
1187                         SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Set start sound : %s", filename);
1188                         break;
1189                 }
1190         }
1191
1192         return STT_ERROR_NONE;
1193 }
1194
1195 int stt_unset_start_sound(stt_h stt)
1196 {
1197         stt_client_s* client = NULL;
1198         if (0 != __stt_get_feature_enabled()) {
1199                 return STT_ERROR_NOT_SUPPORTED;
1200         }
1201         if (0 != __stt_check_privilege()) {
1202                 return STT_ERROR_PERMISSION_DENIED;
1203         }
1204         if (0 != __stt_check_handle(stt, &client)) {
1205                 return STT_ERROR_INVALID_PARAMETER;
1206         }
1207
1208         SLOG(LOG_DEBUG, TAG_STTC, "===== STT UNSET START SOUND");
1209
1210         /* check state */
1211         if (client->current_state != STT_STATE_READY) {
1212                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1213                 return STT_ERROR_INVALID_STATE;
1214         }
1215
1216         int ret = -1;
1217         int count = 0;
1218         while (0 != ret) {
1219                 ret = stt_dbus_request_unset_start_sound(client->uid);
1220                 if (0 != ret) {
1221                         if (STT_ERROR_TIMED_OUT != ret) {
1222                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to unset start sound : %s", __stt_get_error_code(ret));
1223                                 return ret;
1224                         } else {
1225                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1226                                 usleep(10000);
1227                                 count++;
1228                                 if (STT_RETRY_COUNT == count) {
1229                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1230                                         return ret;
1231                                 }
1232                         }
1233                 } else {
1234                         SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Unset start sound");
1235                         break;
1236                 }
1237         }
1238
1239         return STT_ERROR_NONE;
1240 }
1241
1242 int stt_set_stop_sound(stt_h stt, const char* filename)
1243 {
1244         stt_client_s* client = NULL;
1245         if (0 != __stt_get_feature_enabled()) {
1246                 return STT_ERROR_NOT_SUPPORTED;
1247         }
1248         if (0 != __stt_check_privilege()) {
1249                 return STT_ERROR_PERMISSION_DENIED;
1250         }
1251         if (0 != __stt_check_handle(stt, &client)) {
1252                 return STT_ERROR_INVALID_PARAMETER;
1253         }
1254
1255         SLOG(LOG_DEBUG, TAG_STTC, "===== STT SET STOP SOUND");
1256
1257         if (NULL == filename) {
1258                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1259                 return STT_ERROR_INVALID_PARAMETER;
1260         }
1261
1262         if (0 != access(filename, F_OK)) {
1263                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] File does not exist");
1264                 return STT_ERROR_INVALID_PARAMETER;
1265         }
1266
1267         /* check state */
1268         if (client->current_state != STT_STATE_READY) {
1269                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1270                 return STT_ERROR_INVALID_STATE;
1271         }
1272
1273         int ret = -1;
1274         int count = 0;
1275         while (0 != ret) {
1276                 ret = stt_dbus_request_set_stop_sound(client->uid, filename);
1277                 if (0 != ret) {
1278                         if (STT_ERROR_TIMED_OUT != ret) {
1279                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to set stop sound : %s", __stt_get_error_code(ret));
1280                                 return ret;
1281                         } else {
1282                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1283                                 usleep(10000);
1284                                 count++;
1285                                 if (STT_RETRY_COUNT == count) {
1286                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1287                                         return ret;
1288                                 }
1289                         }
1290                 } else {
1291                         SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Set stop sound : %s", filename);
1292                         break;
1293                 }
1294         }
1295
1296         return STT_ERROR_NONE;
1297 }
1298
1299 int stt_unset_stop_sound(stt_h stt)
1300 {
1301         stt_client_s* client = NULL;
1302         if (0 != __stt_get_feature_enabled()) {
1303                 return STT_ERROR_NOT_SUPPORTED;
1304         }
1305         if (0 != __stt_check_privilege()) {
1306                 return STT_ERROR_PERMISSION_DENIED;
1307         }
1308         if (0 != __stt_check_handle(stt, &client)) {
1309                 return STT_ERROR_INVALID_PARAMETER;
1310         }
1311
1312         SLOG(LOG_DEBUG, TAG_STTC, "===== STT UNSET STOP SOUND");
1313
1314         /* check state */
1315         if (client->current_state != STT_STATE_READY) {
1316                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1317                 return STT_ERROR_INVALID_STATE;
1318         }
1319
1320         int ret = -1;
1321         int count = 0;
1322         while (0 != ret) {
1323                 ret = stt_dbus_request_unset_stop_sound(client->uid);
1324                 if (0 != ret) {
1325                         if (STT_ERROR_TIMED_OUT != ret) {
1326                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to unset stop sound : %s", __stt_get_error_code(ret));
1327                                 return ret;
1328                         } else {
1329                                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] retry");
1330                                 usleep(10000);
1331                                 count++;
1332                                 if (STT_RETRY_COUNT == count) {
1333                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to request");
1334                                         return ret;
1335                                 }
1336                         }
1337                 } else {
1338                         SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Unset stop sound");
1339                         break;
1340                 }
1341         }
1342
1343         return STT_ERROR_NONE;
1344 }
1345
1346 int stt_start(stt_h stt, const char* language, const char* type)
1347 {
1348         stt_client_s* client = NULL;
1349         if (0 != __stt_get_feature_enabled()) {
1350                 return STT_ERROR_NOT_SUPPORTED;
1351         }
1352         if (0 != __stt_check_privilege()) {
1353                 return STT_ERROR_PERMISSION_DENIED;
1354         }
1355         if (0 != __stt_check_handle(stt, &client)) {
1356                 return STT_ERROR_INVALID_PARAMETER;
1357         }
1358
1359         SLOG(LOG_DEBUG, TAG_STTC, "===== STT START");
1360
1361         /* check state */
1362         if (client->current_state != STT_STATE_READY) {
1363                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State: Current state(%d) is not READY", client->current_state);
1364                 return STT_ERROR_INVALID_STATE;
1365         }
1366
1367         if (STT_INTERNAL_STATE_NONE != client->internal_state) {
1368                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is NOT none : %d", client->internal_state);
1369                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
1370         }
1371
1372         int ret = -1;
1373         char appid[128] = {0, };
1374         ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid));
1375
1376         if ((AUL_R_OK != ret) || (0 == strlen(appid))) {
1377                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to get application ID");
1378         } else {
1379                 SLOG(LOG_DEBUG, TAG_STTC, "[DEBUG] Current app id is %s", appid);
1380         }
1381
1382         char* temp = NULL;
1383         if (NULL == language) {
1384                 temp = strdup("default");
1385         } else {
1386                 temp = strdup(language);
1387         }
1388
1389         if (true == client->credential_needed && NULL == client->credential) {
1390                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Do not have app credential for this engine(%s)", client->current_engine_id);
1391                 return STT_ERROR_PERMISSION_DENIED;
1392         }
1393
1394         ret = stt_dbus_request_start(client->uid, temp, type, client->silence, appid, client->credential);
1395         if (0 != ret) {
1396                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to start : %s", __stt_get_error_code(ret));
1397         } else {
1398                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Start is successful but not done");
1399                 client->internal_state = STT_INTERNAL_STATE_STARTING;
1400         }
1401
1402         if (NULL != temp)       free(temp);
1403
1404         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1405         SLOG(LOG_DEBUG, TAG_STTC, " ");
1406
1407         return ret;
1408 }
1409
1410 int stt_stop(stt_h stt)
1411 {
1412         stt_client_s* client = NULL;
1413         if (0 != __stt_get_feature_enabled()) {
1414                 return STT_ERROR_NOT_SUPPORTED;
1415         }
1416         if (0 != __stt_check_privilege()) {
1417                 return STT_ERROR_PERMISSION_DENIED;
1418         }
1419         if (0 != __stt_check_handle(stt, &client)) {
1420                 return STT_ERROR_INVALID_PARAMETER;
1421         }
1422
1423         SLOG(LOG_DEBUG, TAG_STTC, "===== STT STOP");
1424
1425         /* check state */
1426         if (client->current_state != STT_STATE_RECORDING) {
1427                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Current state(%d) is NOT RECORDING", client->current_state);
1428                 return STT_ERROR_INVALID_STATE;
1429         }
1430
1431         if (STT_INTERNAL_STATE_STARTING == client->internal_state) {
1432                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STARTING : %d", client->internal_state);
1433                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
1434         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state) {
1435                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is CANCELING : %d", client->internal_state);
1436                 return STT_ERROR_IN_PROGRESS_TO_READY;
1437         } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state) {
1438                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STOPPING : %d", client->internal_state);
1439                 return STT_ERROR_IN_PROGRESS_TO_PROCESSING;
1440         }
1441
1442         int ret = stt_dbus_request_stop(client->uid);
1443
1444         if (0 != ret) {
1445                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to stop : %s", __stt_get_error_code(ret));
1446         } else {
1447                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Stop is successful but not done");
1448                 client->internal_state = STT_INTERNAL_STATE_STOPPING;
1449         }
1450
1451         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1452         SLOG(LOG_DEBUG, TAG_STTC, " ");
1453
1454         return ret;
1455 }
1456
1457
1458 int stt_cancel(stt_h stt)
1459 {
1460         stt_client_s* client = NULL;
1461         if (0 != __stt_get_feature_enabled()) {
1462                 return STT_ERROR_NOT_SUPPORTED;
1463         }
1464         if (0 != __stt_check_privilege()) {
1465                 return STT_ERROR_PERMISSION_DENIED;
1466         }
1467         if (0 != __stt_check_handle(stt, &client)) {
1468                 return STT_ERROR_INVALID_PARAMETER;
1469         }
1470
1471         SLOG(LOG_DEBUG, TAG_STTC, "===== STT CANCEL");
1472
1473         /* check state */
1474         if (STT_STATE_RECORDING != client->current_state && STT_STATE_PROCESSING != client->current_state) {
1475                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid state : Current state(%d) is 'Ready'", client->current_state);
1476                 return STT_ERROR_INVALID_STATE;
1477         }
1478
1479         if (STT_INTERNAL_STATE_STARTING == client->internal_state) {
1480                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STARTING : %d", client->internal_state);
1481                 return STT_ERROR_IN_PROGRESS_TO_RECORDING;
1482         } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state) {
1483                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is STOPPING : %d", client->internal_state);
1484                 return STT_ERROR_IN_PROGRESS_TO_PROCESSING;
1485         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state) {
1486                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Invalid State : Internal state is CANCELING : %d", client->internal_state);
1487                 return STT_ERROR_IN_PROGRESS_TO_READY;
1488         }
1489
1490         int ret = stt_dbus_request_cancel(client->uid);
1491         if (0 != ret) {
1492                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to cancel : %s", __stt_get_error_code(ret));
1493         } else {
1494                 SLOG(LOG_DEBUG, TAG_STTC, "[SUCCESS] Cancel is successful but not done");
1495                 client->internal_state = STT_INTERNAL_STATE_CANCELING;
1496         }
1497
1498         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1499         SLOG(LOG_DEBUG, TAG_STTC, " ");
1500
1501         return ret;
1502 }
1503
1504 int __stt_cb_set_volume(int uid, float volume)
1505 {
1506         stt_client_s* client = NULL;
1507
1508         client = stt_client_get_by_uid(uid);
1509         if (NULL == client) {
1510                 SLOG(LOG_ERROR, TAG_STTC, "Handle is NOT valid");
1511                 return STT_ERROR_INVALID_PARAMETER;
1512         }
1513
1514         if (STT_STATE_RECORDING != client->current_state) {
1515                 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Invalid state : NO 'Recording' state, cur(%d)", client->current_state);
1516                 return STT_ERROR_INVALID_STATE;
1517         }
1518
1519         g_volume_db = volume;
1520         SLOG(LOG_DEBUG, TAG_STTC, "Set volume (%f)", g_volume_db);
1521
1522         return 0;
1523 }
1524
1525 int stt_get_recording_volume(stt_h stt, float* volume)
1526 {
1527         stt_client_s* client = NULL;
1528         if (0 != __stt_get_feature_enabled()) {
1529                 return STT_ERROR_NOT_SUPPORTED;
1530         }
1531         if (0 != __stt_check_privilege()) {
1532                 return STT_ERROR_PERMISSION_DENIED;
1533         }
1534         if (0 != __stt_check_handle(stt, &client)) {
1535                 return STT_ERROR_INVALID_PARAMETER;
1536         }
1537
1538         if (NULL == volume) {
1539                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1540                 return STT_ERROR_INVALID_PARAMETER;
1541         }
1542
1543         if (STT_STATE_RECORDING != client->current_state) {
1544                 SLOG(LOG_DEBUG, TAG_STTC, "[ERROR] Invalid state : NO 'Recording' state, cur(%d)", client->current_state);
1545                 return STT_ERROR_INVALID_STATE;
1546         }
1547
1548         *volume = g_volume_db;
1549
1550         return STT_ERROR_NONE;
1551 }
1552
1553 bool __stt_result_time_cb(int index, int event, const char* text, long start_time, long end_time, void* user_data)
1554 {
1555         stt_client_s* client = (stt_client_s*)user_data;
1556
1557         /* check handle */
1558         if (NULL == client) {
1559                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
1560                 return EINA_FALSE;
1561         }
1562
1563         if (NULL != client->result_time_cb) {
1564                 SLOG(LOG_DEBUG, TAG_STTC, "(%d) event(%d) text(%s) start(%ld) end(%ld)",
1565                         index, event, text, start_time, end_time);
1566                 client->result_time_cb(client->stt, index, (stt_result_time_event_e)event,
1567                         text, start_time, end_time, client->result_time_user_data);
1568         } else {
1569                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Callback is NULL");
1570                 return false;
1571         }
1572
1573         return true;
1574 }
1575
1576 int stt_foreach_detailed_result(stt_h stt, stt_result_time_cb callback, void* user_data)
1577 {
1578         stt_client_s* client = NULL;
1579         if (0 != __stt_get_feature_enabled()) {
1580                 return STT_ERROR_NOT_SUPPORTED;
1581         }
1582         if (0 != __stt_check_privilege()) {
1583                 return STT_ERROR_PERMISSION_DENIED;
1584         }
1585         if (0 != __stt_check_handle(stt, &client)) {
1586                 return STT_ERROR_INVALID_PARAMETER;
1587         }
1588
1589         SLOG(LOG_DEBUG, TAG_STTC, "===== STT FOREACH DETAILED RESULT");
1590
1591         if (NULL == callback) {
1592                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Input parameter is NULL");
1593                 return STT_ERROR_INVALID_PARAMETER;
1594         }
1595
1596         client->result_time_cb = callback;
1597         client->result_time_user_data = user_data;
1598
1599         int ret = -1;
1600         ret = stt_config_mgr_foreach_time_info(__stt_result_time_cb, client);
1601         ret = __stt_convert_config_error_code(ret);
1602         if (0 != ret) {
1603                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to foreach time info : %s", __stt_get_error_code(ret));
1604         }
1605
1606         client->result_time_cb = NULL;
1607         client->result_time_user_data = NULL;
1608
1609         SLOG(LOG_DEBUG, TAG_STTC, "=====");
1610         SLOG(LOG_DEBUG, TAG_STTC, " ");
1611
1612         return ret;
1613 }
1614
1615 static Eina_Bool __stt_notify_error(void *data)
1616 {
1617         stt_client_s* client = (stt_client_s*)data;
1618
1619         SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error from sttd");
1620
1621         /* check handle */
1622         if (NULL == client) {
1623                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
1624                 return EINA_FALSE;
1625         }
1626
1627         if (NULL == stt_client_get_by_uid(client->uid))
1628                 return EINA_FALSE;
1629
1630         if (NULL != client->error_cb) {
1631                 stt_client_use_callback(client);
1632                 g_err_callback_status = true;
1633                 client->error_cb(client->stt, client->reason, client->error_user_data);
1634                 g_err_callback_status = false;
1635                 stt_client_not_use_callback(client);
1636                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is called : reason [%d]", client->reason);
1637         } else {
1638                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null");
1639         }
1640
1641         return EINA_FALSE;
1642 }
1643
1644 int __stt_cb_error(int uid, int reason, char* err_msg)
1645 {
1646         stt_client_s* client = stt_client_get_by_uid(uid);
1647         if (NULL == client) {
1648                 SLOG(LOG_ERROR, TAG_STTC, "Handle not found");
1649                 return -1;
1650         }
1651
1652         client->reason = reason;
1653         client->internal_state = STT_INTERNAL_STATE_NONE;
1654         if (NULL != client->err_msg) {
1655                 free(client->err_msg);
1656                 client->err_msg = NULL;
1657         }
1658         client->err_msg = strdup(err_msg);
1659
1660         SLOG(LOG_INFO, TAG_STTC, "internal state is initialized to 0");
1661
1662         if (NULL != client->error_cb) {
1663                 ecore_timer_add(0, __stt_notify_error, client);
1664         } else {
1665                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Error callback is null");
1666         }
1667
1668         if (STT_ERROR_SERVICE_RESET == reason) {
1669                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] Service reset");
1670
1671                 client->current_state = STT_STATE_CREATED;
1672                 if (0 != stt_prepare(client->stt)) {
1673                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to prepare");
1674                 }
1675         }
1676
1677         return 0;
1678 }
1679
1680 static void __stt_notify_state_changed(void *data)
1681 {
1682         stt_client_s* client = (stt_client_s*)data;
1683
1684         /* check handle */
1685         if (NULL == client) {
1686                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
1687                 return;
1688         }
1689
1690         if (NULL == stt_client_get_by_uid(client->uid)) {
1691                 return;
1692         }
1693
1694         if (STT_INTERNAL_STATE_STARTING == client->internal_state && STT_STATE_RECORDING == client->current_state) {
1695                 client->internal_state = STT_INTERNAL_STATE_NONE;
1696                 SLOG(LOG_DEBUG, TAG_STTC, "Internal state change to NONE");
1697         } else if (STT_INTERNAL_STATE_STOPPING == client->internal_state && STT_STATE_PROCESSING == client->current_state) {
1698                 client->internal_state = STT_INTERNAL_STATE_NONE;
1699                 SLOG(LOG_DEBUG, TAG_STTC, "Internal state change to NONE");
1700         } else if (STT_INTERNAL_STATE_CANCELING == client->internal_state && STT_STATE_READY == client->current_state) {
1701                 client->internal_state = STT_INTERNAL_STATE_NONE;
1702                 SLOG(LOG_DEBUG, TAG_STTC, "Internal state change to NONE");
1703         }
1704
1705         if (NULL != client->state_changed_cb) {
1706                 stt_client_use_callback(client);
1707                 client->state_changed_cb(client->stt, client->before_state,
1708                         client->current_state, client->state_changed_user_data);
1709                 stt_client_not_use_callback(client);
1710                 SLOG(LOG_DEBUG, TAG_STTC, "State changed callback is called");
1711         } else {
1712                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
1713         }
1714
1715         return;
1716 }
1717
1718 static Eina_Bool __stt_notify_result(void *data)
1719 {
1720         stt_client_s* client = (stt_client_s*)data;
1721
1722         /* check handle */
1723         if (NULL == client) {
1724                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to notify error : A handle is not valid");
1725                 return EINA_FALSE;
1726         }
1727
1728         if (NULL == stt_client_get_by_uid(client->uid)) {
1729                 return EINA_FALSE;
1730         }
1731
1732         if (NULL != client->recognition_result_cb) {
1733                 stt_client_use_callback(client);
1734                 client->recognition_result_cb(client->stt, client->event, (const char**)client->data_list, client->data_count,
1735                         client->msg, client->recognition_result_user_data);
1736                 stt_client_not_use_callback(client);
1737                 SLOG(LOG_DEBUG, TAG_STTC, "client recognition result callback called");
1738         } else {
1739                 SLOG(LOG_WARN, TAG_STTC, "[WARNING] User recognition result callback is NULL");
1740         }
1741
1742         if (NULL != client->msg) {
1743                 free(client->msg);
1744                 client->msg = NULL;
1745         }
1746
1747         if (NULL != client->data_list) {
1748                 char **temp = NULL;
1749                 temp = client->data_list;
1750
1751                 int i = 0;
1752                 for (i = 0; i < client->data_count; i++) {
1753                         if (NULL != temp[i]) {
1754                                 free(temp[i]);
1755                                 temp[i] = NULL;
1756                         } else {
1757                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Result data is error");
1758                         }
1759                 }
1760                 free(client->data_list);
1761                 client->data_list = NULL;
1762         }
1763
1764         client->data_count = 0;
1765
1766         stt_config_mgr_remove_time_info_file();
1767
1768         if (STT_RESULT_EVENT_FINAL_RESULT == client->event || STT_RESULT_EVENT_ERROR == client->event) {
1769                 client->before_state = client->current_state;
1770                 client->current_state = STT_STATE_READY;
1771
1772                 if (NULL != client->state_changed_cb) {
1773                         ecore_main_loop_thread_safe_call_async(__stt_notify_state_changed, client);
1774                 } else {
1775                         SLOG(LOG_WARN, TAG_STTC, "[WARNING] State changed callback is null");
1776                 }
1777         }
1778
1779         return EINA_FALSE;
1780 }
1781
1782 int __stt_cb_result(int uid, int event, char** data, int data_count, const char* msg)
1783 {
1784         stt_client_s* client = NULL;
1785
1786         client = stt_client_get_by_uid(uid);
1787         if (NULL == client) {
1788                 SLOG(LOG_ERROR, TAG_STTC, "Handle is NOT valid");
1789                 return STT_ERROR_INVALID_PARAMETER;
1790         }
1791
1792         if (NULL != msg)
1793                 SLOG(LOG_DEBUG, TAG_STTC, "Recognition Result Message = %s", msg);
1794
1795         int i = 0;
1796         for (i = 0; i < data_count; i++) {
1797                 if (NULL != data[i])
1798                         SLOG(LOG_DEBUG, TAG_STTC, "Recognition Result[%d] = %s", i, data[i]);
1799         }
1800
1801         if (NULL != client->recognition_result_cb) {
1802                 client->event = event;
1803                 if (NULL != msg) {
1804                         client->msg = strdup(msg);
1805                 }
1806
1807                 client->data_count = data_count;
1808
1809                 if (data_count > 0) {
1810                         char **temp = NULL;
1811                         temp = (char**)calloc(data_count, sizeof(char*));
1812                         if (NULL == temp) {
1813                                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Fail to allocate memory");
1814                                 return STT_ERROR_OUT_OF_MEMORY;
1815                         }
1816
1817                         for (i = 0; i < data_count; i++) {
1818                                 if (NULL != data[i])
1819                                         temp[i] = strdup(data[i]);
1820                                 else
1821                                         SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Result data is error");
1822                         }
1823
1824                         client->data_list = temp;
1825                 }
1826         } else {
1827                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] User result callback is null");
1828         }
1829
1830         ecore_timer_add(0, __stt_notify_result, client);
1831
1832         return STT_ERROR_NONE;
1833 }
1834
1835 int __stt_cb_set_state(int uid, int state)
1836 {
1837         stt_client_s* client = stt_client_get_by_uid(uid);
1838         if (NULL == client) {
1839                 SLOG(LOG_ERROR, TAG_STTC, "Handle not found");
1840                 return -1;
1841         }
1842
1843         stt_state_e state_from_daemon = (stt_state_e)state;
1844
1845         if (client->current_state == state_from_daemon) {
1846                 SLOG(LOG_DEBUG, TAG_STTC, "Current state has already been %d", client->current_state);
1847                 return 0;
1848         }
1849
1850         client->before_state = client->current_state;
1851         client->current_state = state_from_daemon;
1852
1853         ecore_main_loop_thread_safe_call_async(__stt_notify_state_changed, client);
1854         return 0;
1855 }
1856
1857 int stt_set_recognition_result_cb(stt_h stt, stt_recognition_result_cb callback, void* user_data)
1858 {
1859         stt_client_s* client = NULL;
1860         if (0 != __stt_get_feature_enabled()) {
1861                 return STT_ERROR_NOT_SUPPORTED;
1862         }
1863         if (0 != __stt_check_privilege()) {
1864                 return STT_ERROR_PERMISSION_DENIED;
1865         }
1866         if (0 != __stt_check_handle(stt, &client)) {
1867                 return STT_ERROR_INVALID_PARAMETER;
1868         }
1869
1870         if (callback == NULL)
1871                 return STT_ERROR_INVALID_PARAMETER;
1872
1873         if (STT_STATE_CREATED != client->current_state) {
1874                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
1875                 return STT_ERROR_INVALID_STATE;
1876         }
1877
1878         client->recognition_result_cb = callback;
1879         client->recognition_result_user_data = user_data;
1880
1881         return 0;
1882 }
1883
1884 int stt_unset_recognition_result_cb(stt_h stt)
1885 {
1886         stt_client_s* client = NULL;
1887         if (0 != __stt_get_feature_enabled()) {
1888                 return STT_ERROR_NOT_SUPPORTED;
1889         }
1890         if (0 != __stt_check_privilege()) {
1891                 return STT_ERROR_PERMISSION_DENIED;
1892         }
1893         if (0 != __stt_check_handle(stt, &client)) {
1894                 return STT_ERROR_INVALID_PARAMETER;
1895         }
1896
1897         if (STT_STATE_CREATED != client->current_state) {
1898                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
1899                 return STT_ERROR_INVALID_STATE;
1900         }
1901
1902         client->recognition_result_cb = NULL;
1903         client->recognition_result_user_data = NULL;
1904
1905         return 0;
1906 }
1907
1908 int stt_set_state_changed_cb(stt_h stt, stt_state_changed_cb callback, void* user_data)
1909 {
1910         stt_client_s* client = NULL;
1911         if (0 != __stt_get_feature_enabled()) {
1912                 return STT_ERROR_NOT_SUPPORTED;
1913         }
1914         if (0 != __stt_check_privilege()) {
1915                 return STT_ERROR_PERMISSION_DENIED;
1916         }
1917         if (0 != __stt_check_handle(stt, &client)) {
1918                 return STT_ERROR_INVALID_PARAMETER;
1919         }
1920
1921         if (NULL == callback)
1922                 return STT_ERROR_INVALID_PARAMETER;
1923
1924         if (STT_STATE_CREATED != client->current_state) {
1925                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
1926                 return STT_ERROR_INVALID_STATE;
1927         }
1928
1929         client->state_changed_cb = callback;
1930         client->state_changed_user_data = user_data;
1931
1932         return 0;
1933 }
1934
1935 int stt_unset_state_changed_cb(stt_h stt)
1936 {
1937         stt_client_s* client = NULL;
1938         if (0 != __stt_get_feature_enabled()) {
1939                 return STT_ERROR_NOT_SUPPORTED;
1940         }
1941         if (0 != __stt_check_privilege()) {
1942                 return STT_ERROR_PERMISSION_DENIED;
1943         }
1944         if (0 != __stt_check_handle(stt, &client)) {
1945                 return STT_ERROR_INVALID_PARAMETER;
1946         }
1947
1948         if (STT_STATE_CREATED != client->current_state) {
1949                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
1950                 return STT_ERROR_INVALID_STATE;
1951         }
1952
1953         client->state_changed_cb = NULL;
1954         client->state_changed_user_data = NULL;
1955
1956         return 0;
1957 }
1958
1959 int stt_set_error_cb(stt_h stt, stt_error_cb callback, void* user_data)
1960 {
1961         stt_client_s* client = NULL;
1962         if (0 != __stt_get_feature_enabled()) {
1963                 return STT_ERROR_NOT_SUPPORTED;
1964         }
1965         if (0 != __stt_check_privilege()) {
1966                 return STT_ERROR_PERMISSION_DENIED;
1967         }
1968         if (0 != __stt_check_handle(stt, &client)) {
1969                 return STT_ERROR_INVALID_PARAMETER;
1970         }
1971
1972         if (NULL == callback)
1973                 return STT_ERROR_INVALID_PARAMETER;
1974
1975         if (STT_STATE_CREATED != client->current_state) {
1976                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
1977                 return STT_ERROR_INVALID_STATE;
1978         }
1979
1980         client->error_cb = callback;
1981         client->error_user_data = user_data;
1982
1983         return 0;
1984 }
1985
1986 int stt_unset_error_cb(stt_h stt)
1987 {
1988         stt_client_s* client = NULL;
1989         if (0 != __stt_get_feature_enabled()) {
1990                 return STT_ERROR_NOT_SUPPORTED;
1991         }
1992         if (0 != __stt_check_privilege()) {
1993                 return STT_ERROR_PERMISSION_DENIED;
1994         }
1995         if (0 != __stt_check_handle(stt, &client)) {
1996                 return STT_ERROR_INVALID_PARAMETER;
1997         }
1998
1999         if (STT_STATE_CREATED != client->current_state) {
2000                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2001                 return STT_ERROR_INVALID_STATE;
2002         }
2003
2004         client->error_cb = NULL;
2005         client->error_user_data = NULL;
2006
2007         return 0;
2008 }
2009
2010 int stt_set_default_language_changed_cb(stt_h stt, stt_default_language_changed_cb callback, void* user_data)
2011 {
2012         stt_client_s* client = NULL;
2013         if (0 != __stt_get_feature_enabled()) {
2014                 return STT_ERROR_NOT_SUPPORTED;
2015         }
2016         if (0 != __stt_check_privilege()) {
2017                 return STT_ERROR_PERMISSION_DENIED;
2018         }
2019         if (0 != __stt_check_handle(stt, &client)) {
2020                 return STT_ERROR_INVALID_PARAMETER;
2021         }
2022
2023         if (NULL == callback)
2024                 return STT_ERROR_INVALID_PARAMETER;
2025
2026         if (STT_STATE_CREATED != client->current_state) {
2027                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2028                 return STT_ERROR_INVALID_STATE;
2029         }
2030
2031         client->default_lang_changed_cb = callback;
2032         client->default_lang_changed_user_data = user_data;
2033
2034         return 0;
2035 }
2036
2037 int stt_unset_default_language_changed_cb(stt_h stt)
2038 {
2039         stt_client_s* client = NULL;
2040         if (0 != __stt_get_feature_enabled()) {
2041                 return STT_ERROR_NOT_SUPPORTED;
2042         }
2043         if (0 != __stt_check_privilege()) {
2044                 return STT_ERROR_PERMISSION_DENIED;
2045         }
2046         if (0 != __stt_check_handle(stt, &client)) {
2047                 return STT_ERROR_INVALID_PARAMETER;
2048         }
2049
2050         if (STT_STATE_CREATED != client->current_state) {
2051                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2052                 return STT_ERROR_INVALID_STATE;
2053         }
2054
2055         client->default_lang_changed_cb = NULL;
2056         client->default_lang_changed_user_data = NULL;
2057
2058         return 0;
2059 }
2060
2061 int stt_set_engine_changed_cb(stt_h stt, stt_engine_changed_cb callback, void* user_data)
2062 {
2063         stt_client_s* client = NULL;
2064         if (0 != __stt_get_feature_enabled()) {
2065                 return STT_ERROR_NOT_SUPPORTED;
2066         }
2067         if (0 != __stt_check_privilege()) {
2068                 return STT_ERROR_PERMISSION_DENIED;
2069         }
2070         if (0 != __stt_check_handle(stt, &client)) {
2071                 return STT_ERROR_INVALID_PARAMETER;
2072         }
2073
2074         if (NULL == callback)
2075                 return STT_ERROR_INVALID_PARAMETER;
2076
2077         if (STT_STATE_CREATED != client->current_state) {
2078                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2079                 return STT_ERROR_INVALID_STATE;
2080         }
2081
2082         client->engine_changed_cb = callback;
2083         client->engine_changed_user_data = user_data;
2084
2085         return 0;
2086 }
2087
2088 int stt_unset_engine_changed_cb(stt_h stt)
2089 {
2090         stt_client_s* client = NULL;
2091         if (0 != __stt_get_feature_enabled()) {
2092                 return STT_ERROR_NOT_SUPPORTED;
2093         }
2094         if (0 != __stt_check_privilege()) {
2095                 return STT_ERROR_PERMISSION_DENIED;
2096         }
2097         if (0 != __stt_check_handle(stt, &client)) {
2098                 return STT_ERROR_INVALID_PARAMETER;
2099         }
2100
2101         if (STT_STATE_CREATED != client->current_state) {
2102                 SLOG(LOG_ERROR, TAG_STTC, "[ERROR] Current state(%d) is not 'Created'", client->current_state);
2103                 return STT_ERROR_INVALID_STATE;
2104         }
2105
2106         client->engine_changed_cb = NULL;
2107         client->engine_changed_user_data = NULL;
2108
2109         return 0;
2110 }