Add check handle function
[platform/core/uifw/stt.git] / common / stt_engine.c
1 /*
2 *  Copyright (c) 2011-2014 Samsung Electronics Co., Ltd All Rights Reserved
3 *  Licensed under the Apache License, Version 2.0 (the "License");
4 *  you may not use this file except in compliance with the License.
5 *  You may obtain a copy of the License at
6 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14 #include <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
23 /*
24 * Internal data structure
25 */
26
27 typedef struct {
28         int     engine_id;
29         char*   engine_path;
30         void    *handle;
31
32         sttpe_funcs_s*  pefuncs;
33         sttpd_funcs_s*  pdfuncs;
34
35         int (*sttp_load_engine)(sttpd_funcs_s* pdfuncs, sttpe_funcs_s* pefuncs);
36         int (*sttp_unload_engine)();
37 } sttengine_s;
38
39 extern const char* stt_tag();
40
41 /** stt engine list */
42 static GSList *g_engine_list;
43
44 static const char* __stt_get_engine_error_code(sttp_error_e err)
45 {
46         switch (err) {
47         case STTP_ERROR_NONE:                   return "STTP_ERROR_NONE";
48         case STTP_ERROR_OUT_OF_MEMORY:          return "STTP_ERROR_OUT_OF_MEMORY";
49         case STTP_ERROR_IO_ERROR:               return "STTP_ERROR_IO_ERROR";
50         case STTP_ERROR_INVALID_PARAMETER:      return "STTP_ERROR_INVALID_PARAMETER";
51         case STTP_ERROR_TIMED_OUT:              return "STTP_ERROR_TIMED_OUT";
52         case STTP_ERROR_RECORDER_BUSY:          return "STTP_ERROR_RECORDER_BUSY";
53         case STTP_ERROR_OUT_OF_NETWORK:         return "STTP_ERROR_OUT_OF_NETWORK";
54         case STTP_ERROR_PERMISSION_DENIED:      return "STTP_ERROR_PERMISSION_DENIED";
55         case STTP_ERROR_NOT_SUPPORTED:          return "STTP_ERROR_NOT_SUPPORTED";
56         case STTP_ERROR_INVALID_STATE:          return "STTP_ERROR_INVALID_STATE";
57         case STTP_ERROR_INVALID_LANGUAGE:       return "STTP_ERROR_INVALID_LANGUAGE";
58         case STTP_ERROR_ENGINE_NOT_FOUND:       return "STTP_ERROR_ENGINE_NOT_FOUND";
59         case STTP_ERROR_OPERATION_FAILED:       return "STTP_ERROR_OPERATION_FAILED";
60         case STTP_ERROR_NOT_SUPPORTED_FEATURE:  return "STTP_ERROR_NOT_SUPPORTED_FEATURE";
61         default:
62                 return "Invalid error code";
63         }
64 }
65
66 static sttengine_s* __get_engine(int engine_id)
67 {
68         /* check whether engine id is valid or not.*/
69         GSList *iter = NULL;
70         sttengine_s *engine = NULL;
71
72         if (g_slist_length(g_engine_list) > 0) {
73                 /*Get a first item*/
74                 iter = g_slist_nth(g_engine_list, 0);
75
76                 while (NULL != iter) {
77                         /*Get handle data from list*/
78                         engine = iter->data;
79
80                         if (engine_id == engine->engine_id) {
81                                 return engine;
82                         }
83
84                         /*Get next item*/
85                         iter = g_slist_next(iter);
86                 }
87         }
88
89         return NULL;
90 }
91
92 /* Register engine id */
93 int stt_engine_load(int engine_id, const char* filepath)
94 {
95         if (NULL == filepath || engine_id < 0) {
96                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
97                 return STTP_ERROR_INVALID_PARAMETER;
98         }
99
100         sttengine_s* engine = NULL;
101         engine = __get_engine(engine_id);
102         if (NULL != engine) {
103                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is already loaded", engine_id);
104                 return 0;
105         }
106
107         SECURE_SLOG(LOG_DEBUG, stt_tag(), "[Engine] Load engine id(%d), path(%s)", engine_id, filepath);
108
109         /* allocation memory */
110         engine = (sttengine_s*)calloc(1, sizeof(sttengine_s));
111         if (NULL == engine) {
112                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to allocate memory");
113                 return STTP_ERROR_OUT_OF_MEMORY;
114         }
115
116         /* load engine */
117         char *error;
118
119         engine->handle = dlopen(filepath, RTLD_LAZY);
120         if (!engine->handle) {
121                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine] Invalid engine (Fail dlopen) : %s", filepath);
122                 free(engine);
123                 return STTP_ERROR_OPERATION_FAILED;
124         }
125
126         engine->pefuncs = (sttpe_funcs_s*)calloc(1, sizeof(sttpe_funcs_s));
127         if (NULL == engine->pefuncs) {
128                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to allocate memory");
129                 dlclose(engine->handle);
130                 free(engine);
131                 return STTP_ERROR_OUT_OF_MEMORY;
132         }
133         engine->pdfuncs = (sttpd_funcs_s*)calloc(1, sizeof(sttpd_funcs_s));
134         if (NULL == engine->pdfuncs) {
135                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to allocate memory");
136                 dlclose(engine->handle);
137                 free(engine->pefuncs);
138                 free(engine);
139                 return STTP_ERROR_OUT_OF_MEMORY;
140         }
141
142         engine->sttp_unload_engine = NULL;
143         engine->sttp_load_engine = NULL;
144
145         engine->sttp_unload_engine = (int (*)())dlsym(engine->handle, "sttp_unload_engine");
146         if (NULL != (error = dlerror()) || NULL == engine->sttp_unload_engine) {
147                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to link daemon to sttp_unload_engine() : %s", error);
148                 dlclose(engine->handle);
149                 free(engine->pefuncs);
150                 free(engine->pdfuncs);
151                 free(engine);
152                 return STTP_ERROR_OPERATION_FAILED;
153         }
154
155         engine->sttp_load_engine = (int (*)(sttpd_funcs_s*, sttpe_funcs_s*))dlsym(engine->handle, "sttp_load_engine");
156         if (NULL != (error = dlerror()) || NULL == engine->sttp_load_engine) {
157                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to link daemon to sttp_load_engine() : %s", error);
158                 dlclose(engine->handle);
159                 free(engine->pefuncs);
160                 free(engine->pdfuncs);
161                 free(engine);
162                 return STTP_ERROR_OPERATION_FAILED;
163         }
164
165         engine->engine_id = engine_id;
166         engine->engine_path = strdup(filepath);
167
168         engine->pdfuncs->version = 1;
169         engine->pdfuncs->size = sizeof(sttpd_funcs_s);
170
171         int ret = engine->sttp_load_engine(engine->pdfuncs, engine->pefuncs);
172         if (0 != ret) {
173                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail sttp_load_engine() : %s", __stt_get_engine_error_code(ret));
174                 dlclose(engine->handle);
175                 free(engine->pefuncs);
176                 free(engine->pdfuncs);
177                 free(engine->engine_path);
178                 free(engine);
179                 return ret;
180         }
181
182         /* engine error check */
183         if (engine->pefuncs->size != sizeof(sttpe_funcs_s)) {
184                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine is not valid : function size is not matched");
185         }
186
187         if (NULL == engine->pefuncs->initialize ||
188                 NULL == engine->pefuncs->deinitialize ||
189                 NULL == engine->pefuncs->foreach_langs ||
190                 NULL == engine->pefuncs->is_valid_lang ||
191                 NULL == engine->pefuncs->support_silence ||
192                 NULL == engine->pefuncs->support_recognition_type ||
193                 NULL == engine->pefuncs->get_audio_format ||
194                 NULL == engine->pefuncs->set_silence_detection ||
195                 NULL == engine->pefuncs->start ||
196                 NULL == engine->pefuncs->set_recording ||
197                 NULL == engine->pefuncs->stop ||
198                 NULL == engine->pefuncs->cancel ||
199                 NULL == engine->pefuncs->foreach_result_time)
200                 /* Current unused functions
201                 NULL == engine->pefuncs->start_file_recognition ||
202                 */
203         {
204                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] The engine functions are NOT valid");
205                 dlclose(engine->handle);
206                 free(engine->pefuncs);
207                 free(engine->pdfuncs);
208                 free(engine->engine_path);
209                 free(engine);
210
211                 return STTP_ERROR_OPERATION_FAILED;
212         }
213
214         SLOG(LOG_DEBUG, stt_tag(), "[Engine Success] Load engine : version(%d), size(%d)", engine->pefuncs->version, engine->pefuncs->size);
215
216         g_engine_list = g_slist_append(g_engine_list, engine);
217
218         return 0;
219 }
220
221 /* Unregister engine id */
222 int stt_engine_unload(int engine_id)
223 {
224         sttengine_s* engine = NULL;
225         engine = __get_engine(engine_id);
226         if (NULL == engine) {
227                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
228                 return STTP_ERROR_INVALID_PARAMETER;
229         }
230
231         /* unload engine */
232         engine->sttp_unload_engine();
233         dlclose(engine->handle);
234
235         if (NULL != engine->engine_path)        free(engine->engine_path);
236         if (NULL != engine->pefuncs)            free(engine->pefuncs);
237         if (NULL != engine->pdfuncs)            free(engine->pdfuncs);
238
239         g_engine_list = g_slist_remove(g_engine_list, engine);
240
241         free(engine);
242
243         return 0;
244 }
245
246
247 /* Initialize / Deinitialize */
248 int stt_engine_initialize(int engine_id, sttpe_result_cb result_cb, sttpe_silence_detected_cb silence_cb)
249 {
250         if (NULL == result_cb || NULL == silence_cb) {
251                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
252                 return STTP_ERROR_INVALID_PARAMETER;
253         }
254
255         sttengine_s* engine = NULL;
256         engine = __get_engine(engine_id);
257         if (NULL == engine) {
258                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
259                 return STTP_ERROR_INVALID_PARAMETER;
260         }
261
262         int ret;
263         ret = engine->pefuncs->initialize(result_cb, silence_cb);
264         if (0 != ret) {
265                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to initialize : %s", __stt_get_engine_error_code(ret));
266                 return ret;
267         }
268
269         return 0;
270 }
271
272 int stt_engine_deinitialize(int engine_id)
273 {
274         sttengine_s* engine = NULL;
275         engine = __get_engine(engine_id);
276         if (NULL == engine) {
277                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
278                 return STTP_ERROR_INVALID_PARAMETER;
279         }
280
281         int ret;
282         ret = engine->pefuncs->deinitialize();
283         if (0 != ret) {
284                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] Fail to deinitialize : %s", __stt_get_engine_error_code(ret));
285         }
286
287         return 0;
288 }
289
290 static bool __supported_language_cb(const char* language, void* user_data)
291 {
292         GSList** lang_list = (GSList**)user_data;
293
294         if (NULL == language || NULL == lang_list) {
295                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Input parameter is NULL in callback!!!!");
296                 return false;
297         }
298
299         char* temp_lang = g_strdup(language);
300
301         *lang_list = g_slist_append(*lang_list, temp_lang);
302
303         return true;
304 }
305
306 /* Get option */
307 int stt_engine_get_supported_langs(int engine_id, GSList** lang_list)
308 {
309         if (NULL == lang_list) {
310                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
311                 return STTP_ERROR_INVALID_PARAMETER;
312         }
313
314         sttengine_s* engine = NULL;
315         engine = __get_engine(engine_id);
316         if (NULL == engine) {
317                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
318                 return STTP_ERROR_INVALID_PARAMETER;
319         }
320
321         int ret;
322         ret = engine->pefuncs->foreach_langs(__supported_language_cb, (void*)lang_list);
323         if (0 != ret) {
324                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] get language list error : %s", __stt_get_engine_error_code(ret));
325                 return ret;
326         }
327
328         return 0;
329 }
330
331 int stt_engine_is_valid_language(int engine_id, const char* language, bool *is_valid)
332 {
333         if (NULL == language || NULL == is_valid) {
334                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
335                 return STTP_ERROR_INVALID_PARAMETER;
336         }
337
338         sttengine_s* engine = NULL;
339         engine = __get_engine(engine_id);
340         if (NULL == engine) {
341                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
342                 return STTP_ERROR_INVALID_PARAMETER;
343         }
344
345         bool result;
346         result = engine->pefuncs->is_valid_lang(language);
347
348         *is_valid = result;
349
350         return 0;
351 }
352
353 int stt_engine_set_private_data(int engine_id, const char* key, const char* data)
354 {
355         if (NULL == key || NULL == data) {
356                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
357                 return STTP_ERROR_INVALID_PARAMETER;
358         }
359
360         sttengine_s* engine = NULL;
361         engine = __get_engine(engine_id);
362         if (NULL == engine) {
363                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
364                 return STTP_ERROR_INVALID_PARAMETER;
365         }
366
367         int ret = engine->pefuncs->set_private_data(key, data);
368         if (0 != ret) {
369                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to set private data(%d)", ret);
370         }
371         return STTP_ERROR_NONE;
372 }
373
374 int stt_engine_get_private_data(int engine_id, const char* key, char** data)
375 {
376         if (NULL == key || NULL == data) {
377                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
378                 return STTP_ERROR_INVALID_PARAMETER;
379         }
380
381         sttengine_s* engine = NULL;
382         engine = __get_engine(engine_id);
383         if (NULL == engine) {
384                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
385                 return STTP_ERROR_INVALID_PARAMETER;
386         }
387
388         char* temp = NULL;
389         int ret = engine->pefuncs->get_private_data(key, &temp);
390         if (0 != ret) {
391                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to set private data(%d)", ret);
392         }
393
394         *data = strdup(temp);
395
396         return STTP_ERROR_NONE;
397 }
398
399 int stt_engine_get_first_language(int engine_id, char** language)
400 {
401         if (NULL == language) {
402                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
403                 return STTP_ERROR_INVALID_PARAMETER;
404         }
405
406         sttengine_s* engine = NULL;
407         engine = __get_engine(engine_id);
408         if (NULL == engine) {
409                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
410                 return STTP_ERROR_INVALID_PARAMETER;
411         }
412
413         GSList* lang_list = NULL;
414         int ret;
415         ret = engine->pefuncs->foreach_langs(__supported_language_cb, &lang_list);
416         if (0 != ret) {
417                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] get language list error : %s", __stt_get_engine_error_code(ret));
418                 return ret;
419         }
420
421         GSList *iter = NULL;
422         char* data = NULL;
423
424         iter = g_slist_nth(lang_list, 0);
425         if (NULL != iter) {
426                 data = iter->data;
427
428                 if (true == engine->pefuncs->is_valid_lang(data)) {
429                         *language = strdup(data);
430                 } else {
431                         ret = STTP_ERROR_OPERATION_FAILED;
432                 }
433         }
434
435         /* if list have item */
436         if (g_slist_length(lang_list) > 0) {
437                 /* Get a first item */
438                 iter = g_slist_nth(lang_list, 0);
439
440                 while (NULL != iter) {
441                         data = iter->data;
442
443                         if (NULL != data)
444                                 free(data);
445
446                         lang_list = g_slist_remove_link(lang_list, iter);
447
448                         iter = g_slist_nth(lang_list, 0);
449                 }
450         }
451
452         return ret;
453 }
454
455 int stt_engine_support_silence(int engine_id, bool* support)
456 {
457         if (NULL == support) {
458                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
459                 return STTP_ERROR_INVALID_PARAMETER;
460         }
461
462         sttengine_s* engine = NULL;
463         engine = __get_engine(engine_id);
464         if (NULL == engine) {
465                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
466                 return STTP_ERROR_INVALID_PARAMETER;
467         }
468
469         bool result;
470         result = engine->pefuncs->support_silence();
471         *support = result;
472
473         return 0;
474 }
475
476
477 int stt_engine_need_app_credential(int engine_id, bool* need)
478 {
479         if (NULL == need) {
480                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
481                 return STTP_ERROR_INVALID_PARAMETER;
482         }
483
484         sttengine_s* engine = NULL;
485         engine = __get_engine(engine_id);
486         if (NULL == engine) {
487                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
488                 return STTP_ERROR_INVALID_PARAMETER;
489         }
490
491         bool result;
492         if (NULL != engine->pefuncs->need_app_credential) {
493                 result = engine->pefuncs->need_app_credential();
494                 *need = result;
495                 return STTP_ERROR_NONE;
496         }
497
498         return STTP_ERROR_OPERATION_FAILED;
499 }
500
501 int stt_engine_support_recognition_type(int engine_id, const char* type, bool* support)
502 {
503         if (NULL == type || NULL == support) {
504                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
505                 return STTP_ERROR_INVALID_PARAMETER;
506         }
507
508         sttengine_s* engine = NULL;
509         engine = __get_engine(engine_id);
510         if (NULL == engine) {
511                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
512                 return STTP_ERROR_INVALID_PARAMETER;
513         }
514
515         bool result;
516         if (NULL != engine->pefuncs->support_recognition_type) {
517                 result = engine->pefuncs->support_recognition_type(type);
518                 *support = result;
519                 return 0;
520         }
521
522         return STTP_ERROR_OPERATION_FAILED;
523 }
524
525 int stt_engine_get_audio_type(int engine_id, sttp_audio_type_e* types, int* rate, int* channels)
526 {
527         if (NULL == types || NULL == rate || NULL == channels) {
528                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
529                 return STTP_ERROR_INVALID_PARAMETER;
530         }
531
532         sttengine_s* engine = NULL;
533         engine = __get_engine(engine_id);
534         if (NULL == engine) {
535                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
536                 return STTP_ERROR_INVALID_PARAMETER;
537         }
538
539         int ret;
540         ret = engine->pefuncs->get_audio_format(types, rate, channels);
541         if (0 != ret) {
542                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to get audio format : %s", __stt_get_engine_error_code(ret));
543                 return ret;
544         }
545
546         return 0;
547 }
548
549 /* Set option */
550 int stt_engine_set_silence_detection(int engine_id, bool value)
551 {
552         sttengine_s* engine = NULL;
553         engine = __get_engine(engine_id);
554         if (NULL == engine) {
555                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
556                 return STTP_ERROR_INVALID_PARAMETER;
557         }
558
559         int ret = engine->pefuncs->set_silence_detection(value);
560         if (STTP_ERROR_NOT_SUPPORTED_FEATURE == ret) {
561                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] Not support silence detection");
562                 return STTP_ERROR_NOT_SUPPORTED_FEATURE;
563         } else if (0 != ret) {
564                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to set silence detection : %d", ret);
565                 return ret;
566         }
567
568         return 0;
569 }
570
571 int stt_engine_check_app_agreed(int engine_id, const char* appid, bool* value)
572 {
573         sttengine_s* engine = NULL;
574         engine = __get_engine(engine_id);
575         if (NULL == engine) {
576                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
577                 return STTP_ERROR_INVALID_PARAMETER;
578         }
579
580         if (NULL == engine->pefuncs->check_app_agreed) {
581                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] Not support app agreement. All app is available");
582                 *value = true;
583                 return 0;
584         }
585
586         int ret = engine->pefuncs->check_app_agreed(appid, value);
587         if (0 != ret) {
588                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to get app agreement : %s", __stt_get_engine_error_code(ret));
589                 *value = false;
590                 return ret;
591         }
592
593         return 0;
594 }
595
596 /* Recognition */
597 int stt_engine_recognize_start(int engine_id, const char* lang, const char* recognition_type, const char* credential, void* user_param)
598 {
599         if (NULL == lang || NULL == recognition_type) {
600                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
601                 return STTP_ERROR_INVALID_PARAMETER;
602         }
603
604         sttengine_s* engine = NULL;
605         engine = __get_engine(engine_id);
606         if (NULL == engine) {
607                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
608                 return STTP_ERROR_INVALID_PARAMETER;
609         }
610
611         int ret = engine->pefuncs->start(lang, recognition_type, credential, user_param);
612         if (0 != ret) {
613                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to start recognition : %s", __stt_get_engine_error_code(ret));
614                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to start recognition : lang(%s), recognition_type(%s), credential(%s)", lang, recognition_type, credential);
615                 return ret;
616         }
617
618         return 0;
619 }
620
621 int stt_engine_set_recording_data(int engine_id, const void* data, unsigned int length)
622 {
623         if (NULL == data) {
624                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
625                 return STTP_ERROR_INVALID_PARAMETER;
626         }
627
628         sttengine_s* engine = NULL;
629         engine = __get_engine(engine_id);
630         if (NULL == engine) {
631                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
632                 return STTP_ERROR_INVALID_PARAMETER;
633         }
634
635         int ret = engine->pefuncs->set_recording(data, length);
636         if (0 != ret) {
637                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] Fail to set recording : %s", __stt_get_engine_error_code(ret));
638                 return ret;
639         }
640
641         return 0;
642 }
643
644 int stt_engine_recognize_stop(int engine_id)
645 {
646         sttengine_s* engine = NULL;
647         engine = __get_engine(engine_id);
648         if (NULL == engine) {
649                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
650                 return STTP_ERROR_INVALID_PARAMETER;
651         }
652
653         int ret = engine->pefuncs->stop();
654         if (0 != ret) {
655                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to stop : %s", __stt_get_engine_error_code(ret));
656                 return ret;
657         }
658
659         return 0;
660 }
661
662 int stt_engine_recognize_cancel(int engine_id)
663 {
664         sttengine_s* engine = NULL;
665         engine = __get_engine(engine_id);
666         if (NULL == engine) {
667                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
668                 return STTP_ERROR_INVALID_PARAMETER;
669         }
670
671         int ret = engine->pefuncs->cancel();
672         if (0 != ret) {
673                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to cancel : %s", __stt_get_engine_error_code(ret));
674                 return ret;
675         }
676
677         return 0;
678 }
679
680 int stt_engine_foreach_result_time(int engine_id, void* time_info, sttpe_result_time_cb callback, void* user_data)
681 {
682         sttengine_s* engine = NULL;
683         engine = __get_engine(engine_id);
684         if (NULL == engine) {
685                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
686                 return STTP_ERROR_INVALID_PARAMETER;
687         }
688
689         int ret = engine->pefuncs->foreach_result_time(time_info, callback, user_data);
690         if (0 != ret) {
691                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to foreach result time : %s", __stt_get_engine_error_code(ret));
692                 return ret;
693         }
694
695         return 0;
696 }
697
698 int stt_engine_recognize_start_file(int engine_id, const char* lang, const char* recognition_type, 
699                                      const char* filepath, sttp_audio_type_e audio_type, int sample_rate, void* user_param)
700 {
701         if (NULL == filepath || NULL == lang || NULL == recognition_type) {
702                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Invalid Parameter");
703                 return STTP_ERROR_INVALID_PARAMETER;
704         }
705
706         sttengine_s* engine = NULL;
707         engine = __get_engine(engine_id);
708         if (NULL == engine) {
709                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
710                 return STTP_ERROR_INVALID_PARAMETER;
711         }
712
713         if (NULL == engine->pefuncs->start_file) {
714                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine API is invalid");
715                 return STTP_ERROR_NOT_SUPPORTED_FEATURE;
716         }
717
718         int ret = engine->pefuncs->start_file(lang, recognition_type, filepath, audio_type, sample_rate, user_param);
719         if (0 != ret) {
720                 SLOG(LOG_ERROR, stt_tag(), "[Engine ERROR] Fail to start file recognition : %s", __stt_get_engine_error_code(ret));
721                 return ret;
722         }
723
724         return 0;
725 }
726
727 int stt_engine_recognize_cancel_file(int engine_id)
728 {
729         sttengine_s* engine = NULL;
730         engine = __get_engine(engine_id);
731         if (NULL == engine) {
732                 SECURE_SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine id(%d) is invalid", engine_id);
733                 return STTP_ERROR_INVALID_PARAMETER;
734         }
735
736         if (NULL == engine->pefuncs->cancel_file) {
737                 SLOG(LOG_WARN, stt_tag(), "[Engine WARNING] engine API is invalid");
738                 return STTP_ERROR_NOT_SUPPORTED_FEATURE;
739         }
740
741         int ret = engine->pefuncs->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                 return ret;
745         }
746
747         return 0;
748 }