bf26f9cec9d0dd06904a08107f4409e54a8ec9f5
[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         return 0;
748 }
749
750 int ttsd_engine_agent_is_credential_needed(int uid, bool* credential_needed)
751 {
752         if (NULL == credential_needed) {
753                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid Parameter");
754                 return TTSD_ERROR_INVALID_PARAMETER;
755         }
756
757         if (false == g_agent_init) {
758                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
759                 return TTSD_ERROR_OPERATION_FAILED;
760         }
761
762         if (false == g_engine_info->is_loaded) {
763                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not loaded engine");
764                 return TTSD_ERROR_OPERATION_FAILED;
765         }
766
767         if (NULL == g_engine_info->callbacks->need_app_credential) {
768                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not support to check app credential");
769                 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
770         }
771
772         bool result = false;
773         result = g_engine_info->callbacks->need_app_credential();
774         *credential_needed = result;
775
776         return TTSD_ERROR_NONE;
777 }
778
779 /******************************************************************************************
780 * TTS Engine Interfaces for client
781 *******************************************************************************************/
782
783 int ttsd_engine_load_voice(const char* lang, const int vctype)
784 {
785         if (false == g_agent_init) {
786                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
787                 return TTSD_ERROR_OPERATION_FAILED;
788         }
789
790         if (false == g_engine_info->is_loaded) {
791                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
792                 return TTSD_ERROR_ENGINE_NOT_FOUND;
793         }
794
795         if (NULL == lang) {
796                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No language parameter");
797                 return TTSD_ERROR_INVALID_PARAMETER;
798         }
799
800         /* 1. Find voice info */
801         int ret = -1;
802         GSList *iter = NULL;
803         ttsvoice_s* data = NULL;
804
805         iter = g_slist_nth(g_cur_voices, 0);
806         while (NULL != iter) {
807                 /*Get handle data from list*/
808                 data = iter->data;
809
810                 if (NULL != data) {
811                         if (NULL != data->lang && 0 == strcmp(data->lang, lang) && data->type == vctype) {
812                                 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Find voice : default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
813                                          data->is_default, data->is_loaded,  data->client_ref_count, data->lang, data->type);
814                                 break;
815                         }
816                 }
817
818                 /*Get next item*/
819                 iter = g_slist_next(iter);
820                 data = NULL;
821         }
822
823         if (NULL == data) {
824                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
825                 return TTSD_ERROR_OPERATION_FAILED;
826         }
827
828         /* 2. increse ref count */
829         data->client_ref_count++;
830
831         /* 3. if ref count change 0 to 1 and not default, load voice */
832         if (1 == data->client_ref_count && false == data->is_default) {
833                 /* load voice */
834                 ret = g_engine_info->callbacks->load_voice(data->lang, data->type);
835                         if (0 == ret) {
836                         SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Load voice : lang(%s), type(%d)", 
837                                         data->lang, data->type);
838                                 data->is_loaded = true;
839                         } else {
840                         SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to load voice : lang(%s), type(%d), result(%s)",
841                                         data->lang, data->type, __ttsd_get_engine_error_code(ret));
842
843                                 return TTSD_ERROR_OPERATION_FAILED;
844                         }
845                 } else {
846                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Not load voice : default voice(%d) or ref count(%d)",
847                         data->is_default, data->client_ref_count);
848         }
849
850 #ifdef ENGINE_AGENT_DEBUG
851         ttsd_print_voicelist();
852 #endif
853
854         return 0;
855 }
856
857 int ttsd_engine_unload_voice(const char* lang, const int vctype)
858 {
859         if (false == g_agent_init) {
860                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
861                 return TTSD_ERROR_OPERATION_FAILED;
862         }
863
864         if (false == g_engine_info->is_loaded) {
865                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
866                 return TTSD_ERROR_ENGINE_NOT_FOUND;
867         }
868
869         if (NULL == lang) {
870                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No language parameter");
871                 return TTSD_ERROR_INVALID_PARAMETER;
872         }
873
874         /* 1. Find voice info */
875         int ret = -1;
876         GSList *iter = NULL;
877         ttsvoice_s* data = NULL;
878
879         iter = g_slist_nth(g_cur_voices, 0);
880         while (NULL != iter) {
881                 /*Get handle data from list*/
882                 data = iter->data;
883
884                 if (NULL != data) {
885                         if (NULL != data->lang && 0 == strcmp(data->lang, lang) && data->type == vctype) {
886                                 SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Find voice : default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
887                                          data->is_default, data->is_loaded,  data->client_ref_count, data->lang, data->type);
888                                 break;
889                         }
890                 }
891
892                 /*Get next item*/
893                 iter = g_slist_next(iter);
894                 data = NULL;
895         }
896
897         if (NULL == data) {
898                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] This voice is not supported voice : lang(%s) type(%d)", lang, vctype);
899                 return TTSD_ERROR_OPERATION_FAILED;
900         }
901
902         /* 2. Decrese ref count */
903         data->client_ref_count--;
904
905         /* 3. if ref count change 0 and not default, load voice */
906         if (0 == data->client_ref_count && false == data->is_default) {
907                 /* unload voice */
908                 ret = g_engine_info->callbacks->unload_voice(data->lang, data->type);
909                         if (0 == ret) {
910                         SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent SUCCESS] Unload voice : lang(%s), type(%d)", 
911                                         data->lang, data->type);
912                                 data->is_loaded = false;
913                         } else {
914                         SECURE_SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to unload voice : lang(%s), type(%d), result(%s)",
915                                         data->lang, data->type, __ttsd_get_engine_error_code(ret));
916
917                                 return TTSD_ERROR_OPERATION_FAILED;
918                         }
919                 } else {
920                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Not unload voice : default voice(%d) or ref count(%d)",
921                         data->is_default, data->client_ref_count);
922         }
923
924 #ifdef ENGINE_AGENT_DEBUG
925         ttsd_print_voicelist();
926 #endif
927         return 0;
928 }
929
930 int ttsd_engine_start_synthesis(const char* lang, int vctype, const char* text, int speed, const char* appid, const char* credential, void* user_param)
931 {
932         if (NULL == lang || NULL == text) {
933                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
934                 return TTSD_ERROR_INVALID_PARAMETER;
935         }
936
937         if (false == g_agent_init) {
938                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
939                 return TTSD_ERROR_OPERATION_FAILED;
940         }
941
942         if (false == g_engine_info->is_loaded) {
943                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
944                 return TTSD_ERROR_ENGINE_NOT_FOUND;
945         }
946
947         /* select voice for default */
948         char* temp_lang = NULL;
949         int temp_type;
950         if (true != ttsd_engine_select_valid_voice(lang, vctype, &temp_lang, &temp_type)) {
951                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to select default voice");
952                 if (NULL != temp_lang)  free(temp_lang);
953                 return TTSD_ERROR_INVALID_VOICE;
954         } else {
955                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent] Start synthesis : language(%s), type(%d), speed(%d), text(%s), credential(%s)", 
956                         (NULL == temp_lang) ? "NULL" : temp_lang, temp_type, speed, (NULL == text) ? "NULL" : text, (NULL == credential) ? "NULL" : credential);
957         }
958
959         int temp_speed;
960
961         if (0 == speed) {
962                 temp_speed = g_engine_info->default_speed;
963         } else {
964                 temp_speed = speed;
965         }
966
967         /* synthesize text */
968         int ret = 0;
969         ret = g_engine_info->callbacks->start_synth(temp_lang, temp_type, text, temp_speed, appid, credential, user_param);
970         if (0 != ret) {
971                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] ***************************************");
972                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] * synthesize error : %s *", __ttsd_get_engine_error_code(ret));
973                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] ***************************************");
974                 if (NULL != temp_lang) {
975                         free(temp_lang);
976                         temp_lang = NULL;
977                 }
978                 return ret;
979         }
980
981         if (NULL != temp_lang)  {
982                 free(temp_lang);
983                 temp_lang = NULL;
984         }
985         return 0;
986 }
987
988 int ttsd_engine_cancel_synthesis()
989 {
990         if (false == g_agent_init) {
991                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
992                 return TTSD_ERROR_OPERATION_FAILED;
993         }
994
995         if (false == g_engine_info->is_loaded) {
996                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
997                 return TTSD_ERROR_ENGINE_NOT_FOUND;
998         }
999
1000         /* stop synthesis */
1001         int ret = 0;
1002         ret = g_engine_info->callbacks->cancel_synth();
1003         if (0 != ret) {
1004                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] fail cancel synthesis : %s", __ttsd_get_engine_error_code(ret));
1005         }
1006
1007         return ret;
1008 }
1009
1010 bool __supported_voice_cb(const char* language, int type, void* user_data)
1011 {
1012         GList** voice_list = (GList**)user_data;
1013
1014         if (NULL == language || NULL == voice_list) {
1015                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
1016                 return false;
1017         }
1018
1019         voice_s* voice = calloc(1, sizeof(voice_s));
1020         if (NULL == voice) {
1021                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to allocate memory");
1022                 return false;
1023         }
1024         voice->language = strdup(language);
1025         voice->type = type;
1026
1027         *voice_list = g_list_append(*voice_list, voice);
1028
1029         return true;
1030 }
1031
1032 int ttsd_engine_get_voice_list(GList** voice_list)
1033 {
1034         if (NULL == voice_list) {
1035                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
1036                 return TTSD_ERROR_INVALID_PARAMETER;
1037         }
1038
1039         if (false == g_agent_init) {
1040                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1041                 return TTSD_ERROR_OPERATION_FAILED;
1042         }
1043
1044         if (false == g_engine_info->is_loaded) {
1045                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
1046                 return TTSD_ERROR_ENGINE_NOT_FOUND;
1047         }
1048
1049         int ret = 0;
1050         ret = g_engine_info->callbacks->foreach_voices(__supported_voice_cb, (void*)voice_list);
1051         if (0 != ret) {
1052                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get voice list : %s", __ttsd_get_engine_error_code(ret));
1053         }
1054
1055         return ret;
1056 }
1057
1058 int ttsd_engine_get_default_voice(char** lang, int* vctype)
1059 {
1060         if (false == g_agent_init) {
1061                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1062                 return TTSD_ERROR_OPERATION_FAILED;
1063         }
1064
1065         if (false == g_engine_info->is_loaded) {
1066                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
1067                 return TTSD_ERROR_ENGINE_NOT_FOUND;
1068         }
1069
1070         if (NULL == lang || NULL == vctype) {
1071                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] BAD Parameter");
1072                 return TTSD_ERROR_INVALID_PARAMETER;
1073         }
1074
1075         if (NULL != g_engine_info->default_lang) {
1076                 *lang = strdup(g_engine_info->default_lang);
1077                 *vctype = g_engine_info->default_vctype;
1078
1079                 SECURE_SLOG(LOG_DEBUG, tts_tag(), "[Engine] Get default voice : language(%s), type(%d)", *lang, *vctype);
1080         } else {
1081                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Default voice is NULL");
1082                 return TTSD_ERROR_OPERATION_FAILED;
1083         }
1084
1085         return 0;
1086 }
1087
1088 int ttsd_engine_set_private_data(const char* key, const char* data)
1089 {
1090         if (false == g_agent_init) {
1091                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1092                 return TTSD_ERROR_OPERATION_FAILED;
1093         }
1094
1095         if (false == g_engine_info->is_loaded) {
1096                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
1097                 return TTSD_ERROR_ENGINE_NOT_FOUND;
1098         }
1099
1100         if (NULL == key) {
1101                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
1102                 return TTSD_ERROR_INVALID_PARAMETER;
1103         }
1104
1105         if (NULL == g_engine_info->callbacks->private_data_set) {
1106                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not supported feature");
1107                 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1108         }
1109
1110         int ret = g_engine_info->callbacks->private_data_set(key, data);
1111
1112         if (0 != ret) {
1113                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to set private data(%d)", ret);
1114         }
1115
1116         return ret;
1117 }
1118
1119 int ttsd_engine_get_private_data(const char* key, char** data)
1120 {
1121         if (false == g_agent_init) {
1122                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1123                 return TTSD_ERROR_OPERATION_FAILED;
1124         }
1125
1126         if (false == g_engine_info->is_loaded) {
1127                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] No loaded engine");
1128                 return TTSD_ERROR_ENGINE_NOT_FOUND;
1129         }
1130
1131         if (NULL == key || NULL == data) {
1132                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid parameter");
1133                 return TTSD_ERROR_INVALID_PARAMETER;
1134         }
1135
1136
1137         if (NULL == g_engine_info->callbacks->private_data_requested) {
1138                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not supported feature");
1139                 return TTSD_ERROR_NOT_SUPPORTED_FEATURE;
1140         }
1141
1142         char* temp = NULL;
1143         int ret = 0;
1144         ret = g_engine_info->callbacks->private_data_requested(key, &temp);
1145         if (0 != ret) {
1146                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get private data(%d)", ret);
1147         }
1148
1149         if (NULL == temp)
1150                 *data = strdup("NULL");
1151         else
1152                 *data = strdup(temp);
1153
1154         return ret;
1155 }
1156
1157 void __free_voice_list(GList* voice_list)
1158 {
1159         GList *iter = NULL;
1160         voice_s* data = NULL;
1161
1162         /* if list have item */
1163         if (g_list_length(voice_list) > 0) {
1164                 /* Get a first item */
1165                 iter = g_list_first(voice_list);
1166
1167                 while (NULL != iter) {
1168                         data = iter->data;
1169
1170                         if (NULL != data) {
1171                                 if (NULL != data->language)     free(data->language);
1172                                 free(data);
1173                         }
1174
1175                         voice_list = g_list_remove_link(voice_list, iter);
1176                         g_list_free(iter);
1177                         iter = g_list_first(voice_list);
1178                 }
1179         }
1180 }
1181
1182 /*
1183 * TTS Engine Callback Functions                                                                                 `                                 *
1184 */
1185
1186 /* function for debugging */
1187 int ttsd_print_voicelist()
1188 {
1189         /* Test log */
1190         GSList *iter = NULL;
1191         ttsvoice_s* data = NULL;
1192
1193         SLOG(LOG_DEBUG, tts_tag(), "=== Voice list ===");
1194
1195         if (g_slist_length(g_cur_voices) > 0) {
1196                 /* Get a first item */
1197                 iter = g_slist_nth(g_cur_voices, 0);
1198
1199                 int i = 1;
1200                 while (NULL != iter) {
1201                         /*Get handle data from list*/
1202                         data = iter->data;
1203
1204                         if (NULL == data || NULL == data->lang) {
1205                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Data is invalid");
1206                                 return 0;
1207                         }
1208
1209                         SLOG(LOG_DEBUG, tts_tag(), "[%dth] default(%d) loaded(%d) ref(%d) lang(%s) type(%d)",
1210                                  i, data->is_default, data->is_loaded,  data->client_ref_count, data->lang, data->type);
1211
1212                         /*Get next item*/
1213                         iter = g_slist_next(iter);
1214                         i++;
1215                 }
1216         }
1217
1218         SLOG(LOG_DEBUG, tts_tag(), "==================");
1219
1220         return 0;
1221 }
1222
1223 int __internal_get_engine_info(ttse_request_callback_s* callback)
1224 {
1225         SLOG(LOG_DEBUG, tts_tag(), "[Engine Agent DEBUG] === inside __internal_get_engine_info");
1226
1227         if (NULL == callback) {
1228                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid engine");
1229                 return TTSD_ERROR_ENGINE_NOT_FOUND;
1230         }
1231
1232         if (NULL == callback->get_info) {
1233                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Invalid engine");
1234                 return TTSD_ERROR_ENGINE_NOT_FOUND;
1235         }
1236
1237         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))) {
1238                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to get engine info");
1239                 return TTSD_ERROR_ENGINE_NOT_FOUND;
1240         }
1241
1242         if (NULL != g_engine_info->engine_path) {
1243                 free(g_engine_info->engine_path);
1244                 g_engine_info->engine_path = NULL;
1245         }
1246         g_engine_info->engine_path = strdup("empty");
1247         g_engine_info->is_loaded = false;
1248
1249         if (NULL != g_engine_info->callbacks) {
1250                 free(g_engine_info->callbacks);
1251                 g_engine_info->callbacks = NULL;
1252         }
1253         g_engine_info->callbacks = (tts_engine_callback_s*)calloc(1, sizeof(tts_engine_callback_s));
1254         if (NULL == g_engine_info->callbacks) {
1255                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Fail to allocate memory");
1256                 return TTSD_ERROR_OUT_OF_MEMORY;
1257         }
1258
1259         g_engine_info->callbacks->get_info = callback->get_info;
1260         g_engine_info->callbacks->initialize = callback->initialize;
1261         g_engine_info->callbacks->deinitialize = callback->deinitialize;
1262         g_engine_info->callbacks->foreach_voices = callback->foreach_voices;
1263         g_engine_info->callbacks->is_valid_voice = callback->is_valid_voice;
1264         g_engine_info->callbacks->set_pitch = callback->set_pitch;
1265         g_engine_info->callbacks->load_voice = callback->load_voice;
1266         g_engine_info->callbacks->unload_voice = callback->unload_voice;
1267         g_engine_info->callbacks->start_synth = callback->start_synth;
1268         g_engine_info->callbacks->cancel_synth = callback->cancel_synth;
1269         g_engine_info->callbacks->check_app_agreed = callback->check_app_agreed;
1270         g_engine_info->callbacks->need_app_credential = callback->need_app_credential;
1271
1272         g_engine_info->callbacks->private_data_set = NULL;
1273         g_engine_info->callbacks->private_data_requested = NULL;
1274
1275         SLOG(LOG_DEBUG, tts_tag(), "--- Valid Engine ---");
1276         SLOG(LOG_DEBUG, tts_tag(), "Engine uuid : %s", g_engine_info->engine_uuid);
1277         SLOG(LOG_DEBUG, tts_tag(), "Engine name : %s", g_engine_info->engine_name);
1278         SLOG(LOG_DEBUG, tts_tag(), "Engine path : %s", g_engine_info->engine_path);
1279         SLOG(LOG_DEBUG, tts_tag(), "Engine setting path : %s", g_engine_info->engine_setting_path);
1280         SLOG(LOG_DEBUG, tts_tag(), "Use network : %s", g_engine_info->use_network ? "true" : "false");
1281         SLOG(LOG_DEBUG, tts_tag(), "--------------------");
1282         SLOG(LOG_DEBUG, tts_tag(), "  ");
1283
1284         return TTSD_ERROR_NONE;
1285
1286 }
1287
1288
1289 /** Set callbacks of the current engine */
1290 int ttsd_engine_agent_set_private_data_set_cb(ttse_private_data_set_cb callback)
1291 {
1292         if (false == g_agent_init) {
1293                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1294                 return TTSD_ERROR_OPERATION_FAILED;
1295         }
1296
1297         if (NULL == g_engine_info) {
1298                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] The engine is not valid");
1299                 return TTSD_ERROR_INVALID_PARAMETER;
1300         }
1301
1302         if (false == g_engine_info->is_loaded) {
1303                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not loaded engine");
1304                 return TTSD_ERROR_OPERATION_FAILED;
1305         }
1306
1307         g_engine_info->callbacks->private_data_set = callback;
1308
1309         return TTSD_ERROR_NONE;
1310 }
1311
1312 int ttsd_engine_agent_set_private_data_requested_cb(ttse_private_data_requested_cb callback)
1313 {
1314         if (false == g_agent_init) {
1315                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not Initialized");
1316                 return TTSD_ERROR_OPERATION_FAILED;
1317         }
1318
1319         if (NULL == g_engine_info) {
1320                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] The engine is not valid");
1321                 return TTSD_ERROR_INVALID_PARAMETER;
1322         }
1323
1324         if (false == g_engine_info->is_loaded) {
1325                 SLOG(LOG_ERROR, tts_tag(), "[Engine Agent ERROR] Not loaded engine");
1326                 return TTSD_ERROR_OPERATION_FAILED;
1327         }
1328
1329         g_engine_info->callbacks->private_data_requested = callback;
1330
1331         return TTSD_ERROR_NONE;
1332 }
1333
1334