Change to STT engine process
[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
366                         lang_list = g_slist_remove_link(lang_list, iter);
367
368                         iter = g_slist_nth(lang_list, 0);
369                 }
370         }
371
372         return ret;
373 }
374
375 int stt_engine_support_silence(bool* support)
376 {
377         if (NULL == support) {
378                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
379                 return STTE_ERROR_INVALID_PARAMETER;
380         }
381
382         if (NULL == g_engine) {
383                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
384                 return STTE_ERROR_OPERATION_FAILED;
385         }
386
387         if (NULL == g_engine->callback) {
388                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
389                 return STTE_ERROR_OPERATION_FAILED;
390         }
391
392         if (NULL == g_engine->callback->support_silence) {
393                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
394                 return STTE_ERROR_OPERATION_FAILED;
395         }
396
397         bool result;
398         result = g_engine->callback->support_silence();
399         *support = result;
400
401         return STTE_ERROR_NONE;
402 }
403
404 int stt_engine_need_app_credential(bool* need)
405 {
406         if (NULL == need) {
407                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
408                 return STTE_ERROR_INVALID_PARAMETER;
409         }
410
411         if (NULL == g_engine) {
412                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
413                 return STTE_ERROR_OPERATION_FAILED;
414         }
415
416         if (NULL == g_engine->callback) {
417                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
418                 return STTE_ERROR_OPERATION_FAILED;
419         }
420
421         if (NULL == g_engine->callback->need_app_credential) {
422                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
423                 return STTE_ERROR_OPERATION_FAILED;
424         }
425
426         bool result;
427         result = g_engine->callback->need_app_credential();
428         *need = result;
429
430         return STTE_ERROR_NONE;
431 }
432
433 int stt_engine_support_recognition_type(const char* type, bool* support)
434 {
435         if (NULL == type || NULL == support) {
436                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
437                 return STTE_ERROR_INVALID_PARAMETER;
438         }
439
440         if (NULL == g_engine) {
441                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
442                 return STTE_ERROR_OPERATION_FAILED;
443         }
444
445         if (NULL == g_engine->callback) {
446                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
447                 return STTE_ERROR_OPERATION_FAILED;
448         }
449
450         if (NULL == g_engine->callback->support_recognition_type) {
451                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR} Invalid engine");
452                 return STTE_ERROR_OPERATION_FAILED;
453         }
454
455         int ret = STTE_ERROR_NONE;
456         ret = g_engine->callback->support_recognition_type(type, support);
457         if (0 != ret) {
458                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to get supporting recognition type(%d)", ret);
459         }
460         return ret;
461 }
462
463 int stt_engine_get_audio_type(stte_audio_type_e* types, int* rate, int* channels)
464 {
465         if (NULL == types || NULL == rate || NULL == channels) {
466                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
467                 return STTE_ERROR_INVALID_PARAMETER;
468         }
469
470         if (NULL == g_engine) {
471                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
472                 return STTE_ERROR_OPERATION_FAILED;
473         }
474
475         if (NULL == g_engine->callback) {
476                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
477                 return STTE_ERROR_OPERATION_FAILED;
478         }
479
480         if (NULL == g_engine->callback->get_audio_format) {
481                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
482                 return STTE_ERROR_OPERATION_FAILED;
483         }
484
485         int ret;
486         ret = g_engine->callback->get_audio_format(types, rate, channels);
487         if (0 != ret) {
488                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to get audio format : %s", __stt_get_engine_error_code(ret));
489         }
490
491         return ret;
492 }
493
494 /* Set option */
495 int stt_engine_set_silence_detection(bool value)
496 {
497         if (NULL == g_engine) {
498                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
499                 return STTE_ERROR_OPERATION_FAILED;
500         }
501
502         if (NULL == g_engine->callback) {
503                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
504                 return STTE_ERROR_OPERATION_FAILED;
505         }
506
507         if (NULL == g_engine->callback->set_silence_detection) {
508                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
509                 return STTE_ERROR_OPERATION_FAILED;
510         }
511
512         int ret = g_engine->callback->set_silence_detection(value);
513         if (STTE_ERROR_NOT_SUPPORTED_FEATURE == ret) {
514                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] Not support silence detection");
515         } else if (0 != ret) {
516                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to set silence detection : %d", ret);
517         }
518         return ret;
519 }
520
521 int stt_engine_check_app_agreed(const char* appid, bool* is_agreed)
522 {
523         if (NULL == is_agreed) {
524                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid parameter");
525                 return STTE_ERROR_INVALID_PARAMETER;
526         }
527
528         if (NULL == g_engine) {
529                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
530                 return STTE_ERROR_OPERATION_FAILED;
531         }
532
533         if (NULL == g_engine->callback) {
534                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
535                 return STTE_ERROR_OPERATION_FAILED;
536         }
537
538         if (NULL == g_engine->callback->check_app_agreed) {
539                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] Not support app agreement. All app is available");
540                 *is_agreed = true;
541                 return 0;
542         }
543
544         int ret = g_engine->callback->check_app_agreed(appid, is_agreed);
545         if (0 != ret) {
546                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to get app agreement : %s", __stt_get_engine_error_code(ret));
547                 *is_agreed = false;
548         }
549
550         return ret;
551 }
552
553 /* Recognition */
554 int stt_engine_recognize_start(const char* lang, const char* recognition_type, const char* appid, const char* credential, void* user_param)
555 {
556         if (NULL == lang || NULL == recognition_type) {
557                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
558                 return STTE_ERROR_INVALID_PARAMETER;
559         }
560
561         if (NULL == g_engine) {
562                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
563                 return STTE_ERROR_OPERATION_FAILED;
564         }
565
566         if (NULL == g_engine->callback) {
567                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
568                 return STTE_ERROR_OPERATION_FAILED;
569         }
570
571         if (NULL == g_engine->callback->start) {
572                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
573                 return STTE_ERROR_OPERATION_FAILED;
574         }
575
576         int ret = g_engine->callback->start(lang, recognition_type, appid, credential, user_param);
577
578         if (0 != ret) {
579                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to start recognition : %s", __stt_get_engine_error_code(ret));
580                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to start recognition : lang(%s), recognition_type(%s), credential(%s)", lang, recognition_type, credential);
581         }
582
583         return ret;
584 }
585
586 int stt_engine_set_recording_data(const void* data, unsigned int length)
587 {
588         if (NULL == data) {
589                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
590                 return STTE_ERROR_INVALID_PARAMETER;
591         }
592
593         if (NULL == g_engine) {
594                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
595                 return STTE_ERROR_OPERATION_FAILED;
596         }
597
598         if (NULL == g_engine->callback) {
599                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
600                 return STTE_ERROR_OPERATION_FAILED;
601         }
602
603         if (NULL == g_engine->callback->set_recording) {
604                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
605                 return STTE_ERROR_OPERATION_FAILED;
606         }
607
608         int ret = g_engine->callback->set_recording(data, length);
609         if (0 != ret) {
610                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] Fail to set recording : %s", __stt_get_engine_error_code(ret));
611         }
612
613         return ret;
614 }
615
616 int stt_engine_recognize_stop()
617 {
618         if (NULL == g_engine) {
619                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
620                 return STTE_ERROR_OPERATION_FAILED;
621         }
622
623         if (NULL == g_engine->callback) {
624                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
625                 return STTE_ERROR_OPERATION_FAILED;
626         }
627
628         if (NULL == g_engine->callback->stop) {
629                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
630                 return STTE_ERROR_OPERATION_FAILED;
631         }
632
633         int ret = g_engine->callback->stop();
634         if (0 != ret) {
635                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to stop : %s", __stt_get_engine_error_code(ret));
636         }
637
638         return ret;
639 }
640
641 int stt_engine_recognize_cancel()
642 {
643         if (NULL == g_engine) {
644                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
645                 return STTE_ERROR_OPERATION_FAILED;
646         }
647
648         if (NULL == g_engine->callback) {
649                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
650                 return STTE_ERROR_OPERATION_FAILED;
651         }
652
653         if (NULL == g_engine->callback->cancel) {
654                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
655                 return STTE_ERROR_OPERATION_FAILED;
656         }
657
658         int ret = g_engine->callback->cancel();
659         if (0 != ret) {
660                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to cancel : %s", __stt_get_engine_error_code(ret));
661         }
662
663         return ret;
664 }
665
666 int stt_engine_foreach_result_time(void* time_info, stte_result_time_cb callback, void* user_data)
667 {
668         if (NULL == g_engine) {
669                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
670                 return STTE_ERROR_OPERATION_FAILED;
671         }
672
673         if (NULL == g_engine->callback) {
674                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
675                 return STTE_ERROR_OPERATION_FAILED;
676         }
677
678         if (NULL == g_engine->callback->foreach_result_time) {
679                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
680                 return STTE_ERROR_OPERATION_FAILED;
681         }
682
683         int ret = g_engine->callback->foreach_result_time(time_info, callback, user_data);
684         if (0 != ret) {
685                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to foreach result time : %s", __stt_get_engine_error_code(ret));
686         }
687
688         return ret;
689 }
690
691 int stt_engine_recognize_start_file(const char* lang, const char* recognition_type, 
692                                      const char* filepath, stte_audio_type_e audio_type, int sample_rate, void* user_param)
693 {
694         if (NULL == filepath || NULL == lang || NULL == recognition_type) {
695                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
696                 return STTE_ERROR_INVALID_PARAMETER;
697         }
698
699         if (NULL == g_engine) {
700                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
701                 return STTE_ERROR_OPERATION_FAILED;
702         }
703
704         if (NULL == g_engine->callback) {
705                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
706                 return STTE_ERROR_OPERATION_FAILED;
707         }
708
709 #ifdef __UNUSED_CODES__
710         if (NULL == g_engine->callback->start_file) {
711                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine API is invalid");
712                 return STTE_ERROR_NOT_SUPPORTED_FEATURE;
713         }
714
715         int ret = g_engine->callback->start_file(lang, recognition_type, filepath, audio_type, sample_rate, user_param);
716         if (0 != ret) {
717                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to start file recognition : %s", __stt_get_engine_error_code(ret));
718         }
719 #endif
720         return 0;
721 }
722
723 int stt_engine_recognize_cancel_file()
724 {
725         if (NULL == g_engine) {
726                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] No engine");
727                 return STTE_ERROR_OPERATION_FAILED;
728         }
729
730         if (NULL == g_engine->callback) {
731                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid engine");
732                 return STTE_ERROR_OPERATION_FAILED;
733         }
734
735 #ifdef __UNUSED_CODES__
736         if (NULL == g_engine->callback->cancel_file) {
737                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine API is invalid");
738                 return STTE_ERROR_NOT_SUPPORTED_FEATURE;
739         }
740
741         int ret = g_engine->callback->cancel_file();
742         if (0 != ret) {
743                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to start file recognition : %s", __stt_get_engine_error_code(ret));
744         }
745 #endif
746         return 0;
747 }
748
749 int stt_engine_set_recognition_result_cb(stt_engine_result_cb result_cb, void* user_data)
750 {
751         if (NULL == result_cb) {
752                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid parameter");
753                 return STTE_ERROR_INVALID_PARAMETER;
754         }
755
756         g_result_cb = result_cb;
757
758         return 0;
759 }
760
761 int stt_engine_send_result(stte_result_event_e event, const char* type, const char** result, int result_count,
762                                 const char* msg, void* time_info, void* user_data)
763 {
764         if (NULL == type || NULL == result) {
765                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid parameter");
766         }
767
768         int ret = STTE_ERROR_NONE;
769         if (false == __stt_get_engine_from()) {
770                 ret = sttd_engine_agent_send_result(event, type, result, result_count, msg, time_info, user_data);
771                 if (0 != ret) {
772                         SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to send result");
773                 }
774         } else {
775                 g_result_cb(event, type, result, result_count, msg, time_info, user_data);
776         }
777         return ret;
778 }
779
780 int stt_engine_send_error(stte_error_e error, const char* msg)
781 {
782         if (NULL == msg) {
783                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid parameter");
784         }
785
786         int ret = STTE_ERROR_NONE;
787         ret = sttd_engine_agent_send_error(error, msg);
788         if (0 != ret) {
789                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to send error info");
790         }
791         return ret;
792 }
793
794 int stt_engine_send_speech_status(stte_speech_status_e status, void* user_data)
795 {
796         int ret = STTE_ERROR_NONE;
797         ret = sttd_engine_agent_send_speech_status(status, user_data);
798         if (0 != ret) {
799                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to send speech status");
800         }
801         return ret;
802 }
803
804 int stt_engine_set_private_data_set_cb(stte_private_data_set_cb private_data_set_cb, void* user_data)
805 {
806         if (NULL == private_data_set_cb) {
807                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid parameter");
808                 return STTE_ERROR_INVALID_PARAMETER;
809         }
810
811         g_set_private_data_cb = private_data_set_cb;
812
813         return 0;
814 }
815
816 int stt_engine_set_private_data_requested_cb(stte_private_data_requested_cb private_data_requested_cb, void* user_data)
817 {
818         if (NULL == private_data_requested_cb) {
819                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid parameter");
820                 return STTE_ERROR_INVALID_PARAMETER;
821         }
822
823         g_get_private_data_cb = private_data_requested_cb;
824
825         return 0;
826 }