Update log level for information
[platform/core/uifw/tts.git] / server / ttsd_engine_agent.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
15 #include <dlfcn.h>
16 #include <dirent.h>
17
18 #include "tts_defs.h"
19 #include "ttsd_main.h"
20 #include "ttsd_engine_agent.h"
21 #include "ttsd_config.h"
22
23 #define ENGINE_PATH_SIZE        256
24
25 /*
26 * Internal data structure
27 */
28 typedef struct _ttsengine_info {
29         /* base info */
30         char*   engine_uuid;
31         char*   engine_path;
32         char*   engine_name;
33         char*   engine_setting_path;
34
35         /* info for using engine load */
36         bool    is_loaded;
37         bool    use_network;
38
39         tts_engine_callback_s* callbacks;
40
41         /* engine base setting */
42         char*   default_lang;
43         int     default_vctype;
44         int     default_speed;
45         int     default_pitch;
46 } ttsengine_info_s;
47
48 typedef struct {
49         bool    is_default;
50         bool    is_loaded;
51         int     client_ref_count;
52
53         char*   lang;
54         int     type;
55 } ttsvoice_s;
56
57
58 /** Init flag */
59 static bool g_agent_init;
60
61 /** Current engine information */
62 static ttsengine_info_s* g_engine_info = NULL;
63
64 /** Current voice information */
65 static GSList* g_cur_voices = NULL;
66
67 /** Callback function for voice list */
68 static bool __supported_voice_cb(const char* language, int type, void* user_data);
69
70 /** Free voice list */
71 static void __free_voice_list(GList* voice_list);
72
73 static int ttsd_print_voicelist();
74
75 /** Get engine info */
76 int __internal_get_engine_info(ttse_request_callback_s* callback);
77
78 static const char* __ttsd_get_engine_error_code(ttse_error_e err)
79 {
80         switch (err) {
81         case TTSE_ERROR_NONE:                   return "TTSE_ERROR_NONE";
82         case TTSE_ERROR_OUT_OF_MEMORY:          return "TTSE_ERROR_OUT_OF_MEMORY";
83         case TTSE_ERROR_IO_ERROR:               return "TTSE_ERROR_IO_ERROR";
84         case TTSE_ERROR_INVALID_PARAMETER:      return "TTSE_ERROR_INVALID_PARAMETER";
85         case TTSE_ERROR_NETWORK_DOWN:           return "TTSE_ERROR_NETWORK_DOWN";
86         case TTSE_ERROR_INVALID_STATE:          return "TTSE_ERROR_INVALID_STATE";
87         case TTSE_ERROR_INVALID_VOICE:          return "TTSE_ERROR_INVALID_VOICE";
88         case TTSE_ERROR_OPERATION_FAILED:       return "TTSE_ERROR_OPERATION_FAILED";
89         default:
90                 return "Invalid error code";
91         }
92 }
93
94 int ttsd_engine_agent_init()
95 {
96         if (true == g_agent_init) {
97                 SLOG(LOG_WARN, tts_tag(), "[Engine Agent] Already initialized");
98                 return TTSD_ERROR_OPERATION_FAILED;
99         }
100
101         ttsengine_info_s* temp;
102         temp = (ttsengine_info_s*)calloc(1, sizeof(ttsengine_info_s));
103         if (NULL == temp) {
104                 SLOG(LOG_WARN, tts_tag(), "[Engine Agent] Fail to alloc memory");
105                 return TTSD_ERROR_OUT_OF_MEMORY;
106         }
107
108         if (0 != ttsd_config_get_default_voice(&(temp->default_lang), &(temp->default_vctype))) {
109                 SLOG(LOG_WARN, tts_tag(), "[Server WARNING] There is No default voice in config");
110                 /* Set default voice */
111                 temp->default_lang = strdup(TTS_BASE_LANGUAGE);
112                 temp->default_vctype = TTSE_VOICE_TYPE_FEMALE;
113         }
114
115         SLOG(LOG_DEBUG, tts_tag(), "[Server DEBUG] language(%s), type(%d)", temp->default_lang, temp->default_vctype);
116
117         if (0 != ttsd_config_get_default_speed(&(temp->default_speed))) {
118                 SLOG(LOG_WARN, tts_tag(), "[Server WARNING] There is No default speed in config");
119                 temp->default_speed = TTS_SPEED_NORMAL;
120         }
121
122         if (0 != ttsd_config_get_default_pitch(&(temp->default_pitch))) {
123                 SLOG(LOG_WARN, tts_tag(), "[Server WARNING] There is No default pitch in config");
124                 temp->default_pitch = TTS_PITCH_NORMAL;
125         }
126
127         temp->is_loaded = false;
128         g_engine_info = temp;
129
130         g_agent_init = true;
131
132         SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Initialize Engine Agent");
133         return 0;
134 }
135
136 int ttsd_engine_agent_release()
137 {
138         if (false == g_agent_init) {
139                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
140                 return TTSD_ERROR_OPERATION_FAILED;
141         }
142
143         /* unload current engine */
144         if (g_engine_info->is_loaded) {
145                 ttsd_engine_agent_unload_current_engine();
146         }
147
148         if (NULL != g_engine_info->default_lang) {
149                 free(g_engine_info->default_lang);
150                 g_engine_info->default_lang = NULL;
151         }
152
153         if (NULL != g_engine_info->engine_uuid) {
154                 free(g_engine_info->engine_uuid);
155                 g_engine_info->engine_uuid = NULL;
156         }
157
158         if (NULL != g_engine_info->engine_name) {
159                 free(g_engine_info->engine_name);
160                 g_engine_info->engine_name = NULL;
161         }
162
163         if (NULL != g_engine_info->engine_setting_path) {
164                 free(g_engine_info->engine_setting_path);
165                 g_engine_info->engine_setting_path = NULL;
166         }
167
168         if (NULL != g_engine_info->engine_path) {
169                 free(g_engine_info->engine_path);
170                 g_engine_info->engine_path = NULL;
171         }
172
173         free(g_engine_info);
174         g_engine_info = NULL;
175
176         g_agent_init = false;
177
178         SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Release Engine Agent");
179
180         return 0;
181 }
182
183 static bool __set_voice_info_cb(const char* language, int type, void* user_data)
184 {
185         if (NULL == language) {
186                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
187                 return false;
188         }
189
190         ttsvoice_s* voice = calloc(1, sizeof(ttsvoice_s));
191         if (NULL == voice) {
192                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to allocate memory");
193                 return false;
194         }
195         voice->lang = strdup(language);
196         voice->type = type;
197
198         voice->client_ref_count = 0;
199         voice->is_loaded = false;
200
201         if (0 == strcmp(g_engine_info->default_lang, language) && g_engine_info->default_vctype == type) {
202                 voice->is_default = true;
203                 voice->is_loaded = true;
204         } else {
205                 voice->is_default = false;
206         }
207
208         g_cur_voices = g_slist_append(g_cur_voices, voice);
209
210         return true;
211 }
212
213 static int __update_voice_list()
214 {
215         if (false == g_agent_init) {
216                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
217                 return TTSD_ERROR_OPERATION_FAILED;
218         }
219
220         /* Get voice list */
221         if (NULL != g_cur_voices) {
222                 GSList *iter = NULL;
223                 ttsvoice_s* data = NULL;
224
225                 iter = g_slist_nth(g_cur_voices, 0);
226                 while (NULL != iter) {
227                         data = iter->data;
228
229                         if (NULL != data) {
230                                 if (NULL != data->lang) {
231                                         free(data->lang);
232                                         data->lang = NULL;
233                                 }
234
235                                 g_cur_voices = g_slist_remove(g_cur_voices, data);
236                                 free(data);
237                                 data = NULL;
238                         }
239
240                         iter = g_slist_nth(g_cur_voices, 0);
241                 }
242         }
243
244         g_cur_voices = NULL;
245
246         int ret = -1;
247         ret = g_engine_info->callbacks->foreach_voices(__set_voice_info_cb, NULL);
248
249         if (0 != ret || 0 >= g_slist_length(g_cur_voices)) {
250                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] fail to get voice list : result(%d)", ret);
251                 return -1;
252         }
253
254 #ifdef ENGINE_AGENT_DEBUG
255         ttsd_print_voicelist();
256 #endif
257         return 0;
258 }
259
260 int ttsd_engine_agent_load_current_engine(ttse_request_callback_s* callback)
261 {
262         SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent DEBUG] === ttsd_engine_agent_load_current_engine START");
263
264
265         if (false == g_agent_init) {
266                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
267                 return TTSD_ERROR_OPERATION_FAILED;
268         }
269
270         /* check whether current engine is loaded or not */
271         if (true == g_engine_info->is_loaded) {
272                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent] Engine has already been loaded ");
273                 return 0;
274         }
275
276         if (NULL == callback) {
277                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid engine");
278                 return TTSD_ERROR_ENGINE_NOT_FOUND;
279         }
280
281         if (NULL == callback->get_info
282                 || NULL == callback->initialize || NULL == callback->deinitialize
283                 || NULL == callback->foreach_voices || NULL == callback->is_valid_voice
284                 || NULL == callback->set_pitch
285                 || NULL == callback->load_voice || NULL == callback->unload_voice
286                 || NULL == callback->start_synth || NULL == callback->cancel_synth
287                 || NULL == callback->check_app_agreed || NULL == callback->need_app_credential) {
288                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid engine");
289                 return TTSD_ERROR_ENGINE_NOT_FOUND;
290         }
291
292         /* Get current engine info */
293         int ret = __internal_get_engine_info(callback);
294         if (0 != ret) {
295                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get engine info");
296                 return ret;
297         }
298
299         /* Initialize engine */
300         ret = g_engine_info->callbacks->initialize();
301         if (0 != ret) {
302                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to initialize current engine : %s", __ttsd_get_engine_error_code(ret));
303                 return TTSD_ERROR_OPERATION_FAILED;
304         }
305
306         /* Get voice info of current engine */
307         ret = __update_voice_list();
308         if (0 != ret) {
309                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to set voice info : result(%d)", ret);
310                 return TTSD_ERROR_OPERATION_FAILED;
311         }
312
313         /* Select default voice */
314         if (NULL != g_engine_info->default_lang) {
315                 bool is_valid = false;
316                 ret = g_engine_info->callbacks->is_valid_voice(g_engine_info->default_lang, g_engine_info->default_vctype, &is_valid);
317                 if (0 == ret) {
318                         if (true == is_valid) {
319                                 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Set origin default voice to current engine : lang(%s), type(%d)", 
320                                         g_engine_info->default_lang, g_engine_info->default_vctype);
321                         } else {
322                                 SLOG(LOG_WARN, tts_tag(), "[Engine Agent WARNING] Fail to set origin default voice : lang(%s), type(%d)",
323                                         g_engine_info->default_lang, g_engine_info->default_vctype);
324
325                                 /* TODO - Error Tolerance when Default voice is not valid */
326                                 return TTSD_ERROR_OPERATION_FAILED;
327                         }
328                 } else {
329                         SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail(Engine ERROR) : %s", __ttsd_get_engine_error_code(ret));
330                         return ret;
331                 }
332         }
333
334         /* load default voice */
335         ret = g_engine_info->callbacks->load_voice(g_engine_info->default_lang, g_engine_info->default_vctype);
336         if (0 == ret) {
337                 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Load default voice : lang(%s), type(%d)",
338                         g_engine_info->default_lang, g_engine_info->default_vctype);
339         } else {
340                 SLOG(LOG_WARN, tts_tag(), "[Engine Agent ERROR] Fail to load default voice : lang(%s), type(%d) result(%s)",
341                         g_engine_info->default_lang, g_engine_info->default_vctype, __ttsd_get_engine_error_code(ret));
342
343                 return TTSD_ERROR_OPERATION_FAILED;
344         }
345
346         /* set default pitch */
347         ret = g_engine_info->callbacks->set_pitch(g_engine_info->default_pitch);
348         if (0 != ret) {
349                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to set pitch : pitch(%d), result(%s)", 
350                         g_engine_info->default_pitch, __ttsd_get_engine_error_code(ret));
351                 return ret;
352         } else {
353                 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Set default pitch : pitch(%d)", g_engine_info->default_pitch);
354         }
355
356         g_engine_info->is_loaded = true;
357
358         return 0;
359 }
360
361 int ttsd_engine_agent_unload_current_engine()
362 {
363         if (false == g_agent_init) {
364                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
365                 return TTSD_ERROR_OPERATION_FAILED;
366         }
367
368         if (false == g_engine_info->is_loaded) {
369                 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Engine has already been unloaded ");
370                 return 0;
371         }
372
373         /* shutdown engine */
374         int ret = 0;
375         ret = g_engine_info->callbacks->deinitialize();
376         if (0 != ret) {
377                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent] Fail deinitialize() : %s", __ttsd_get_engine_error_code(ret));
378         }
379
380         /* reset current engine data */
381         g_engine_info->is_loaded = false;
382
383         GSList *iter = NULL;
384         ttsvoice_s* data = NULL;
385
386         iter = g_slist_nth(g_cur_voices, 0);
387         while (NULL != iter) {
388                 data = iter->data;
389
390                 if (NULL != data) {
391                         if (NULL != data->lang)         free(data->lang);
392                         g_cur_voices = g_slist_remove(g_cur_voices, data);
393                         free(data);
394                         data = NULL;
395                 }
396
397                 iter = g_slist_nth(g_cur_voices, 0);
398         }
399
400         SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent Success] Unload current engine");
401
402         return 0;
403 }
404
405 bool ttsd_engine_agent_need_network()
406 {
407         if (false == g_agent_init) {
408                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
409                 return TTSD_ERROR_OPERATION_FAILED;
410         }
411
412         return g_engine_info->use_network;
413 }
414
415 bool ttsd_engine_agent_is_same_engine(const char* engine_id)
416 {
417         if (false == g_agent_init) {
418                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
419                 return false;
420         }
421
422         if (NULL == engine_id) {
423                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] engine_id is NULL");
424                 return false;
425         }
426
427         if (NULL == g_engine_info) {
428                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] g_engine_info is NULL");
429                 return false;
430         }
431
432         if (false == g_engine_info->is_loaded) {
433                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not loaded engine");
434                 return false;
435         }
436
437         /* compare current engine and engine id.*/
438         if (NULL != g_engine_info->engine_uuid && 0 == strncmp(g_engine_info->engine_uuid, engine_id, strlen(engine_id))) {
439                 return true;
440         }
441
442         return false;
443 }
444
445 bool ttsd_engine_select_valid_voice(const char* lang, int type, char** out_lang, int* out_type)
446 {
447         if (NULL == lang || NULL == out_lang || NULL == out_type) {
448                 return false;
449         }
450
451         if (NULL == g_engine_info) {
452                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] g_engine_info is NULL");
453                 return false;
454         }
455
456         if (false == g_engine_info->is_loaded) {
457                 SLOG(LOG_WARN, tts_tag(), "[Engine Agent WARNING] Not loaded engine");
458                 return false;
459         }
460
461         SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Select voice : input lang(%s), input type(%d), default lang(%s), default type(%d)", 
462                 (NULL == lang) ? "NULL" : lang, type, (NULL == g_engine_info->default_lang) ? "NULL" : g_engine_info->default_lang, g_engine_info->default_vctype);
463
464         /* case 1 : Both are default */
465         if (0 == strncmp(lang, "default", strlen(lang)) && 0 == type) {
466                 if (NULL != g_engine_info->default_lang) {
467                         *out_lang = strdup(g_engine_info->default_lang);
468                 } else {
469                         *out_lang = NULL;
470                 }
471
472                 *out_type = g_engine_info->default_vctype;
473                 return true;
474         }
475
476         /* Get voice list */
477         GList* voice_list = NULL;
478         int ret = 0;
479         ret = g_engine_info->callbacks->foreach_voices(__supported_voice_cb, &voice_list);
480         if (0 != ret || 0 >= g_list_length(voice_list)) {
481                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] fail to get voice list : result(%d)", ret);
482                 return false;
483         }
484
485         bool result;
486         result = false;
487
488         GList *iter = NULL;
489         voice_s* voice;
490
491         /* case 2 : lang and type are not default type */
492         if (0 != strncmp(lang, "default", strlen("default")) && 0 != type) {
493                 iter = g_list_first(voice_list);
494
495                 while (NULL != iter) {
496                         /* Get handle data from list */
497                         voice = iter->data;
498
499                         if (0 == strncmp(voice->language, lang, strlen(lang)) &&  voice->type == type) {
500                                 *out_lang = strdup(voice->language);
501                                 *out_type = voice->type;
502                                 result = true;
503                                 break;
504                         }
505
506                         iter = g_list_next(iter);
507                 }
508
509         } else if (0 != strncmp(lang, "default", strlen("default")) && 0 == type) {
510                 /* Only type is default */
511                 if (0 == strncmp(lang, g_engine_info->default_lang, strlen(g_engine_info->default_lang))) {
512                         *out_lang = strdup(g_engine_info->default_lang);
513                         *out_type = g_engine_info->default_vctype;
514                         result = true;
515                 } else {
516                         voice_s* voice_selected = NULL;
517                         iter = g_list_first(voice_list);
518                         while (NULL != iter) {
519                                 /* Get handle data from list */
520                                 voice = iter->data;
521
522                                 if (0 == strncmp(voice->language, lang, strlen(lang))) {
523                                         voice_selected = voice;
524                                         if (voice->type == g_engine_info->default_vctype) {
525                                                 voice_selected = voice;
526                                                 break;
527                                         }
528                                 }
529                                 iter = g_list_next(iter);
530                         }
531
532                         if (NULL != voice_selected) {
533                                 *out_lang = strdup(voice_selected->language);
534                                 *out_type = voice_selected->type;
535                                 result = true;
536                         }
537                 }
538         } else if (0 == strncmp(lang, "default", strlen("default")) && 0 != type) {
539                 /* Only lang is default */
540                 if (type == g_engine_info->default_vctype) {
541                         *out_lang = strdup(g_engine_info->default_lang);
542                         *out_type = g_engine_info->default_vctype;
543                         result = true;
544                 } else {
545                         voice_s* voice_selected = NULL;
546                         iter = g_list_first(voice_list);
547                         while (NULL != iter) {
548                                 /* Get handle data from list */
549                                 voice = iter->data;
550
551                                 if (0 == strncmp(voice->language, g_engine_info->default_lang, strlen(g_engine_info->default_lang))) {
552                                         voice_selected = voice;
553                                         if (voice->type == type) {
554                                                 voice_selected = voice;
555                                                 break;
556                                         }
557                                 }
558                                 iter = g_list_next(iter);
559                         }
560
561                         if (NULL != voice_selected) {
562                                 *out_lang = strdup(voice->language);
563                                 *out_type = voice_selected->type;
564                                 result = true;
565                         }
566                 }
567         }
568
569         if (true == result) {
570                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Selected voice : lang(%s), type(%d)", *out_lang, *out_type);
571         }
572
573         __free_voice_list(voice_list);
574
575         return result;
576 }
577
578
579
580 int ttsd_engine_agent_set_default_voice(const char* language, int vctype)
581 {
582         if (NULL == language) {
583                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] language is NULL");
584                 return false;
585         }
586
587         if (false == g_agent_init) {
588                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
589                 return TTSD_ERROR_OPERATION_FAILED;
590         }
591
592         if (NULL == g_engine_info) {
593                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] g_engine_info is NULL");
594                 return false;
595         }
596
597         if (false == g_engine_info->is_loaded) {
598                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
599                 return TTSD_ERROR_ENGINE_NOT_FOUND;
600         }
601
602         int ret = -1;
603         bool is_valid = false;
604         ret = g_engine_info->callbacks->is_valid_voice(language, vctype, &is_valid);
605         if (0 == ret) {
606                 if (true == is_valid) {
607                         SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Current voice is valid : lang(%s), type(%d)", 
608                                 (NULL == g_engine_info->default_lang) ? "NULL" : g_engine_info->default_lang, g_engine_info->default_vctype);
609                 } else {
610                         SLOG(LOG_WARN, tts_tag(), "[Engine Agent WARNING] Current voice is invalid : lang(%s), type(%d)",
611                                 (NULL == g_engine_info->default_lang) ? "NULL" : g_engine_info->default_lang, g_engine_info->default_vctype);
612
613                         return TTSD_ERROR_OPERATION_FAILED;
614                 }
615         } else {
616                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail(Engine ERROR) : %s", __ttsd_get_engine_error_code(ret));
617                 return ret;
618         }
619
620
621         GSList *iter = NULL;
622         ttsvoice_s* data = NULL;
623
624         /* Update new default voice info */
625         iter = g_slist_nth(g_cur_voices, 0);
626         while (NULL != iter) {
627                 /* Get handle data from list */
628                 data = iter->data;
629
630                 if (NULL == data) {
631                         SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Voice data is NULL");
632                         return TTSD_ERROR_OPERATION_FAILED;
633                 }
634
635                 if (NULL != data->lang) {
636                 if (0 == strcmp(data->lang, language) && data->type == vctype) {
637                         data->is_default = true;
638                         if (0 == data->client_ref_count) {
639                                 /* load voice */
640                                         ret = g_engine_info->callbacks->load_voice(data->lang, data->type);
641                                         if (0 == ret) {
642                                                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] load voice : lang(%s), type(%d)", 
643                                                         data->lang, data->type);
644                                                 data->is_loaded = true;
645                                         } else {
646                                                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to load voice : lang(%s), type(%d), result(%s)",
647                                                         data->lang, data->type, __ttsd_get_engine_error_code(ret));
648                                         }
649                                 }
650                         }
651                         break;
652                 }
653
654                 /*Get next item*/
655                 iter = g_slist_next(iter);
656         }
657
658 #ifdef ENGINE_AGENT_DEBUG
659         ttsd_print_voicelist();
660 #endif
661
662         /* Update old default voice info */
663         iter = g_slist_nth(g_cur_voices, 0);
664         while (NULL != iter) {
665                 /*Get handle data from list*/
666                 data = iter->data;
667
668                 if (NULL == data) {
669                         SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Voice data is NULL");
670                         return TTSD_ERROR_OPERATION_FAILED;
671                 }
672
673                 if (0 == strcmp(data->lang, g_engine_info->default_lang) && data->type == g_engine_info->default_vctype) {
674                         data->is_default = false;
675                         if (0 == data->client_ref_count) {
676                                 /* Unload voice */
677                                 ret = g_engine_info->callbacks->unload_voice(data->lang, data->type);
678                                 if (0 == ret) {
679                                         SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Unload voice : lang(%s), type(%d)", 
680                                                 data->lang, data->type);
681                                         data->is_loaded = false;
682                                 } else {
683                                         SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to unload voice : lang(%s), type(%d), result(%s)",
684                                                 data->lang, data->type, __ttsd_get_engine_error_code(ret));
685                                 }
686                         }
687                         break;
688                 }
689
690                 /*Get next item*/
691                 iter = g_slist_next(iter);
692         }
693
694         if (NULL != g_engine_info->default_lang)        free(g_engine_info->default_lang);
695
696         g_engine_info->default_lang = strdup(language);
697         g_engine_info->default_vctype = vctype;
698
699 #ifdef ENGINE_AGENT_DEBUG
700         ttsd_print_voicelist();
701 #endif
702
703         SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Set default voice : lang(%s), type(%d)",
704                 g_engine_info->default_lang, g_engine_info->default_vctype);
705
706         return 0;
707 }
708
709 int ttsd_engine_agent_set_default_speed(int speed)
710 {
711         if (false == g_agent_init) {
712                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
713                 return TTSD_ERROR_OPERATION_FAILED;
714         }
715
716         g_engine_info->default_speed = speed;
717
718         return 0;
719 }
720
721 int ttsd_engine_agent_set_default_pitch(int pitch)
722 {
723         if (false == g_agent_init) {
724                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
725                 return TTSD_ERROR_OPERATION_FAILED;
726         }
727
728         if (NULL == g_engine_info) {
729                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No engine info");
730                 return TTSD_ERROR_ENGINE_NOT_FOUND;
731         }
732
733         if (false == g_engine_info->is_loaded) {
734                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
735                 return TTSD_ERROR_ENGINE_NOT_FOUND;
736         }
737
738         int ret = g_engine_info->callbacks->set_pitch(pitch);
739         if (0 != ret) {
740                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to set pitch : pitch(%d), result(%s)",
741                          pitch, __ttsd_get_engine_error_code(ret));
742                 return TTSD_ERROR_OPERATION_FAILED;
743         }
744
745         g_engine_info->default_pitch = pitch;
746
747         SLOG(LOG_INFO, tts_tag(), "[Engine Agent] Set pitch(%d)", pitch);
748         return 0;
749 }
750
751 int ttsd_engine_agent_is_credential_needed(int uid, bool* credential_needed)
752 {
753         if (NULL == credential_needed) {
754                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid Parameter");
755                 return TTSD_ERROR_INVALID_PARAMETER;
756         }
757
758         if (false == g_agent_init) {
759                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
760                 return TTSD_ERROR_OPERATION_FAILED;
761         }
762
763         if (false == g_engine_info->is_loaded) {
764                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not loaded engine");
765                 return TTSD_ERROR_OPERATION_FAILED;
766         }
767
768         if (NULL == g_engine_info->callbacks->need_app_credential) {
769                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not support to check app credential");
770                 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
771         }
772
773         bool result = false;
774         result = g_engine_info->callbacks->need_app_credential();
775         *credential_needed = result;
776
777         SLOG(LOG_INFO, tts_tag(), "[Engine Agent] Need app credential, credential_needed(%d)", *credential_needed);
778         return TTSD_ERROR_NONE;
779 }
780
781 /******************************************************************************************
782 * TTS Engine Interfaces for client
783 *******************************************************************************************/
784
785 int ttsd_engine_load_voice(const char* lang, const int vctype)
786 {
787         if (false == g_agent_init) {
788                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
789                 return TTSD_ERROR_OPERATION_FAILED;
790         }
791
792         if (false == g_engine_info->is_loaded) {
793                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
794                 return TTSD_ERROR_ENGINE_NOT_FOUND;
795         }
796
797         if (NULL == lang) {
798                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No language parameter");
799                 return TTSD_ERROR_INVALID_PARAMETER;
800         }
801
802         /* 1. Find voice info */
803         int ret = -1;
804         GSList *iter = NULL;
805         ttsvoice_s* data = NULL;
806
807         iter = g_slist_nth(g_cur_voices, 0);
808         while (NULL != iter) {
809                 /*Get handle data from list*/
810                 data = iter->data;
811
812                 if (NULL != data) {
813                         if (NULL != data->lang && 0 == strcmp(data->lang, lang) && data->type == vctype) {
814                                 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Find voice : default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
815                                          data->is_default, data->is_loaded,  data->client_ref_count, data->lang, data->type);
816                                 break;
817                         }
818                 }
819
820                 /*Get next item*/
821                 iter = g_slist_next(iter);
822                 data = NULL;
823         }
824
825         if (NULL == data) {
826                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
827                 return TTSD_ERROR_OPERATION_FAILED;
828         }
829
830         /* 2. increse ref count */
831         data->client_ref_count++;
832
833         /* 3. if ref count change 0 to 1 and not default, load voice */
834         if (1 == data->client_ref_count && false == data->is_default) {
835                 /* load voice */
836                 ret = g_engine_info->callbacks->load_voice(data->lang, data->type);
837                 if (0 == ret) {
838                         SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Load voice : lang(%s), type(%d)", 
839                                 data->lang, data->type);
840                         data->is_loaded = true;
841                 } else {
842                         SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to load voice : lang(%s), type(%d), result(%s)",
843                                 data->lang, data->type, __ttsd_get_engine_error_code(ret));
844
845                         return TTSD_ERROR_OPERATION_FAILED;
846                 }
847         } else {
848                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Not load voice : default voice(%d) or ref count(%d)",
849                 data->is_default, data->client_ref_count);
850         }
851
852 #ifdef ENGINE_AGENT_DEBUG
853         ttsd_print_voicelist();
854 #endif
855
856         return 0;
857 }
858
859 int ttsd_engine_unload_voice(const char* lang, const int vctype)
860 {
861         if (false == g_agent_init) {
862                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
863                 return TTSD_ERROR_OPERATION_FAILED;
864         }
865
866         if (false == g_engine_info->is_loaded) {
867                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
868                 return TTSD_ERROR_ENGINE_NOT_FOUND;
869         }
870
871         if (NULL == lang) {
872                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No language parameter");
873                 return TTSD_ERROR_INVALID_PARAMETER;
874         }
875
876         /* 1. Find voice info */
877         int ret = -1;
878         GSList *iter = NULL;
879         ttsvoice_s* data = NULL;
880
881         iter = g_slist_nth(g_cur_voices, 0);
882         while (NULL != iter) {
883                 /*Get handle data from list*/
884                 data = iter->data;
885
886                 if (NULL != data) {
887                         if (NULL != data->lang && 0 == strcmp(data->lang, lang) && data->type == vctype) {
888                                 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Find voice : default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
889                                          data->is_default, data->is_loaded,  data->client_ref_count, data->lang, data->type);
890                                 break;
891                         }
892                 }
893
894                 /*Get next item*/
895                 iter = g_slist_next(iter);
896                 data = NULL;
897         }
898
899         if (NULL == data) {
900                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
901                 return TTSD_ERROR_OPERATION_FAILED;
902         }
903
904         /* 2. Decrese ref count */
905         data->client_ref_count--;
906
907         /* 3. if ref count change 0 and not default, load voice */
908         if (0 == data->client_ref_count && false == data->is_default) {
909                 /* unload voice */
910                 ret = g_engine_info->callbacks->unload_voice(data->lang, data->type);
911                 if (0 == ret) {
912                         SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Unload voice : lang(%s), type(%d)", 
913                                 data->lang, data->type);
914                         data->is_loaded = false;
915                 } else {
916                         SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to unload voice : lang(%s), type(%d), result(%s)",
917                                 data->lang, data->type, __ttsd_get_engine_error_code(ret));
918
919                         return TTSD_ERROR_OPERATION_FAILED;
920                 }
921         } else {
922                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Not unload voice : default voice(%d) or ref count(%d)",
923                 data->is_default, data->client_ref_count);
924         }
925
926 #ifdef ENGINE_AGENT_DEBUG
927         ttsd_print_voicelist();
928 #endif
929         return 0;
930 }
931
932 int ttsd_engine_start_synthesis(const char* lang, int vctype, const char* text, int speed, const char* appid, const char* credential, void* user_param)
933 {
934         if (NULL == lang || NULL == text) {
935                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
936                 return TTSD_ERROR_INVALID_PARAMETER;
937         }
938
939         if (false == g_agent_init) {
940                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
941                 return TTSD_ERROR_OPERATION_FAILED;
942         }
943
944         if (false == g_engine_info->is_loaded) {
945                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
946                 return TTSD_ERROR_ENGINE_NOT_FOUND;
947         }
948
949         /* select voice for default */
950         char* temp_lang = NULL;
951         int temp_type;
952         if (true != ttsd_engine_select_valid_voice(lang, vctype, &temp_lang, &temp_type)) {
953                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to select default voice");
954                 if (NULL != temp_lang)  free(temp_lang);
955                 return TTSD_ERROR_INVALID_VOICE;
956         } else {
957                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Start synthesis : language(%s), type(%d), speed(%d), text(%s), credential(%s)", 
958                         (NULL == temp_lang) ? "NULL" : temp_lang, temp_type, speed, (NULL == text) ? "NULL" : text, (NULL == credential) ? "NULL" : credential);
959         }
960
961         int temp_speed;
962
963         if (0 == speed) {
964                 temp_speed = g_engine_info->default_speed;
965         } else {
966                 temp_speed = speed;
967         }
968
969         /* synthesize text */
970         int ret = 0;
971         ret = g_engine_info->callbacks->start_synth(temp_lang, temp_type, text, temp_speed, appid, credential, user_param);
972         if (0 != ret) {
973                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] ***************************************");
974                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] * synthesize error : %s *", __ttsd_get_engine_error_code(ret));
975                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] ***************************************");
976                 if (NULL != temp_lang) {
977                         free(temp_lang);
978                         temp_lang = NULL;
979                 }
980                 return ret;
981         }
982
983         if (NULL != temp_lang)  {
984                 free(temp_lang);
985                 temp_lang = NULL;
986         }
987         return 0;
988 }
989
990 int ttsd_engine_cancel_synthesis()
991 {
992         if (false == g_agent_init) {
993                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
994                 return TTSD_ERROR_OPERATION_FAILED;
995         }
996
997         if (false == g_engine_info->is_loaded) {
998                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
999                 return TTSD_ERROR_ENGINE_NOT_FOUND;
1000         }
1001
1002         SLOG(LOG_INFO, tts_tag(), "[Engine Agent] Cancel synth");
1003         /* stop synthesis */
1004         int ret = 0;
1005         ret = g_engine_info->callbacks->cancel_synth();
1006         if (0 != ret) {
1007                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] fail cancel synthesis : %s", __ttsd_get_engine_error_code(ret));
1008         }
1009
1010         return ret;
1011 }
1012
1013 bool __supported_voice_cb(const char* language, int type, void* user_data)
1014 {
1015         GList** voice_list = (GList**)user_data;
1016
1017         if (NULL == language || NULL == voice_list) {
1018                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
1019                 return false;
1020         }
1021
1022         voice_s* voice = calloc(1, sizeof(voice_s));
1023         if (NULL == voice) {
1024                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to allocate memory");
1025                 return false;
1026         }
1027         voice->language = strdup(language);
1028         voice->type = type;
1029
1030         *voice_list = g_list_append(*voice_list, voice);
1031
1032         return true;
1033 }
1034
1035 int ttsd_engine_get_voice_list(GList** voice_list)
1036 {
1037         if (NULL == voice_list) {
1038                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
1039                 return TTSD_ERROR_INVALID_PARAMETER;
1040         }
1041
1042         if (false == g_agent_init) {
1043                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1044                 return TTSD_ERROR_OPERATION_FAILED;
1045         }
1046
1047         if (false == g_engine_info->is_loaded) {
1048                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
1049                 return TTSD_ERROR_ENGINE_NOT_FOUND;
1050         }
1051
1052         int ret = 0;
1053         ret = g_engine_info->callbacks->foreach_voices(__supported_voice_cb, (void*)voice_list);
1054         if (0 != ret) {
1055                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get voice list : %s", __ttsd_get_engine_error_code(ret));
1056         }
1057
1058         return ret;
1059 }
1060
1061 int ttsd_engine_get_default_voice(char** lang, int* vctype)
1062 {
1063         if (false == g_agent_init) {
1064                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1065                 return TTSD_ERROR_OPERATION_FAILED;
1066         }
1067
1068         if (false == g_engine_info->is_loaded) {
1069                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
1070                 return TTSD_ERROR_ENGINE_NOT_FOUND;
1071         }
1072
1073         if (NULL == lang || NULL == vctype) {
1074                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] BAD Parameter");
1075                 return TTSD_ERROR_INVALID_PARAMETER;
1076         }
1077
1078         if (NULL != g_engine_info->default_lang) {
1079                 *lang = strdup(g_engine_info->default_lang);
1080                 *vctype = g_engine_info->default_vctype;
1081
1082                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine] Get default voice : language(%s), type(%d)", *lang, *vctype);
1083         } else {
1084                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Default voice is NULL");
1085                 return TTSD_ERROR_OPERATION_FAILED;
1086         }
1087
1088         return 0;
1089 }
1090
1091 int ttsd_engine_set_private_data(const char* key, const char* data)
1092 {
1093         if (false == g_agent_init) {
1094                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1095                 return TTSD_ERROR_OPERATION_FAILED;
1096         }
1097
1098         if (false == g_engine_info->is_loaded) {
1099                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
1100                 return TTSD_ERROR_ENGINE_NOT_FOUND;
1101         }
1102
1103         if (NULL == key) {
1104                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
1105                 return TTSD_ERROR_INVALID_PARAMETER;
1106         }
1107
1108         if (NULL == g_engine_info->callbacks->private_data_set) {
1109                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not supported feature");
1110                 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1111         }
1112
1113         int ret = g_engine_info->callbacks->private_data_set(key, data);
1114
1115         if (0 != ret) {
1116                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to set private data(%d)", ret);
1117         }
1118
1119         return ret;
1120 }
1121
1122 int ttsd_engine_get_private_data(const char* key, char** data)
1123 {
1124         if (false == g_agent_init) {
1125                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1126                 return TTSD_ERROR_OPERATION_FAILED;
1127         }
1128
1129         if (false == g_engine_info->is_loaded) {
1130                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
1131                 return TTSD_ERROR_ENGINE_NOT_FOUND;
1132         }
1133
1134         if (NULL == key || NULL == data) {
1135                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
1136                 return TTSD_ERROR_INVALID_PARAMETER;
1137         }
1138
1139
1140         if (NULL == g_engine_info->callbacks->private_data_requested) {
1141                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not supported feature");
1142                 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1143         }
1144
1145         char* temp = NULL;
1146         int ret = 0;
1147         ret = g_engine_info->callbacks->private_data_requested(key, &temp);
1148         if (0 != ret) {
1149                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get private data(%d)", ret);
1150         }
1151
1152         if (NULL == temp)
1153                 *data = strdup("NULL");
1154         else
1155                 *data = strdup(temp);
1156
1157         return ret;
1158 }
1159
1160 void __free_voice_list(GList* voice_list)
1161 {
1162         GList *iter = NULL;
1163         voice_s* data = NULL;
1164
1165         /* if list have item */
1166         if (g_list_length(voice_list) > 0) {
1167                 /* Get a first item */
1168                 iter = g_list_first(voice_list);
1169
1170                 while (NULL != iter) {
1171                         data = iter->data;
1172
1173                         if (NULL != data) {
1174                                 if (NULL != data->language)     free(data->language);
1175                                 free(data);
1176                         }
1177
1178                         voice_list = g_list_remove_link(voice_list, iter);
1179                         g_list_free(iter);
1180                         iter = g_list_first(voice_list);
1181                 }
1182         }
1183 }
1184
1185 /*
1186 * TTS Engine Callback Functions                                                                                 `                                 *
1187 */
1188
1189 /* function for debugging */
1190 int ttsd_print_voicelist()
1191 {
1192         /* Test log */
1193         GSList *iter = NULL;
1194         ttsvoice_s* data = NULL;
1195
1196         SLOG(LOG_DEBUG, tts_tag(), "=== Voice list ===");
1197
1198         if (g_slist_length(g_cur_voices) > 0) {
1199                 /* Get a first item */
1200                 iter = g_slist_nth(g_cur_voices, 0);
1201
1202                 int i = 1;
1203                 while (NULL != iter) {
1204                         /*Get handle data from list*/
1205                         data = iter->data;
1206
1207                         if (NULL == data || NULL == data->lang) {
1208                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Data is invalid");
1209                                 return 0;
1210                         }
1211
1212                         SLOG(LOG_DEBUG, tts_tag(), "[%dth] default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
1213                                  i, data->is_default, data->is_loaded,  data->client_ref_count, data->lang, data->type);
1214
1215                         /*Get next item*/
1216                         iter = g_slist_next(iter);
1217                         i++;
1218                 }
1219         }
1220
1221         SLOG(LOG_DEBUG, tts_tag(), "==================");
1222
1223         return 0;
1224 }
1225
1226 int __internal_get_engine_info(ttse_request_callback_s* callback)
1227 {
1228         SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent DEBUG] === inside __internal_get_engine_info");
1229
1230         if (NULL == callback) {
1231                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid engine");
1232                 return TTSD_ERROR_ENGINE_NOT_FOUND;
1233         }
1234
1235         if (NULL == callback->get_info) {
1236                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid engine");
1237                 return TTSD_ERROR_ENGINE_NOT_FOUND;
1238         }
1239
1240         if (0 != callback->get_info(&(g_engine_info->engine_uuid), &(g_engine_info->engine_name), &(g_engine_info->engine_setting_path), &(g_engine_info->use_network))) {
1241                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get engine info");
1242                 return TTSD_ERROR_ENGINE_NOT_FOUND;
1243         }
1244
1245         if (NULL != g_engine_info->engine_path) {
1246                 free(g_engine_info->engine_path);
1247                 g_engine_info->engine_path = NULL;
1248         }
1249         g_engine_info->engine_path = strdup("empty");
1250         g_engine_info->is_loaded = false;
1251
1252         if (NULL != g_engine_info->callbacks) {
1253                 free(g_engine_info->callbacks);
1254                 g_engine_info->callbacks = NULL;
1255         }
1256         g_engine_info->callbacks = (tts_engine_callback_s*)calloc(1, sizeof(tts_engine_callback_s));
1257         if (NULL == g_engine_info->callbacks) {
1258                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to allocate memory");
1259                 return TTSD_ERROR_OUT_OF_MEMORY;
1260         }
1261
1262         g_engine_info->callbacks->get_info = callback->get_info;
1263         g_engine_info->callbacks->initialize = callback->initialize;
1264         g_engine_info->callbacks->deinitialize = callback->deinitialize;
1265         g_engine_info->callbacks->foreach_voices = callback->foreach_voices;
1266         g_engine_info->callbacks->is_valid_voice = callback->is_valid_voice;
1267         g_engine_info->callbacks->set_pitch = callback->set_pitch;
1268         g_engine_info->callbacks->load_voice = callback->load_voice;
1269         g_engine_info->callbacks->unload_voice = callback->unload_voice;
1270         g_engine_info->callbacks->start_synth = callback->start_synth;
1271         g_engine_info->callbacks->cancel_synth = callback->cancel_synth;
1272         g_engine_info->callbacks->check_app_agreed = callback->check_app_agreed;
1273         g_engine_info->callbacks->need_app_credential = callback->need_app_credential;
1274
1275         g_engine_info->callbacks->private_data_set = NULL;
1276         g_engine_info->callbacks->private_data_requested = NULL;
1277
1278         SLOG(LOG_DEBUG, tts_tag(), "--- Valid Engine ---");
1279         SLOG(LOG_DEBUG, tts_tag(), "Engine uuid : %s", g_engine_info->engine_uuid);
1280         SLOG(LOG_DEBUG, tts_tag(), "Engine name : %s", g_engine_info->engine_name);
1281         SLOG(LOG_DEBUG, tts_tag(), "Engine path : %s", g_engine_info->engine_path);
1282         SLOG(LOG_DEBUG, tts_tag(), "Engine setting path : %s", g_engine_info->engine_setting_path);
1283         SLOG(LOG_DEBUG, tts_tag(), "Use network : %s", g_engine_info->use_network ? "true" : "false");
1284         SLOG(LOG_DEBUG, tts_tag(), "--------------------");
1285         SLOG(LOG_DEBUG, tts_tag(), "  ");
1286
1287         return TTSD_ERROR_NONE;
1288
1289 }
1290
1291
1292 /** Set callbacks of the current engine */
1293 int ttsd_engine_agent_set_private_data_set_cb(ttse_private_data_set_cb callback)
1294 {
1295         if (false == g_agent_init) {
1296                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1297                 return TTSD_ERROR_OPERATION_FAILED;
1298         }
1299
1300         if (NULL == g_engine_info) {
1301                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] The engine is not valid");
1302                 return TTSD_ERROR_INVALID_PARAMETER;
1303         }
1304
1305         if (false == g_engine_info->is_loaded) {
1306                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not loaded engine");
1307                 return TTSD_ERROR_OPERATION_FAILED;
1308         }
1309
1310         g_engine_info->callbacks->private_data_set = callback;
1311
1312         return TTSD_ERROR_NONE;
1313 }
1314
1315 int ttsd_engine_agent_set_private_data_requested_cb(ttse_private_data_requested_cb callback)
1316 {
1317         if (false == g_agent_init) {
1318                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1319                 return TTSD_ERROR_OPERATION_FAILED;
1320         }
1321
1322         if (NULL == g_engine_info) {
1323                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] The engine is not valid");
1324                 return TTSD_ERROR_INVALID_PARAMETER;
1325         }
1326
1327         if (false == g_engine_info->is_loaded) {
1328                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not loaded engine");
1329                 return TTSD_ERROR_OPERATION_FAILED;
1330         }
1331
1332         g_engine_info->callbacks->private_data_requested = callback;
1333
1334         return TTSD_ERROR_NONE;
1335 }
1336
1337