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