Fix dbus delay when requesting hello
[platform/core/uifw/stt.git] / common / stt_engine.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 <dlog.h>
15 #include <dlfcn.h>
16 #include <dirent.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <stdbool.h>
20
21 #include "stt_engine.h"
22 #include "sttd_engine_agent.h"
23
24 /*
25 * Internal data structure
26 */
27
28 typedef struct {
29         char*   engine_path;
30         stte_request_callback_s *callback;
31 } sttengine_s;
32
33 extern const char* stt_tag();
34
35 /** stt engine */
36 static sttengine_s *g_engine = NULL;
37
38 static bool g_is_from_lib = false;
39
40 /** callback functions */
41 static stt_engine_result_cb g_result_cb = NULL;
42 static stte_private_data_set_cb g_set_private_data_cb = NULL;
43 static stte_private_data_requested_cb g_get_private_data_cb = NULL;
44
45
46 static int __stt_set_engine_from(bool is_from_lib)
47 {
48         g_is_from_lib = is_from_lib;
49         return 0;
50 }
51
52 static bool __stt_get_engine_from(void)
53 {
54         return g_is_from_lib;
55 }
56
57 static const char* __stt_get_engine_error_code(stte_error_e err)
58 {
59         switch (err) {
60         case STTE_ERROR_NONE:                   return "STTE_ERROR_NONE";
61         case STTE_ERROR_OUT_OF_MEMORY:          return "STTE_ERROR_OUT_OF_MEMORY";
62         case STTE_ERROR_IO_ERROR:               return "STTE_ERROR_IO_ERROR";
63         case STTE_ERROR_INVALID_PARAMETER:      return "STTE_ERROR_INVALID_PARAMETER";
64         case STTE_ERROR_NETWORK_DOWN:           return "STTE_ERROR_NETWORK_DOWN";
65         case STTE_ERROR_PERMISSION_DENIED:      return "STTE_ERROR_PERMISSION_DENIED";
66         case STTE_ERROR_NOT_SUPPORTED:          return "STTE_ERROR_NOT_SUPPORTED";
67         case STTE_ERROR_INVALID_STATE:          return "STTE_ERROR_INVALID_STATE";
68         case STTE_ERROR_INVALID_LANGUAGE:       return "STTE_ERROR_INVALID_LANGUAGE";
69         case STTE_ERROR_OPERATION_FAILED:       return "STTE_ERROR_OPERATION_FAILED";
70         case STTE_ERROR_NOT_SUPPORTED_FEATURE:  return "STTE_ERROR_NOT_SUPPORTED_FEATURE";
71         case STTE_ERROR_RECORDING_TIMED_OUT:    return "STTE_ERROR_RECORDING_TIMED_OUT";
72         default:
73                 return "Invalid error code";
74         }
75 }
76
77 /* Register engine id */
78 int stt_engine_load(const char* filepath, stte_request_callback_s *callback)
79 {
80         if (NULL == callback || NULL == filepath) {
81                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
82                 return STTE_ERROR_INVALID_PARAMETER;
83         }
84
85         /* allocation memory */
86         if (NULL != g_engine) {
87                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine is already loaded");
88         } else {
89                 g_engine = (sttengine_s*)calloc(1, sizeof(sttengine_s));
90                 if (NULL == g_engine) {
91                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to allocate memory");
92                         return STTE_ERROR_OUT_OF_MEMORY;
93                 }
94
95                 /* load engine */
96                 g_engine->callback = callback;
97                 g_engine->engine_path = strdup(filepath);
98         }
99
100         SLOG(LOG_DEBUG, stt_tag(), "[Engine Success] Load engine : version(%d)", g_engine->callback->version);
101
102         return 0;
103 }
104
105 /* Unregister engine id */
106 int stt_engine_unload()
107 {
108         if (NULL == g_engine) {
109                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
110                 return STTE_ERROR_OPERATION_FAILED;
111         }
112
113         g_engine->callback = NULL;
114
115         if (NULL != g_engine->engine_path) {
116                 free(g_engine->engine_path);
117                 g_engine->engine_path = NULL;
118         }
119
120         free(g_engine);
121         g_engine = NULL;
122
123         return 0;
124 }
125
126
127 /* Initialize / Deinitialize */
128 int stt_engine_initialize(bool is_from_lib)
129 {
130         if (NULL == g_engine) {
131                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
132                 return STTE_ERROR_OPERATION_FAILED;
133         }
134
135         if (NULL == g_engine->callback) {
136                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
137                 return STTE_ERROR_OPERATION_FAILED;
138         }
139
140         if (NULL == g_engine->callback->initialize) {
141                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
142                 return STTE_ERROR_OPERATION_FAILED;
143         }
144
145         int ret;
146         ret = __stt_set_engine_from(is_from_lib);
147         if (0 != ret) {
148                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to set engine : %s", __stt_get_engine_error_code(ret));
149                 return STTE_ERROR_OPERATION_FAILED;
150         }
151
152         ret = g_engine->callback->initialize();
153         if (0 != ret) {
154                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to initialize : %s", __stt_get_engine_error_code(ret));
155         }
156
157         return ret;
158 }
159
160 int stt_engine_deinitialize()
161 {
162         if (NULL == g_engine) {
163                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
164                 return STTE_ERROR_OPERATION_FAILED;
165         }
166
167         if (NULL == g_engine->callback) {
168                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
169                 return STTE_ERROR_OPERATION_FAILED;
170         }
171
172         if (NULL == g_engine->callback->deinitialize) {
173                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
174                 return STTE_ERROR_OPERATION_FAILED;
175         }
176
177         int ret;
178         ret = g_engine->callback->deinitialize();
179         if (0 != ret) {
180                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] Fail to deinitialize : %s", __stt_get_engine_error_code(ret));
181         }
182
183         return ret;
184 }
185
186 static bool __supported_language_cb(const char* language, void* user_data)
187 {
188         GSList** lang_list = (GSList**)user_data;
189
190         if (NULL == language || NULL == lang_list) {
191                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Input parameter is NULL in callback!!!!");
192                 return false;
193         }
194
195         char* temp_lang = g_strdup(language);
196
197         *lang_list = g_slist_append(*lang_list, temp_lang);
198
199         return true;
200 }
201
202 /* Get option */
203 int stt_engine_get_supported_langs(GSList** lang_list)
204 {
205         if (NULL == lang_list) {
206                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
207                 return STTE_ERROR_INVALID_PARAMETER;
208         }
209
210         if (NULL == g_engine) {
211                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
212                 return STTE_ERROR_OPERATION_FAILED;
213         }
214
215         if (NULL == g_engine->callback) {
216                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
217                 return STTE_ERROR_OPERATION_FAILED;
218         }
219
220         if (NULL == g_engine->callback->foreach_langs) {
221                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
222                 return STTE_ERROR_OPERATION_FAILED;
223         }
224
225         int ret;
226         ret = g_engine->callback->foreach_langs(__supported_language_cb, (void*)lang_list);
227         if (0 != ret) {
228                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] get language list error : %s", __stt_get_engine_error_code(ret));
229         }
230
231         return ret;
232 }
233
234 int stt_engine_is_valid_language(const char* language, bool *is_valid)
235 {
236         if (NULL == language || NULL == is_valid) {
237                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
238                 return STTE_ERROR_INVALID_PARAMETER;
239         }
240
241         if (NULL == g_engine) {
242                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
243                 return STTE_ERROR_OPERATION_FAILED;
244         }
245
246         if (NULL == g_engine->callback) {
247                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
248                 return STTE_ERROR_OPERATION_FAILED;
249         }
250
251         if (NULL == g_engine->callback->is_valid_lang) {
252                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
253                 return STTE_ERROR_OPERATION_FAILED;
254         }
255
256         int ret = STTE_ERROR_NONE;
257         ret = g_engine->callback->is_valid_lang(language, is_valid);
258         if (0 != ret) {
259                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to check valid language(%d)", ret);
260         }
261         return ret;
262 }
263
264 int stt_engine_set_private_data(const char* key, const char* data)
265 {
266         if (NULL == key || NULL == data) {
267                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
268                 return STTE_ERROR_INVALID_PARAMETER;
269         }
270
271         int ret = STTE_ERROR_NONE;
272         if (NULL != g_set_private_data_cb) {
273                 ret = g_set_private_data_cb(key, data);
274                 if (0 != ret) {
275                         SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to set private data(%d)", ret);
276                 }
277         }
278
279         return ret;
280 }
281
282 int stt_engine_get_private_data(const char* key, char** data)
283 {
284         if (NULL == key || NULL == data) {
285                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
286                 return STTE_ERROR_INVALID_PARAMETER;
287         }
288
289         int ret = STTE_ERROR_NONE;
290         char* temp = NULL;
291         if (NULL != g_get_private_data_cb) {
292                 ret = g_get_private_data_cb(key, &temp);
293                 if (0 != ret) {
294                         SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to get private data(%d)", ret);
295                         return ret;
296                 }
297         } else {
298                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] There's no private data function)");
299         }
300
301         if (NULL == temp)
302                 *data = strdup("NULL");
303         else
304                 *data = strdup(temp);
305
306         return STTE_ERROR_NONE;
307 }
308
309 int stt_engine_get_first_language(char** language)
310 {
311         if (NULL == language) {
312                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
313                 return STTE_ERROR_INVALID_PARAMETER;
314         }
315
316         if (NULL == g_engine) {
317                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
318                 return STTE_ERROR_OPERATION_FAILED;
319         }
320
321         if (NULL == g_engine->callback) {
322                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
323                 return STTE_ERROR_OPERATION_FAILED;
324         }
325
326         if (NULL == g_engine->callback->foreach_langs || NULL == g_engine->callback->is_valid_lang) {
327                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
328                 return STTE_ERROR_OPERATION_FAILED;
329         }
330
331         GSList* lang_list = NULL;
332         int ret;
333         ret = g_engine->callback->foreach_langs(__supported_language_cb, &lang_list);
334         if (0 != ret) {
335                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] get language list error : %s", __stt_get_engine_error_code(ret));
336                 return ret;
337         }
338
339         GSList *iter = NULL;
340         char* data = NULL;
341
342         iter = g_slist_nth(lang_list, 0);
343         if (NULL != iter) {
344                 data = iter->data;
345
346                 bool is_valid = false;
347                 ret = g_engine->callback->is_valid_lang(data, &is_valid);
348                 if (0 == ret && true == is_valid) {
349                         *language = strdup(data);
350                 } else {
351                         ret = STTE_ERROR_OPERATION_FAILED;
352                 }
353         }
354
355         /* if list have item */
356         if (g_slist_length(lang_list) > 0) {
357                 /* Get a first item */
358                 iter = g_slist_nth(lang_list, 0);
359
360                 while (NULL != iter) {
361                         data = iter->data;
362
363                         if (NULL != data) {
364                                 free(data);
365                                 data = NULL;
366                         }
367
368                         lang_list = g_slist_remove_link(lang_list, iter);
369
370                         iter = g_slist_nth(lang_list, 0);
371                 }
372         }
373
374         return ret;
375 }
376
377 int stt_engine_support_silence(bool* support)
378 {
379         if (NULL == support) {
380                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
381                 return STTE_ERROR_INVALID_PARAMETER;
382         }
383
384         if (NULL == g_engine) {
385                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
386                 return STTE_ERROR_OPERATION_FAILED;
387         }
388
389         if (NULL == g_engine->callback) {
390                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
391                 return STTE_ERROR_OPERATION_FAILED;
392         }
393
394         if (NULL == g_engine->callback->support_silence) {
395                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
396                 return STTE_ERROR_OPERATION_FAILED;
397         }
398
399         bool result;
400         result = g_engine->callback->support_silence();
401         *support = result;
402
403         return STTE_ERROR_NONE;
404 }
405
406 int stt_engine_need_app_credential(bool* need)
407 {
408         if (NULL == need) {
409                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
410                 return STTE_ERROR_INVALID_PARAMETER;
411         }
412
413         if (NULL == g_engine) {
414                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
415                 return STTE_ERROR_OPERATION_FAILED;
416         }
417
418         if (NULL == g_engine->callback) {
419                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
420                 return STTE_ERROR_OPERATION_FAILED;
421         }
422
423         if (NULL == g_engine->callback->need_app_credential) {
424                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
425                 return STTE_ERROR_OPERATION_FAILED;
426         }
427
428         bool result;
429         result = g_engine->callback->need_app_credential();
430         *need = result;
431
432         return STTE_ERROR_NONE;
433 }
434
435 int stt_engine_support_recognition_type(const char* type, bool* support)
436 {
437         if (NULL == type || NULL == support) {
438                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
439                 return STTE_ERROR_INVALID_PARAMETER;
440         }
441
442         if (NULL == g_engine) {
443                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
444                 return STTE_ERROR_OPERATION_FAILED;
445         }
446
447         if (NULL == g_engine->callback) {
448                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
449                 return STTE_ERROR_OPERATION_FAILED;
450         }
451
452         if (NULL == g_engine->callback->support_recognition_type) {
453                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR} Invalid engine");
454                 return STTE_ERROR_OPERATION_FAILED;
455         }
456
457         int ret = STTE_ERROR_NONE;
458         ret = g_engine->callback->support_recognition_type(type, support);
459         if (0 != ret) {
460                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to get supporting recognition type(%d)", ret);
461         }
462         return ret;
463 }
464
465 int stt_engine_get_audio_type(stte_audio_type_e* types, int* rate, int* channels)
466 {
467         if (NULL == types || NULL == rate || NULL == channels) {
468                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
469                 return STTE_ERROR_INVALID_PARAMETER;
470         }
471
472         if (NULL == g_engine) {
473                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
474                 return STTE_ERROR_OPERATION_FAILED;
475         }
476
477         if (NULL == g_engine->callback) {
478                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
479                 return STTE_ERROR_OPERATION_FAILED;
480         }
481
482         if (NULL == g_engine->callback->get_audio_format) {
483                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
484                 return STTE_ERROR_OPERATION_FAILED;
485         }
486
487         int ret;
488         ret = g_engine->callback->get_audio_format(types, rate, channels);
489         if (0 != ret) {
490                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to get audio format : %s", __stt_get_engine_error_code(ret));
491         }
492
493         return ret;
494 }
495
496 /* Set option */
497 int stt_engine_set_silence_detection(bool value)
498 {
499         if (NULL == g_engine) {
500                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
501                 return STTE_ERROR_OPERATION_FAILED;
502         }
503
504         if (NULL == g_engine->callback) {
505                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
506                 return STTE_ERROR_OPERATION_FAILED;
507         }
508
509         if (NULL == g_engine->callback->set_silence_detection) {
510                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
511                 return STTE_ERROR_OPERATION_FAILED;
512         }
513
514         int ret = g_engine->callback->set_silence_detection(value);
515         if (STTE_ERROR_NOT_SUPPORTED_FEATURE == ret) {
516                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] Not support silence detection");
517         } else if (0 != ret) {
518                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to set silence detection : %d", ret);
519         }
520         return ret;
521 }
522
523 int stt_engine_check_app_agreed(const char* appid, bool* is_agreed)
524 {
525         if (NULL == is_agreed) {
526                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid parameter");
527                 return STTE_ERROR_INVALID_PARAMETER;
528         }
529
530         if (NULL == g_engine) {
531                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
532                 return STTE_ERROR_OPERATION_FAILED;
533         }
534
535         if (NULL == g_engine->callback) {
536                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
537                 return STTE_ERROR_OPERATION_FAILED;
538         }
539
540         if (NULL == g_engine->callback->check_app_agreed) {
541                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] Not support app agreement. All app is available");
542                 *is_agreed = true;
543                 return 0;
544         }
545
546         int ret = g_engine->callback->check_app_agreed(appid, is_agreed);
547         if (0 != ret) {
548                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to get app agreement : %s", __stt_get_engine_error_code(ret));
549                 *is_agreed = false;
550         }
551
552         return ret;
553 }
554
555 /* Recognition */
556 int stt_engine_recognize_start(const char* lang, const char* recognition_type, const char* appid, const char* credential, void* user_param)
557 {
558         if (NULL == lang || NULL == recognition_type) {
559                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
560                 return STTE_ERROR_INVALID_PARAMETER;
561         }
562
563         if (NULL == g_engine) {
564                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
565                 return STTE_ERROR_OPERATION_FAILED;
566         }
567
568         if (NULL == g_engine->callback) {
569                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
570                 return STTE_ERROR_OPERATION_FAILED;
571         }
572
573         if (NULL == g_engine->callback->start) {
574                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
575                 return STTE_ERROR_OPERATION_FAILED;
576         }
577
578         int ret = g_engine->callback->start(lang, recognition_type, appid, credential, user_param);
579
580         if (0 != ret) {
581                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to start recognition : %s", __stt_get_engine_error_code(ret));
582                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to start recognition : lang(%s), recognition_type(%s), credential(%s)", lang, recognition_type, credential);
583         }
584
585         return ret;
586 }
587
588 int stt_engine_set_recording_data(const void* data, unsigned int length)
589 {
590         if (NULL == data) {
591                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
592                 return STTE_ERROR_INVALID_PARAMETER;
593         }
594
595         if (NULL == g_engine) {
596                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
597                 return STTE_ERROR_OPERATION_FAILED;
598         }
599
600         if (NULL == g_engine->callback) {
601                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
602                 return STTE_ERROR_OPERATION_FAILED;
603         }
604
605         if (NULL == g_engine->callback->set_recording) {
606                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
607                 return STTE_ERROR_OPERATION_FAILED;
608         }
609
610         int ret = g_engine->callback->set_recording(data, length);
611         if (0 != ret) {
612                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] Fail to set recording : %s", __stt_get_engine_error_code(ret));
613         }
614
615         return ret;
616 }
617
618 int stt_engine_recognize_stop()
619 {
620         if (NULL == g_engine) {
621                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
622                 return STTE_ERROR_OPERATION_FAILED;
623         }
624
625         if (NULL == g_engine->callback) {
626                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
627                 return STTE_ERROR_OPERATION_FAILED;
628         }
629
630         if (NULL == g_engine->callback->stop) {
631                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
632                 return STTE_ERROR_OPERATION_FAILED;
633         }
634
635         int ret = g_engine->callback->stop();
636         if (0 != ret) {
637                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to stop : %s", __stt_get_engine_error_code(ret));
638         }
639
640         return ret;
641 }
642
643 int stt_engine_recognize_cancel()
644 {
645         if (NULL == g_engine) {
646                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
647                 return STTE_ERROR_OPERATION_FAILED;
648         }
649
650         if (NULL == g_engine->callback) {
651                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
652                 return STTE_ERROR_OPERATION_FAILED;
653         }
654
655         if (NULL == g_engine->callback->cancel) {
656                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
657                 return STTE_ERROR_OPERATION_FAILED;
658         }
659
660         int ret = g_engine->callback->cancel();
661         if (0 != ret) {
662                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to cancel : %s", __stt_get_engine_error_code(ret));
663         }
664
665         return ret;
666 }
667
668 int stt_engine_foreach_result_time(void* time_info, stte_result_time_cb callback, void* user_data)
669 {
670         if (NULL == g_engine) {
671                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
672                 return STTE_ERROR_OPERATION_FAILED;
673         }
674
675         if (NULL == g_engine->callback) {
676                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
677                 return STTE_ERROR_OPERATION_FAILED;
678         }
679
680         if (NULL == g_engine->callback->foreach_result_time) {
681                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
682                 return STTE_ERROR_OPERATION_FAILED;
683         }
684
685         int ret = g_engine->callback->foreach_result_time(time_info, callback, user_data);
686         if (0 != ret) {
687                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to foreach result time : %s", __stt_get_engine_error_code(ret));
688         }
689
690         return ret;
691 }
692
693 int stt_engine_recognize_start_file(const char* lang, const char* recognition_type, 
694                                      const char* filepath, stte_audio_type_e audio_type, int sample_rate, void* user_param)
695 {
696         if (NULL == filepath || NULL == lang || NULL == recognition_type) {
697                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
698                 return STTE_ERROR_INVALID_PARAMETER;
699         }
700
701         if (NULL == g_engine) {
702                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
703                 return STTE_ERROR_OPERATION_FAILED;
704         }
705
706         if (NULL == g_engine->callback) {
707                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
708                 return STTE_ERROR_OPERATION_FAILED;
709         }
710
711 #ifdef __UNUSED_CODES__
712         if (NULL == g_engine->callback->start_file) {
713                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine API is invalid");
714                 return STTE_ERROR_NOT_SUPPORTED_FEATURE;
715         }
716
717         int ret = g_engine->callback->start_file(lang, recognition_type, filepath, audio_type, sample_rate, user_param);
718         if (0 != ret) {
719                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to start file recognition : %s", __stt_get_engine_error_code(ret));
720         }
721 #endif
722         return 0;
723 }
724
725 int stt_engine_recognize_cancel_file()
726 {
727         if (NULL == g_engine) {
728                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
729                 return STTE_ERROR_OPERATION_FAILED;
730         }
731
732         if (NULL == g_engine->callback) {
733                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
734                 return STTE_ERROR_OPERATION_FAILED;
735         }
736
737 #ifdef __UNUSED_CODES__
738         if (NULL == g_engine->callback->cancel_file) {
739                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine API is invalid");
740                 return STTE_ERROR_NOT_SUPPORTED_FEATURE;
741         }
742
743         int ret = g_engine->callback->cancel_file();
744         if (0 != ret) {
745                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to start file recognition : %s", __stt_get_engine_error_code(ret));
746         }
747 #endif
748         return 0;
749 }
750
751 int stt_engine_set_recognition_result_cb(stt_engine_result_cb result_cb, void* user_data)
752 {
753         if (NULL == result_cb) {
754                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid parameter");
755                 return STTE_ERROR_INVALID_PARAMETER;
756         }
757
758         g_result_cb = result_cb;
759
760         return 0;
761 }
762
763 int stt_engine_send_result(stte_result_event_e event, const char* type, const char** result, int result_count,
764                                 const char* msg, void* time_info, void* user_data)
765 {
766         if (NULL == type || NULL == result) {
767                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid parameter");
768         }
769
770         int ret = STTE_ERROR_NONE;
771         if (false == __stt_get_engine_from()) {
772                 ret = sttd_engine_agent_send_result(event, type, result, result_count, msg, time_info, user_data);
773                 if (0 != ret) {
774                         SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to send result");
775                 }
776         } else {
777                 ret = g_result_cb(event, type, result, result_count, msg, time_info, user_data);
778         }
779         return ret;
780 }
781
782 int stt_engine_send_error(stte_error_e error, const char* msg)
783 {
784         int ret = STTE_ERROR_NONE;
785         ret = sttd_engine_agent_send_error(error, msg);
786         if (0 != ret) {
787                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to send error info");
788         }
789         return ret;
790 }
791
792 int stt_engine_send_speech_status(stte_speech_status_e status, void* user_data)
793 {
794         int ret = STTE_ERROR_NONE;
795         ret = sttd_engine_agent_send_speech_status(status, user_data);
796         if (0 != ret) {
797                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to send speech status");
798         }
799         return ret;
800 }
801
802 int stt_engine_set_private_data_set_cb(stte_private_data_set_cb private_data_set_cb, void* user_data)
803 {
804         if (NULL == private_data_set_cb) {
805                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid parameter");
806                 return STTE_ERROR_INVALID_PARAMETER;
807         }
808
809         g_set_private_data_cb = private_data_set_cb;
810
811         return 0;
812 }
813
814 int stt_engine_set_private_data_requested_cb(stte_private_data_requested_cb private_data_requested_cb, void* user_data)
815 {
816         if (NULL == private_data_requested_cb) {
817                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid parameter");
818                 return STTE_ERROR_INVALID_PARAMETER;
819         }
820
821         g_get_private_data_cb = private_data_requested_cb;
822
823         return 0;
824 }