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