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