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