Update tts for tizen 2.0 beta
[platform/core/uifw/tts.git] / server / ttsd_engine_agent.c
1 /*
2 *  Copyright (c) 2011 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 "ttsd_main.h"
19 #include "ttsd_engine_agent.h"
20 #include "ttsd_config.h"
21
22 #define ENGINE_PATH_SIZE        256
23
24 /*
25 * Internal data structure
26 */
27 typedef struct {
28         /* base info */
29         char*   engine_uuid;
30         char*   engine_name; 
31         char*   engine_path;
32
33         /* info for using engine load*/
34         bool    is_set;
35         bool    is_loaded;              
36         bool    need_network;
37         void    *handle;
38
39         /* engine base setting */
40         char*   default_lang;
41         int     default_vctype;
42         int     default_speed;
43
44         ttspe_funcs_s*  pefuncs;
45         ttspd_funcs_s*  pdfuncs;
46
47         int (*ttsp_load_engine)(const ttspd_funcs_s* pdfuncs, ttspe_funcs_s* pefuncs);
48         int (*ttsp_unload_engine)();
49 } ttsengine_s;
50
51 typedef struct {
52         char*   engine_uuid;
53         char*   engine_path;
54         char*   engine_name;
55         char*   setting_ug_path;
56         bool    use_network;
57 } ttsengine_info_s;
58
59
60 /** Init flag */
61 static bool g_agent_init;
62
63 /** TTS engine list */
64 static GList *g_engine_list;            
65
66 /** Current engine information */
67 static ttsengine_s g_cur_engine;
68
69 /** Result callback function */
70 static synth_result_callback g_result_cb;
71
72
73 /** Set current engine */
74 int __internal_set_current_engine(const char* engine_uuid);
75
76 /** Check engine id */
77 int __internal_check_engine_id(const char* engine_uuid);
78
79 /** Update engine list */
80 int __internal_update_engine_list();
81
82 /** Get engine info */
83 int __internal_get_engine_info(const char* filepath, ttsengine_info_s** info);
84
85 /** Callback function for result */
86 bool __result_cb(ttsp_result_event_e event, const void* data, unsigned int data_size, void *user_data);
87
88 /** Callback function for voice list */
89 bool __supported_voice_cb(const char* language, ttsp_voice_type_e type, void* user_data);
90
91 /** Free voice list */
92 void __free_voice_list(GList* voice_list);
93
94 /** Callback function for engine info */
95 void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* setting_ug_name, 
96                       bool use_network, void* user_data);
97
98 /** Callback fucntion for engine setting */
99 bool __engine_setting_cb(const char* key, const char* value, void* user_data);
100
101
102 int ttsd_engine_agent_init(synth_result_callback result_cb)
103 {
104         /* initialize static data */
105         if (result_cb == NULL) {
106                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] invalid parameter \n");
107                 return TTSD_ERROR_INVALID_PARAMETER;
108         }
109
110         g_result_cb = result_cb;
111
112         g_cur_engine.engine_uuid = NULL;
113         g_cur_engine.engine_name = NULL;
114         g_cur_engine.engine_path = NULL;
115
116         g_cur_engine.is_set = false;
117         g_cur_engine.handle = NULL;
118         g_cur_engine.pefuncs = (ttspe_funcs_s*)g_malloc0( sizeof(ttspe_funcs_s) );
119         g_cur_engine.pdfuncs = (ttspd_funcs_s*)g_malloc0( sizeof(ttspd_funcs_s) );
120
121         g_agent_init = true;
122
123         if (0 != ttsd_config_get_default_voice(&(g_cur_engine.default_lang), &(g_cur_engine.default_vctype))) {
124                 SLOG(LOG_WARN, TAG_TTSD, "[Server WARNING] There is No default voice in config\n"); 
125                 /* Set default voice */
126                 g_cur_engine.default_lang = strdup("en_US");
127                 g_cur_engine.default_vctype = TTSP_VOICE_TYPE_FEMALE;
128         }
129
130         if (0 != ttsd_config_get_default_speed(&(g_cur_engine.default_speed))) {
131                 SLOG(LOG_WARN, TAG_TTSD, "[Server WARNING] There is No default speed in config\n"); 
132                 ttsd_config_set_default_speed((int)TTSP_SPEED_NORMAL);
133                 g_cur_engine.default_speed = TTSP_SPEED_NORMAL;
134         }
135
136         SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent SUCCESS] Initialize Engine Agent ");
137
138         return 0;
139 }
140
141 int ttsd_engine_agent_release()
142 {
143         if (false == g_agent_init) {
144                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
145                 return TTSD_ERROR_OPERATION_FAILED;
146         }
147
148         /* unload current engine */
149         ttsd_engine_agent_unload_current_engine();
150
151         /* release engine list */
152         GList *iter = NULL;
153         ttsengine_s *data = NULL;
154
155         if (g_list_length(g_engine_list) > 0) {
156                 /* Get a first item */
157                 iter = g_list_first(g_engine_list);
158
159                 while (NULL != iter) {
160                         /* Get data from item */
161                         data = iter->data;
162                         dlclose(data->handle); 
163
164                         iter = g_list_remove(iter, data);
165                 }
166         }
167
168         g_list_free(iter);
169
170         /* release current engine data */
171         if (g_cur_engine.pefuncs != NULL)
172                 g_free(g_cur_engine.pefuncs);
173         
174         if (g_cur_engine.pdfuncs != NULL)
175                 g_free(g_cur_engine.pdfuncs);
176
177         g_result_cb = NULL;
178         g_agent_init = false;
179
180         if (g_cur_engine.default_lang != NULL) 
181                 g_free(g_cur_engine.default_lang);
182
183
184         SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent SUCCESS] Release Engine Agent\n");
185
186         return 0;
187 }
188
189 int ttsd_engine_agent_initialize_current_engine()
190 {
191         if (false == g_agent_init) {
192                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
193                 return TTSD_ERROR_OPERATION_FAILED;
194         }
195
196         /* update engine list */
197         if (0 != __internal_update_engine_list()) {
198                 SLOG(LOG_WARN, TAG_TTSD, "[Engine Agent WARNING] No engine error \n");
199                 return TTSD_ERROR_OPERATION_FAILED;
200         }
201
202         /* 2. get current engine from config */
203         char* cur_engine_uuid = NULL;
204         bool is_get_engineid_from_config = false;
205
206         if (0 != ttsd_config_get_default_engine(&cur_engine_uuid)) {
207                 /*not set current engine */
208                 /*set system default engine*/
209                 GList *iter = NULL;
210                 ttsengine_info_s *data = NULL;
211
212                 if (g_list_length(g_engine_list) > 0) {
213                         iter = g_list_first(g_engine_list);
214                         char* default_engine = "27F277E9-BBC4-4dca-B553-D9884A3CDAA0";
215
216                         while (NULL != iter) {
217                                 data = iter->data;
218
219                                 if (0 == strncmp(data->engine_uuid, default_engine, strlen(default_engine))) {
220                                         /* current data is default engine */
221                                         break;
222                                 }
223
224                                 iter = g_list_next(iter);
225                         }
226                 } else {
227                         SLOG(LOG_WARN, TAG_TTSD, "[Engine Agent WARNING] Fail to set a engine of engine list\n");
228                         return TTSD_ERROR_OPERATION_FAILED;     
229                 }
230
231                 if (NULL != data->engine_uuid) {
232                         cur_engine_uuid = strdup(data->engine_uuid); 
233                 } else {
234                         SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Data of current engine is corrupt\n");
235                         return TTSD_ERROR_OPERATION_FAILED;
236                 }
237                 
238                 is_get_engineid_from_config = false;
239         } else {
240                 is_get_engineid_from_config = true;
241         }
242
243         /* check whether cur engine uuid is valid or not. */
244         if (0 != __internal_check_engine_id(cur_engine_uuid)) {
245                 SLOG(LOG_WARN, TAG_TTSD, "[Engine Agent WARNING] It is not valid engine id from config \n");
246
247                 GList *iter = NULL;
248                 
249                 if (g_list_length(g_engine_list) > 0) 
250                         iter = g_list_first(g_engine_list);
251                 else {
252                         SLOG(LOG_WARN, TAG_TTSD, "[Engine Agent ERROR] NO TTS Engine !! \n");
253                         return TTSD_ERROR_OPERATION_FAILED;     
254                 }
255
256                 if (cur_engine_uuid != NULL)    
257                         g_free(cur_engine_uuid);
258
259                 ttsengine_info_s *data = NULL;
260                 data = iter->data;
261
262                 cur_engine_uuid = g_strdup(data->engine_uuid);
263
264                 is_get_engineid_from_config = false;
265         }
266
267         if (NULL != cur_engine_uuid) 
268                 SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent] Current Engine Id : %s \n", cur_engine_uuid);
269         else 
270                 return TTSD_ERROR_OPERATION_FAILED;
271
272         /* set current engine */
273         if (0 != __internal_set_current_engine(cur_engine_uuid)) {
274                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] fail to set current engine ");
275                 return TTSD_ERROR_OPERATION_FAILED;
276         } 
277
278         if (false == is_get_engineid_from_config) {
279                 if (0 != ttsd_config_set_default_engine(cur_engine_uuid))
280                         SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] fail to set id to config \n"); 
281         }
282
283         if (NULL != cur_engine_uuid)    
284                 g_free(cur_engine_uuid);
285
286         SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent SUCCESS] Set current engine"); 
287
288         return 0;
289 }
290
291 int __internal_check_engine_id(const char* engine_uuid)
292 {
293         GList *iter = NULL;
294         ttsengine_s *data = NULL;
295
296         if (g_list_length(g_engine_list) > 0) {
297                 iter = g_list_first(g_engine_list);
298
299                 while (NULL != iter) {
300                         data = iter->data;
301
302                         if (0 == strncmp(engine_uuid, data->engine_uuid, strlen(data->engine_uuid))) 
303                                 return 0;
304         
305                         iter = g_list_next(iter);
306                 }
307         }
308
309         return -1;
310 }
311
312 void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* setting_ug_name, 
313                              bool use_network, void* user_data)
314 {
315         ttsengine_info_s* temp = (ttsengine_info_s*)user_data; 
316
317         temp->engine_uuid = g_strdup(engine_uuid);
318         temp->engine_name = g_strdup(engine_name);
319         temp->setting_ug_path = g_strdup(setting_ug_name);
320         temp->use_network = use_network;
321 }
322
323 int __internal_get_engine_info(const char* filepath, ttsengine_info_s** info)
324 {
325         char *error;
326         void* handle;
327
328         handle = dlopen (filepath, RTLD_LAZY );
329
330         if (!handle) {
331                 SLOG(LOG_WARN, TAG_TTSD, "[Engine Agent] Invalid engine : %s", filepath); 
332                 return TTSD_ERROR_OPERATION_FAILED;
333         }
334
335         /* link engine to daemon */
336         dlsym(handle, "ttsp_load_engine");
337         if ((error = dlerror()) != NULL) {
338                 SLOG(LOG_WARN, TAG_TTSD, "[Engine Agent] Invalid engine. Fail to open ttsp_load_engine : %s", filepath);
339                 dlclose(handle);
340                 return TTSD_ERROR_OPERATION_FAILED;
341         }
342
343         dlsym(handle, "ttsp_unload_engine");
344         if ((error = dlerror()) != NULL) {
345                 SLOG(LOG_WARN, TAG_TTSD, "[Engine Agent] Invalid engine. Fail to open ttsp_unload_engine : %s", filepath);
346                 dlclose(handle);
347                 return TTSD_ERROR_OPERATION_FAILED;
348         }
349
350         int (*get_engine_info)(ttsp_engine_info_cb callback, void* user_data);
351
352         get_engine_info = (int (*)(ttsp_engine_info_cb, void*))dlsym(handle, "ttsp_get_engine_info");
353         if ((error = dlerror()) != NULL) {
354                 SLOG(LOG_WARN, TAG_TTSD, "[Engine Agent] ttsp_get_engine_info() link error\n");
355                 dlclose(handle);
356                 return TTSD_ERROR_OPERATION_FAILED;
357         }
358
359         ttsengine_info_s* temp;
360         temp = (ttsengine_info_s*)g_malloc0(sizeof(ttsengine_info_s));
361
362         /* get engine info */
363         if (0 != get_engine_info(&__engine_info_cb, (void*)temp)) {
364                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] fail to get engine info\n");
365                 dlclose(handle);
366                 g_free(temp);
367                 return TTSD_ERROR_OPERATION_FAILED;
368         }
369
370         /* close engine */
371         dlclose(handle);
372
373         temp->engine_path = g_strdup(filepath);
374         
375         SLOG(LOG_DEBUG, TAG_TTSD, "----- Valid engine");
376         SLOG(LOG_DEBUG, TAG_TTSD, "Engine uuid : %s\n", temp->engine_uuid);
377         SLOG(LOG_DEBUG, TAG_TTSD, "Engine name : %s\n", temp->engine_name);
378         SLOG(LOG_DEBUG, TAG_TTSD, "Setting ug path : %s\n", temp->setting_ug_path);
379         SLOG(LOG_DEBUG, TAG_TTSD, "Engine path : %s\n", temp->engine_path);
380         SLOG(LOG_DEBUG, TAG_TTSD, "Use network : %s\n", temp->use_network ? "true":"false");
381         SLOG(LOG_DEBUG, TAG_TTSD, "-----");
382         SLOG(LOG_DEBUG, TAG_TTSD, "  ");
383
384         *info = temp;
385
386         return 0;
387 }
388
389 int __internal_update_engine_list()
390 {
391         /* relsease engine list */
392         GList *iter = NULL;
393         ttsengine_info_s *data = NULL;
394
395         if (g_list_length(g_engine_list) > 0) {
396                 iter = g_list_first(g_engine_list);
397
398                 while (NULL != iter) {
399                         data = iter->data;
400
401                         if (data != NULL)
402                                 g_free(data);
403
404                         g_engine_list = g_list_remove_link(g_engine_list, iter);
405                         iter = g_list_first(g_engine_list);
406                 }
407         }
408
409         /* get file name from engine directory and get engine information from each filename */
410         DIR *dp;
411         struct dirent *dirp;
412         dp = opendir(ENGINE_DIRECTORY_DEFAULT);
413
414         if (dp != NULL) {
415                 while ((dirp = readdir(dp)) != NULL) {
416                         ttsengine_info_s* info;
417                         char* filepath = NULL;
418                         int file_size;
419
420                         file_size = strlen(ENGINE_DIRECTORY_DEFAULT) + strlen(dirp->d_name) + 5;
421                         filepath = (char*)g_malloc0( sizeof(char) * file_size);
422
423                         if (NULL != filepath) { 
424                                 strncpy(filepath, ENGINE_DIRECTORY_DEFAULT, strlen(ENGINE_DIRECTORY_DEFAULT) );
425                                 strncat(filepath, "/", strlen("/") );
426                                 strncat(filepath, dirp->d_name, strlen(dirp->d_name) );
427                         } else {
428                                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not enough memory!! \n" );
429                                 continue;       
430                         }
431
432                         /* get its info and update engine list */
433                         if (0 == __internal_get_engine_info(filepath, &info)) {
434                                 /* add engine info to g_engine_list */
435                                 g_engine_list = g_list_append(g_engine_list, info);
436                         }
437
438                         if (NULL != filepath)
439                                 g_free(filepath);
440                 }
441
442                 closedir(dp);
443         }
444
445         dp = opendir(ENGINE_DIRECTORY_DOWNLOAD);
446
447         if (dp != NULL) {
448                 while ((dirp = readdir(dp)) != NULL) {
449                         ttsengine_info_s* info;
450                         char* filepath = NULL;
451                         int file_size;
452
453                         file_size = strlen(ENGINE_DIRECTORY_DOWNLOAD) + strlen(dirp->d_name) + 5;
454                         filepath = (char*)g_malloc0( sizeof(char) * file_size);
455
456                         if (NULL != filepath) { 
457                                 strncpy(filepath, ENGINE_DIRECTORY_DOWNLOAD, strlen(ENGINE_DIRECTORY_DOWNLOAD) );
458                                 strncat(filepath, "/", strlen("/") );
459                                 strncat(filepath, dirp->d_name, strlen(dirp->d_name) );
460                         } else {
461                                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not enough memory!! \n" );
462                                 continue;       
463                         }
464
465                         /* get its info and update engine list */
466                         if (0 == __internal_get_engine_info(filepath, &info)) {
467                                 /* add engine info to g_engine_list */
468                                 g_engine_list = g_list_append(g_engine_list, info);
469                         }
470
471                         if (NULL != filepath)
472                                 g_free(filepath);
473                 }
474
475                 closedir(dp);
476         }
477
478         if (g_list_length(g_engine_list) <= 0) {
479                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] No Engine\n");
480                 return TTSD_ERROR_OPERATION_FAILED;     
481         }
482
483 #ifdef ENGINE_AGENT_DEBUG       
484         ttsd_print_enginelist();
485 #endif
486
487         return 0;
488 }
489
490 int __internal_set_current_engine(const char* engine_uuid)
491 {
492         /* check whether engine id is valid or not. */
493         GList *iter = NULL;
494         ttsengine_info_s *data = NULL;
495
496         bool flag = false;
497         if (g_list_length(g_engine_list) > 0) {
498                 iter = g_list_first(g_engine_list);
499
500                 while (NULL != iter) {
501                         data = iter->data;
502
503                         if (0 == strncmp(data->engine_uuid, engine_uuid, strlen(engine_uuid))) {
504                                 flag = true;
505                                 break;
506                         }
507
508                         /*Get next item*/
509                         iter = g_list_next(iter);
510                 }
511         }
512
513         /* If current engine does not exist, return error */
514         if (false == flag) {
515                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] __internal_set_current_engine : Cannot find engine id \n");
516                 return TTSD_ERROR_OPERATION_FAILED;
517         } else {
518                 if (g_cur_engine.engine_uuid != NULL) {
519                         /*compare current engine uuid */
520                         if (0 == strncmp(g_cur_engine.engine_uuid, data->engine_uuid, strlen(engine_uuid))) {
521                                 SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent] tts engine has already been set \n");
522                                 return 0;
523                         }
524                 }
525         }
526
527         /* set data from g_engine_list */
528         if (g_cur_engine.engine_uuid != NULL)   g_free(g_cur_engine.engine_uuid);
529         if (g_cur_engine.engine_name != NULL)   g_free(g_cur_engine.engine_name);
530         if (g_cur_engine.engine_path != NULL)   g_free(g_cur_engine.engine_path);
531
532         if (NULL == data->engine_uuid || NULL == data->engine_name || NULL == data->engine_path) {
533                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] __internal_set_current_engine : Engine data is NULL");
534                 return TTSD_ERROR_OPERATION_FAILED;
535         }
536
537         g_cur_engine.engine_uuid = g_strdup(data->engine_uuid);
538         g_cur_engine.engine_name = g_strdup(data->engine_name);
539         g_cur_engine.engine_path = g_strdup(data->engine_path);
540
541         g_cur_engine.handle = NULL;
542         g_cur_engine.is_loaded = false;
543         g_cur_engine.is_set = true;
544         g_cur_engine.need_network = data->use_network;
545
546         SLOG(LOG_DEBUG, TAG_TTSD, "-----");
547         SLOG(LOG_DEBUG, TAG_TTSD, "Current engine uuid : %s \n", g_cur_engine.engine_uuid);
548         SLOG(LOG_DEBUG, TAG_TTSD, "Current engine name : %s \n", g_cur_engine.engine_name);
549         SLOG(LOG_DEBUG, TAG_TTSD, "Current engine path : %s \n", g_cur_engine.engine_path);
550         SLOG(LOG_DEBUG, TAG_TTSD, "-----");
551
552         return 0;
553 }
554
555 int ttsd_engine_agent_load_current_engine()
556 {
557         if (false == g_agent_init) {
558                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
559                 return TTSD_ERROR_OPERATION_FAILED;
560         }
561
562         if (false == g_cur_engine.is_set) {
563                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] ttsd_engine_agent_load_current_engine : No Current Engine  \n");
564                 return TTSD_ERROR_OPERATION_FAILED;
565         }
566
567         /* check whether current engine is loaded or not */
568         if (true == g_cur_engine.is_loaded ) {
569                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent] ttsd_engine_agent_load_current_engine : Engine has already been loaded  \n" );
570                 return 0;
571         }
572
573         SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent] current engine path : %s\n", g_cur_engine.engine_path);
574
575         /* open engine */
576         char *error = NULL;
577         g_cur_engine.handle = dlopen(g_cur_engine.engine_path, RTLD_LAZY); /* RTLD_LAZY RTLD_NOW*/
578
579         if ((error = dlerror()) != NULL || !g_cur_engine.handle) {
580                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] fail to get current engine handle : dlopen error \n");
581                 return -2;
582         }
583
584         g_cur_engine.ttsp_unload_engine = (int (*)())dlsym(g_cur_engine.handle, "ttsp_unload_engine");
585         if ((error = dlerror()) != NULL) {
586                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] fail to link daemon to ttsp_unload_engine() of current engine\n");
587                 return -3;
588         }
589
590         g_cur_engine.ttsp_load_engine = (int (*)(const ttspd_funcs_s* , ttspe_funcs_s*) )dlsym(g_cur_engine.handle, "ttsp_load_engine");
591         if ((error = dlerror()) != NULL) {
592                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] fail to link daemon to ttsp_load_engine() of current engine \n");
593                 return -3;
594         }
595
596         /* load engine */
597         g_cur_engine.pdfuncs->version = 1;
598         g_cur_engine.pdfuncs->size = sizeof(ttspd_funcs_s);
599
600         int ret = 0;
601         ret = g_cur_engine.ttsp_load_engine(g_cur_engine.pdfuncs, g_cur_engine.pefuncs); 
602         if (0 != ret) {
603                 printf("Fail load '%s' engine\n", g_cur_engine.engine_path);
604                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] fail to load engine : result(%d) \n");
605                 return TTSD_ERROR_OPERATION_FAILED;
606         }
607
608         SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent] engine info : version(%d), size(%d)\n",g_cur_engine.pefuncs->version, g_cur_engine.pefuncs->size );
609
610         /* engine error check */
611         if (g_cur_engine.pefuncs->size != sizeof(ttspe_funcs_s)) {
612                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] ttsd_engine_agent_load_current_engine : current engine is not valid \n");
613                 return TTSD_ERROR_OPERATION_FAILED;
614         }
615
616         /* initalize engine */
617         if (NULL == g_cur_engine.pefuncs->initialize) {
618                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] init function of engine is NULL!!");
619                 return TTSD_ERROR_OPERATION_FAILED;
620         }
621
622         ret = g_cur_engine.pefuncs->initialize(__result_cb);
623         if (0 != ret) {
624                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] fail to initialize current engine : result(%d)\n", ret);
625                 return TTSD_ERROR_OPERATION_FAILED;
626         }
627
628         /* select default voice */
629         bool set_voice = false;
630         if (NULL != g_cur_engine.default_lang) {
631                 if (NULL == g_cur_engine.pefuncs->is_valid_voice) {
632                         SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] is_valid_voice() of engine is NULL!!");
633                         return TTSD_ERROR_OPERATION_FAILED;
634                 }
635
636                 if (true == g_cur_engine.pefuncs->is_valid_voice(g_cur_engine.default_lang, g_cur_engine.default_vctype)) {
637                         set_voice = true;
638                         SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent SUCCESS] Set origin default voice to current engine : lang(%s), type(%d) \n", 
639                                 g_cur_engine.default_lang,  g_cur_engine.default_vctype);
640                 } else {
641                         SLOG(LOG_WARN, TAG_TTSD, "[Engine Agent WARNING] Fail set origin default voice : lang(%s), type(%d)\n",
642                                 g_cur_engine.default_lang, g_cur_engine.default_vctype);
643                 }
644         }
645
646         if (false == set_voice) {
647                 if (NULL == g_cur_engine.pefuncs->foreach_voices) {
648                         SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] get_voice_list of engine is NULL!!");
649                         return TTSD_ERROR_OPERATION_FAILED;
650                 }
651
652                 /* get language list */
653                 int ret;
654                 GList* voice_list = NULL;
655
656                 ret = g_cur_engine.pefuncs->foreach_voices(__supported_voice_cb, &voice_list);
657
658                 if (0 == ret && 0 < g_list_length(voice_list)) {
659                         GList *iter = NULL;
660                         voice_s* voice;
661                         
662                         iter = g_list_first(voice_list);
663
664                         if (NULL != iter) {
665                                 voice = iter->data;
666
667                                 if (true != g_cur_engine.pefuncs->is_valid_voice(voice->language, voice->type)) {
668                                         SLOG(LOG_ERROR, TAG_TTSD, "[Engine ERROR] Fail voice is NOT valid");
669                                         return TTSD_ERROR_OPERATION_FAILED;
670                                 }
671
672                                 ttsd_config_set_default_voice(voice->language, (int)voice->type);
673                                 
674                                 g_cur_engine.default_lang = g_strdup(voice->language);
675                                 g_cur_engine.default_vctype = voice->type;
676
677                                 SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent SUCCESS] Select default voice : lang(%s), type(%d) \n", 
678                                         voice->language,  voice->type);
679
680                                 
681                         } else {
682                                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine ERROR] Fail to get language list : result(%d)\n", ret);
683                                 return TTSD_ERROR_OPERATION_FAILED;
684                         }
685
686                         __free_voice_list(voice_list);
687                 } else {
688                         SLOG(LOG_ERROR, TAG_TTSD, "[Engine ERROR] Fail to get language list : result(%d)\n", ret);
689                         return TTSD_ERROR_OPERATION_FAILED;
690                 }
691         } 
692  
693         g_cur_engine.is_loaded = true;
694
695         return 0;
696 }
697
698 int ttsd_engine_agent_unload_current_engine()
699 {
700         if (false == g_agent_init) {
701                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
702                 return TTSD_ERROR_OPERATION_FAILED;
703         }
704
705         if (false == g_cur_engine.is_set) {
706                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] No Current Engine  \n");
707                 return TTSD_ERROR_OPERATION_FAILED;
708         }
709
710         if (false == g_cur_engine.is_loaded) {
711                 SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent] Engine has already been unloaded  \n" );
712                 return 0;
713         }
714
715         /* shutdown engine */
716         if (NULL == g_cur_engine.pefuncs->deinitialize) {
717                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] The deinitialize() of engine is NULL!!");
718         } else {
719                 int ret = 0;
720                 ret = g_cur_engine.pefuncs->deinitialize();
721                 if (0 != ret) {
722                         SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent] Fail deinitialize() : result(%d)\n", ret);
723                 }
724         }
725
726         /* unload engine */
727         g_cur_engine.ttsp_unload_engine();
728         
729         dlclose(g_cur_engine.handle);
730
731         /* reset current engine data */
732         g_cur_engine.handle = NULL;
733         g_cur_engine.is_loaded = false;
734
735         return 0;
736 }
737
738 bool ttsd_engine_agent_need_network()
739 {
740         if (false == g_agent_init) {
741                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
742                 return TTSD_ERROR_OPERATION_FAILED;
743         }
744
745         if (false == g_cur_engine.is_loaded) {
746                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not loaded engine \n");
747                 return TTSD_ERROR_OPERATION_FAILED;
748         }
749
750         return g_cur_engine.need_network;
751 }
752
753 bool ttsd_engine_select_valid_voice(const char* lang, int type, char** out_lang, ttsp_voice_type_e* out_type)
754 {
755         if (NULL == lang || NULL == out_lang || NULL == out_type) {
756                 return false;
757         }
758
759         SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent] Select voice : input lang(%s) , input type(%d), default lang(%s), default type(%d)", 
760                 lang, type, g_cur_engine.default_lang, g_cur_engine.default_vctype);
761
762         
763         /* case 1 : Both are default */
764         if (0 == strncmp(lang, "default", strlen("default")) && 0 == type) {
765                 *out_lang = strdup(g_cur_engine.default_lang);
766                 *out_type = g_cur_engine.default_vctype;
767                 return true;    
768
769         } 
770         
771         /* Get voice list */
772         if (NULL == g_cur_engine.pefuncs->foreach_voices) {
773                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] foreach_voices of engine is NULL!!");
774                 return TTSD_ERROR_OPERATION_FAILED;
775         }
776
777         GList* voice_list = NULL;
778         int ret = 0;
779
780         ret = g_cur_engine.pefuncs->foreach_voices(__supported_voice_cb, &voice_list);
781         if (0 != ret || 0 >= g_list_length(voice_list)) {
782                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] fail to get voice list : result(%d) \n", ret);
783                 return false;
784         }
785
786         bool result;
787         result = false;
788
789         GList *iter = NULL;
790         voice_s* voice;
791
792         /* lang and type are not default type */
793         if (0 != strncmp(lang, "default", strlen("default")) && 0 != type) {
794                 iter = g_list_first(voice_list);
795
796                 while (NULL != iter) {
797                         /* Get handle data from list */
798                         voice = iter->data;
799
800                         if (0 == strncmp(voice->language, lang, strlen(lang)) &&  voice->type == type) {
801                                 *out_lang = strdup(voice->language);
802                                 *out_type = voice->type;
803                                 result = true;
804                                 break;
805                         }
806
807                         iter = g_list_next(iter);
808                 }
809
810         } else if (0 != strncmp(lang, "default", strlen("default")) && 0 == type) {
811                 /* Only type is default */
812                 if (0 == strncmp(lang, g_cur_engine.default_lang, strlen(g_cur_engine.default_lang))) {
813                         *out_lang = strdup(g_cur_engine.default_lang);
814                         *out_type = g_cur_engine.default_vctype;
815                         result = true;
816                 } else {
817                         voice_s* voice_selected = NULL;
818                         iter = g_list_first(voice_list);
819                         while (NULL != iter) {
820                                 /* Get handle data from list */
821                                 voice = iter->data;
822
823                                 if (0 == strncmp(voice->language, lang, strlen(lang))) {
824                                         voice_selected = voice;
825                                         if (voice->type == g_cur_engine.default_vctype) {
826                                                 voice_selected = voice;
827                                                 break;
828                                         }
829                                 }
830                                 iter = g_list_next(iter);
831                         }
832
833                         if (NULL != voice_selected) {
834                                 *out_lang = strdup(voice_selected->language);
835                                 *out_type = voice_selected->type;
836                                 result = true;
837                         }
838                 }
839         } else if (0 == strncmp(lang, "default", strlen("default")) && 0 != type) {
840                 /* Only lang is default */
841                 if (type == g_cur_engine.default_vctype) {
842                         *out_lang = strdup(g_cur_engine.default_lang);
843                         *out_type = g_cur_engine.default_vctype;
844                         result = true;
845                 } else {
846                         voice_s* voice_selected = NULL;
847                         iter = g_list_first(voice_list);
848                         while (NULL != iter) {
849                                 /* Get handle data from list */
850                                 voice = iter->data;
851
852                                 if (0 == strncmp(voice->language, g_cur_engine.default_lang, strlen(g_cur_engine.default_lang)) ) {
853                                         voice_selected = voice;
854                                         if (voice->type == type) {
855                                                 voice_selected = voice;
856                                                 break;
857                                         }
858                                 }
859                                 iter = g_list_next(iter);
860                         }
861
862                         if (NULL != voice_selected) {
863                                 *out_lang = strdup(voice->language);
864                                 *out_type = voice_selected->type;
865                                 result = true;
866                         }
867                 }
868         }
869
870         if (true == result) {
871                 SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent] Selected voice : lang(%s), type(%d) \n", *out_lang, *out_type);
872         }
873
874         __free_voice_list(voice_list);
875
876         return result;
877 }
878
879 bool ttsd_engine_agent_is_same_engine(const char* engine_id)
880 {
881         if (false == g_agent_init) {
882                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
883                 return false;
884         }
885
886         if (false == g_cur_engine.is_loaded) {
887                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not loaded engine \n");
888                 return false;
889         }
890
891         /* compare current engine and engine id.*/
892         if (0 == strncmp(g_cur_engine.engine_uuid, engine_id, strlen(engine_id))) {
893                 return true;
894         }
895
896         return false;
897 }
898
899 /******************************************************************************************
900 * TTS Engine Interfaces for client
901 *******************************************************************************************/
902
903 int ttsd_engine_start_synthesis(const char* lang, const ttsp_voice_type_e vctype, const char* text, const int speed, void* user_param)
904 {
905         SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent] start ttsd_engine_start_synthesis() \n");
906
907         if (false == g_agent_init) {
908                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
909                 return TTSD_ERROR_OPERATION_FAILED;
910         }
911
912         if (false == g_cur_engine.is_loaded) {
913                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not loaded engine \n");
914                 return TTSD_ERROR_OPERATION_FAILED;
915         }
916
917         /* select voice for default */
918         char* temp_lang = NULL;
919         ttsp_voice_type_e temp_type;
920         if (true != ttsd_engine_select_valid_voice(lang, vctype, &temp_lang, &temp_type)) {
921                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Fail to select default voice \n");
922                 return TTSD_ERROR_INVALID_VOICE;
923         } else {
924                 SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent] Start synthesis : language(%s), type(%d), speed(%d), text(%s) \n", 
925                         temp_lang, temp_type, speed, text);
926         }
927
928         if (NULL == g_cur_engine.pefuncs->start_synth) {
929                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] start_synth() of engine is NULL!!");
930                 return TTSD_ERROR_OPERATION_FAILED;
931         }
932
933         ttsp_speed_e temp_speed;
934
935         if (0 == speed) {
936                 temp_speed = g_cur_engine.default_speed;
937         } else {
938                 temp_speed = speed;
939         }
940
941         /* synthesize text */
942         int ret = 0;
943         ret = g_cur_engine.pefuncs->start_synth(temp_lang, temp_type, text, temp_speed, user_param);
944         if (0 != ret) {
945                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] ***************************************", ret);
946                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] * synthesize error : result(%6d) *", ret);
947                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] ***************************************", ret);
948                 return TTSD_ERROR_OPERATION_FAILED;
949         }
950
951         if (NULL == temp_lang)
952                 free(temp_lang);
953
954         return 0;
955 }
956
957
958 int ttsd_engine_cancel_synthesis()
959 {
960         SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent] start ttsd_engine_cancel_synthesis() \n");
961         
962         if (false == g_agent_init) {
963                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
964                 return TTSD_ERROR_OPERATION_FAILED;
965         }
966
967         if (false == g_cur_engine.is_loaded) {
968                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not loaded engine \n");
969                 return TTSD_ERROR_OPERATION_FAILED;
970         }
971         
972         if (NULL == g_cur_engine.pefuncs->cancel_synth) {
973                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] cancel_synth() of engine is NULL!!");
974                 return TTSD_ERROR_OPERATION_FAILED;
975         }
976
977         /* stop synthesis */
978         int ret = 0;
979         ret = g_cur_engine.pefuncs->cancel_synth();
980         if (0 != ret) {
981                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] fail cancel synthesis : result(%d) \n", ret);
982                 return TTSD_ERROR_OPERATION_FAILED;
983         }
984
985         return 0;
986 }
987
988 int ttsd_engine_get_audio_format( ttsp_audio_type_e* type, int* rate, int* channels)
989 {
990         if (false == g_agent_init) {
991                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
992                 return TTSD_ERROR_OPERATION_FAILED;
993         }
994
995         if (false == g_cur_engine.is_loaded) {
996                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not loaded engine \n");
997                 return TTSD_ERROR_OPERATION_FAILED;
998         }
999
1000         if (NULL == g_cur_engine.pefuncs->get_audio_format) {
1001                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] get_audio_format() of engine is NULL!!");
1002                 return TTSD_ERROR_OPERATION_FAILED;
1003         }
1004
1005         int ret = 0;
1006         ret = g_cur_engine.pefuncs->get_audio_format(type, rate, channels);
1007         if (0 != ret) {
1008                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] fail to get audio format : result(%d) \n", ret);
1009                 return TTSD_ERROR_OPERATION_FAILED;
1010         } else
1011                 SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent] get audio format : type(%d), rate(%d), channel(%d) \n", *type, *rate, *channels);
1012         
1013         return 0;
1014 }
1015
1016 bool __supported_voice_cb(const char* language, ttsp_voice_type_e type, void* user_data)
1017 {
1018         GList** voice_list = (GList**)user_data;
1019
1020         if (NULL == language || NULL == voice_list) {
1021                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Input parameter is NULL in voice list callback!!!!");
1022                 return false;
1023         }
1024
1025         SLOG(LOG_DEBUG, TAG_TTSD, "-- Language(%s), Type(%d)", language, type);
1026
1027         voice_s* voice = g_malloc0(sizeof(voice_s));
1028         voice->language = strdup(language);
1029         voice->type = type;
1030
1031         *voice_list = g_list_append(*voice_list, voice);
1032
1033         return true;
1034 }
1035
1036 int ttsd_engine_get_voice_list(GList** voice_list)
1037 {
1038         if (false == g_agent_init) {
1039                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
1040                 return TTSD_ERROR_OPERATION_FAILED;
1041         }
1042
1043         if (false == g_cur_engine.is_loaded) {
1044                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not loaded engine \n");
1045                 return TTSD_ERROR_OPERATION_FAILED;
1046         }
1047
1048         if (NULL == g_cur_engine.pefuncs->foreach_voices) {
1049                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] The function of engine is NULL!!");
1050                 return TTSD_ERROR_OPERATION_FAILED;
1051         }
1052
1053         int ret = 0;
1054         ret = g_cur_engine.pefuncs->foreach_voices(__supported_voice_cb, (void*)voice_list);
1055         if (0 != ret) {
1056                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Fail to get voice list : result(%d) \n", ret);
1057                 return TTSD_ERROR_OPERATION_FAILED;
1058         }
1059
1060         return 0;
1061 }
1062
1063 int ttsd_engine_get_default_voice( char** lang, ttsp_voice_type_e* vctype )
1064 {
1065         if (false == g_agent_init) {
1066                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
1067                 return TTSD_ERROR_OPERATION_FAILED;
1068         }
1069
1070         if (false == g_cur_engine.is_loaded) {
1071                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not loaded engine \n");
1072                 return TTSD_ERROR_OPERATION_FAILED;
1073         }
1074
1075         if (NULL == lang || NULL == vctype) {
1076                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] BAD Parameter \n"); 
1077                 return TTSD_ERROR_INVALID_PARAMETER;
1078         }
1079
1080         if (NULL != g_cur_engine.default_lang) {
1081                 *lang = g_strdup(g_cur_engine.default_lang);
1082                 *vctype = g_cur_engine.default_vctype;
1083
1084                 SLOG(LOG_DEBUG, TAG_TTSD, "[Engine] Get default voice : language(%s), type(%d)\n", *lang, *vctype);
1085         } else {
1086                 if (NULL == g_cur_engine.pefuncs->foreach_voices) {
1087                         SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] get_voice_list of engine is NULL!!");
1088                         return TTSD_ERROR_OPERATION_FAILED;
1089                 }
1090
1091                 /* get language list */
1092                 int ret;
1093                 GList* voice_list = NULL;
1094
1095                 ret = g_cur_engine.pefuncs->foreach_voices(__supported_voice_cb, &voice_list);
1096
1097                 if (0 == ret && 0 < g_list_length(voice_list)) {
1098                         GList *iter = NULL;
1099                         voice_s* voice;
1100
1101                         iter = g_list_first(voice_list);
1102
1103                         if (NULL != iter) {
1104                                 voice = iter->data;
1105                                 
1106                                 if (true != g_cur_engine.pefuncs->is_valid_voice(voice->language, voice->type)) {
1107                                         SLOG(LOG_ERROR, TAG_TTSD, "[Engine ERROR] Fail voice is NOT valid ");
1108                                         return TTSD_ERROR_OPERATION_FAILED;
1109                                 }
1110                                 
1111                                 ttsd_config_set_default_voice(voice->language, (int)voice->type);
1112                                 
1113                                 if (NULL != g_cur_engine.default_lang)
1114                                         g_free(g_cur_engine.default_lang);
1115
1116                                 g_cur_engine.default_lang = g_strdup(voice->language);
1117                                 g_cur_engine.default_vctype = voice->type;
1118
1119                                 *lang = g_strdup(g_cur_engine.default_lang);
1120                                 *vctype = g_cur_engine.default_vctype = voice->type;
1121
1122                                 SLOG(LOG_DEBUG, TAG_TTSD, "[Engine] Get default voice (New selected) : language(%s), type(%d)\n", *lang, *vctype);
1123                         } else {
1124                                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine ERROR] Fail to get language list : result(%d)\n", ret);
1125                                 return TTSD_ERROR_OPERATION_FAILED;
1126                         }
1127
1128                         __free_voice_list(voice_list);
1129                 } else {
1130                         SLOG(LOG_ERROR, TAG_TTSD, "[Engine ERROR] Fail to get language list : result(%d)\n", ret);
1131                         return TTSD_ERROR_OPERATION_FAILED;
1132                 }
1133         }
1134         
1135         return 0;
1136 }
1137
1138 /*
1139 * TTS Engine Interfaces for setting
1140 */
1141 int ttsd_engine_setting_get_engine_list(GList** engine_list)
1142 {
1143         if (false == g_agent_init) {
1144                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
1145                 return TTSD_ERROR_OPERATION_FAILED;
1146         }
1147
1148         if (NULL == engine_list) {
1149                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Input parameter is NULL" );
1150                 return TTSD_ERROR_INVALID_PARAMETER;
1151         }
1152
1153         /* update engine list */
1154         if (0 != __internal_update_engine_list()) {
1155                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] fail __internal_update_engine_list() \n");
1156                 return TTSD_ERROR_OPERATION_FAILED;
1157         }
1158
1159         GList *iter = NULL;
1160         ttsengine_info_s *data = NULL;
1161
1162         iter = g_list_first(g_engine_list);
1163
1164         SLOG(LOG_DEBUG, TAG_TTSD, "----- [Engine Agent] engine list -----");
1165         
1166         while (NULL != iter) {
1167                 engine_s* temp_engine;
1168         
1169                 temp_engine = (engine_s*)g_malloc0(sizeof(engine_s));
1170
1171                 data = iter->data;
1172
1173                 temp_engine->engine_id = strdup(data->engine_uuid);
1174                 temp_engine->engine_name = strdup(data->engine_name);
1175                 temp_engine->ug_name = strdup(data->setting_ug_path);
1176
1177                 *engine_list = g_list_append(*engine_list, temp_engine);
1178
1179                 iter = g_list_next(iter);
1180
1181                 SLOG(LOG_DEBUG, TAG_TTSD, " -- engine id(%s) engine name(%s) ug name(%s) \n", 
1182                         temp_engine->engine_id, temp_engine->engine_name, temp_engine->ug_name);
1183                 
1184         }
1185
1186         SLOG(LOG_DEBUG, TAG_TTSD, "--------------------------------------");
1187         
1188         return 0;
1189 }
1190
1191 int ttsd_engine_setting_get_engine(char** engine_id)
1192 {
1193         if (false == g_agent_init) {
1194                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
1195                 return TTSD_ERROR_OPERATION_FAILED;
1196         }
1197
1198         if (false == g_cur_engine.is_loaded) {
1199                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not loaded engine \n");
1200                 return TTSD_ERROR_ENGINE_NOT_FOUND;
1201         }
1202
1203         *engine_id = strdup(g_cur_engine.engine_uuid);
1204
1205         return 0;
1206 }
1207
1208 int ttsd_engine_setting_set_engine(const char* engine_id)
1209 {
1210         if (false == g_agent_init) {
1211                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
1212                 return TTSD_ERROR_OPERATION_FAILED;
1213         }
1214
1215         /* compare current engine and new engine.*/
1216         if (0 == strncmp(g_cur_engine.engine_uuid, engine_id, strlen(engine_id))) {
1217                 SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent] new engine(%s) is the same as current engine(%s) \n", engine_id, g_cur_engine.engine_uuid);
1218                 return 0;
1219         }
1220
1221         char* tmp_uuid = NULL;
1222         tmp_uuid = strdup(g_cur_engine.engine_uuid);
1223
1224         /* unload engine */
1225         if (0 != ttsd_engine_agent_unload_current_engine()) {
1226                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent Error] fail to unload current engine \n");
1227         } else {
1228                 SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent SUCCESS] unload current engine \n");
1229         }
1230
1231         /* change current engine */
1232         if (0 != __internal_set_current_engine(engine_id)) {
1233                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] fail __internal_set_current_engine() \n");
1234
1235                 /* roll back to old current engine. */
1236                 __internal_set_current_engine(tmp_uuid);
1237                 ttsd_engine_agent_load_current_engine();
1238                 
1239                 if (tmp_uuid != NULL)   
1240                         free(tmp_uuid);
1241
1242                 return TTSD_ERROR_OPERATION_FAILED;
1243         }
1244
1245         /* load engine */
1246         if (0 != ttsd_engine_agent_load_current_engine()) {
1247                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent Error] fail to load new engine \n");
1248                 
1249                 if( tmp_uuid != NULL )  
1250                         free(tmp_uuid);
1251
1252                 return TTSD_ERROR_OPERATION_FAILED;
1253         } else {
1254                 SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent SUCCESS] load new engine \n");
1255         }
1256
1257         /* save engine id to config */
1258         if (0 != ttsd_config_set_default_engine(engine_id)) {
1259                 SLOG(LOG_WARN, TAG_TTSD, "[Engine Agent WARNING] Fail to save engine id to config \n"); 
1260         }
1261
1262         if (tmp_uuid != NULL)   
1263                 free(tmp_uuid);
1264
1265         return 0;
1266 }
1267
1268 int ttsd_engine_setting_get_voice_list(char** engine_id, GList** voice_list)
1269 {
1270         if (false == g_agent_init) {
1271                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
1272                 return TTSD_ERROR_OPERATION_FAILED;
1273         }
1274
1275         if (false == g_cur_engine.is_loaded) {
1276                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not loaded engine \n");
1277                 return TTSD_ERROR_OPERATION_FAILED;
1278         }
1279
1280         int ret = 0;
1281
1282         /* get language list from engine*/
1283         ret = ttsd_engine_get_voice_list(voice_list);
1284         if (0 != ret) {
1285                 SLOG(LOG_ERROR, TAG_TTSD, "[Server Error] fail ttsd_engine_get_voice_list()  \n");
1286                 return ret;
1287         }
1288
1289         *engine_id = strdup(g_cur_engine.engine_uuid);
1290         
1291         return 0;
1292 }
1293
1294 int ttsd_engine_setting_get_default_voice(char** language, ttsp_voice_type_e* vctype)
1295 {
1296         if (false == g_agent_init) {
1297                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
1298                 return TTSD_ERROR_OPERATION_FAILED;
1299         }
1300
1301         if (false == g_cur_engine.is_loaded) {
1302                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not loaded engine \n");
1303                 return TTSD_ERROR_OPERATION_FAILED;
1304         }
1305
1306         /* get current language from engine*/
1307         int ret = 0;
1308         char* temp_lang;
1309         ttsp_voice_type_e temp_int;
1310
1311         ret = ttsd_engine_get_default_voice(&temp_lang, &temp_int);
1312         if (0 != ret) {
1313                 SLOG(LOG_ERROR, TAG_TTSD, "[Server Error] fail ttsd_engine_get_default_voice() \n");
1314                 return ret;
1315         } 
1316
1317         if (NULL != temp_lang) {
1318                 *language = strdup(temp_lang);
1319                 *vctype = temp_int;
1320                 free(temp_lang);
1321         } else {
1322                 SLOG(LOG_ERROR, TAG_TTSD, "[Server Error] fail to get default language \n");
1323                 return TTSD_ERROR_OPERATION_FAILED;
1324         }
1325
1326         return 0;
1327 }
1328
1329 int ttsd_engine_setting_set_default_voice(const char* language, ttsp_voice_type_e vctype)
1330 {
1331         if (false == g_agent_init) {
1332                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
1333                 return TTSD_ERROR_OPERATION_FAILED;
1334         }
1335
1336         if (false == g_cur_engine.is_loaded) {
1337                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not loaded engine \n");
1338                 return TTSD_ERROR_OPERATION_FAILED;
1339         }
1340
1341         if (NULL == g_cur_engine.pefuncs->is_valid_voice) {
1342                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] The function of engine is NULL!!");
1343                 return TTSD_ERROR_OPERATION_FAILED;
1344         }
1345
1346         int ret = -1;
1347         if(false == g_cur_engine.pefuncs->is_valid_voice(language, vctype)) {
1348                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Voice is NOT valid !!");
1349                 return TTSD_ERROR_INVALID_VOICE;
1350         }
1351
1352         if (NULL != g_cur_engine.default_lang)
1353                 free(g_cur_engine.default_lang);
1354
1355         g_cur_engine.default_lang = strdup(language);
1356         g_cur_engine.default_vctype = vctype;
1357
1358         ret = ttsd_config_set_default_voice(language, (int)vctype);
1359         if (0 == ret) {
1360                 SLOG(LOG_DEBUG, TAG_TTSD, "[Engine Agent SUCCESS] Set default voice : lang(%s), type(%d) \n",
1361                                 g_cur_engine.default_lang, g_cur_engine.default_vctype); 
1362         } else {
1363                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] fail to write default voice to config (%d) \n", ret); 
1364         }
1365
1366         return 0;
1367 }
1368
1369 int ttsd_engine_setting_get_default_speed(ttsp_speed_e* speed)
1370 {
1371         if (false == g_agent_init) {
1372                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
1373                 return TTSD_ERROR_OPERATION_FAILED;
1374         }
1375
1376         if (false == g_cur_engine.is_loaded) {
1377                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not loaded engine \n");
1378                 return TTSD_ERROR_OPERATION_FAILED;
1379         }
1380         
1381         /* get current language */
1382         *speed = g_cur_engine.default_speed;
1383
1384         return 0;
1385 }
1386
1387 int ttsd_engine_setting_set_default_speed(const ttsp_speed_e speed)
1388 {
1389         if (false == g_agent_init) {
1390                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
1391                 return TTSD_ERROR_OPERATION_FAILED;
1392         }
1393
1394         if (false == g_cur_engine.is_loaded) {
1395                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not loaded engine \n");
1396                 return TTSD_ERROR_OPERATION_FAILED;
1397         }
1398
1399         g_cur_engine.default_speed = speed;
1400
1401         if (0 != ttsd_config_set_default_speed(speed)) {
1402                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] fail to set default speed to config");
1403         }
1404
1405         return 0;
1406 }
1407
1408 bool __engine_setting_cb(const char* key, const char* value, void* user_data)
1409 {
1410         GList** engine_setting_list = (GList**)user_data;
1411
1412         if (NULL == engine_setting_list || NULL == key || NULL == value) {
1413                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Input parameter is NULL in engine setting callback!!!!");
1414                 return false;
1415         }
1416
1417         engine_setting_s* temp = g_malloc0(sizeof(engine_setting_s));
1418         temp->key = g_strdup(key);
1419         temp->value = g_strdup(value);
1420
1421         *engine_setting_list = g_list_append(*engine_setting_list, temp);
1422
1423         return true;
1424 }
1425
1426
1427 int ttsd_engine_setting_get_engine_setting_info(char** engine_id, GList** setting_list)
1428 {
1429         if (false == g_agent_init) {
1430                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized" );
1431                 return TTSD_ERROR_OPERATION_FAILED;
1432         }
1433
1434         if (false == g_cur_engine.is_loaded) {
1435                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not loaded engine");
1436                 return TTSD_ERROR_OPERATION_FAILED;
1437         }
1438
1439         if (NULL == setting_list) {
1440                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Input parameter is NULL");
1441                 return TTSD_ERROR_INVALID_PARAMETER;
1442         }
1443
1444         if (NULL == g_cur_engine.pefuncs->foreach_engine_setting) {
1445                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] foreach_engine_setting() of engine is NULL!!");
1446                 return TTSD_ERROR_OPERATION_FAILED;
1447         }
1448
1449         /* get setting info and move setting info to input parameter */
1450         int result = 0;
1451
1452         result = g_cur_engine.pefuncs->foreach_engine_setting(__engine_setting_cb, setting_list);
1453
1454         if (0 == result && 0 < g_list_length(*setting_list)) {
1455                 *engine_id = strdup(g_cur_engine.engine_uuid);
1456         } else {
1457                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] fail to get setting info : result(%d)\n", result);
1458                 result = TTSD_ERROR_OPERATION_FAILED;
1459         }
1460
1461         return result;
1462 }
1463
1464 int ttsd_engine_setting_set_engine_setting(const char* key, const char* value)
1465 {
1466         if (false == g_agent_init) {
1467                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not Initialized \n" );
1468                 return TTSD_ERROR_OPERATION_FAILED;
1469         }
1470
1471         if (false == g_cur_engine.is_loaded) {
1472                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] Not loaded engine \n");
1473                 return TTSD_ERROR_OPERATION_FAILED;
1474         }
1475
1476         if (NULL == g_cur_engine.pefuncs->set_engine_setting) {
1477                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] set_setting_info of engine is NULL!! \n");
1478                 return TTSD_ERROR_OPERATION_FAILED;
1479         }
1480
1481         /* get setting info and move setting info to input parameter */
1482         int ret = 0;
1483         ret = g_cur_engine.pefuncs->set_engine_setting(key, value);
1484
1485         if (0 != ret) {
1486                 SLOG(LOG_ERROR, TAG_TTSD, "[Engine Agent ERROR] fail to set engine setting : result(%d)\n", ret); 
1487                 return TTSD_ERROR_OPERATION_FAILED;
1488         } 
1489
1490         return 0;
1491 }
1492
1493 void __free_voice_list(GList* voice_list)
1494 {
1495         GList *iter = NULL;
1496         voice_s* data = NULL;
1497
1498         /* if list have item */
1499         if (g_list_length(voice_list) > 0) {
1500                 /* Get a first item */
1501                 iter = g_list_first(voice_list);
1502
1503                 while (NULL != iter) {
1504                         data = iter->data;
1505                         
1506                         if (NULL != data->language)
1507                                 g_free(data->language);
1508                         if (NULL != data);
1509                                 g_free(data);
1510
1511                         voice_list = g_list_remove_link(voice_list, iter);
1512                         
1513                         iter = g_list_first(voice_list);
1514                 }
1515         }
1516 }
1517
1518 /*
1519 * TTS Engine Callback Functions                                                                                 `                                 *
1520 */
1521 bool __result_cb(ttsp_result_event_e event, const void* data, unsigned int data_size, void *user_data)
1522 {
1523         g_result_cb(event, data, data_size, user_data);
1524
1525         return true;
1526 }
1527
1528 /* function for debugging */
1529 int ttsd_print_enginelist()
1530 {
1531         GList *iter = NULL;
1532         ttsengine_info_s *data = NULL;
1533
1534         if (g_list_length(g_engine_list) > 0) {
1535                 iter = g_list_first(g_engine_list);
1536
1537                 SLOG(LOG_DEBUG, TAG_TTSD, "----- engine list -----");
1538
1539                 int i = 1;      
1540                 while (NULL != iter) {
1541                         data = iter->data;
1542
1543                         SLOG(LOG_DEBUG, TAG_TTSD, "[%dth]\n", i);
1544                         SLOG(LOG_DEBUG, TAG_TTSD, "engine uuid : %s\n", data->engine_uuid);
1545                         SLOG(LOG_DEBUG, TAG_TTSD, "engine name : %s\n", data->engine_name);
1546                         SLOG(LOG_DEBUG, TAG_TTSD, "engine path : %s\n", data->engine_path);
1547                         SLOG(LOG_DEBUG, TAG_TTSD, "setting ug path : %s\n", data->setting_ug_path);
1548
1549                         iter = g_list_next(iter);
1550                         i++;
1551                 }
1552                 SLOG(LOG_DEBUG, TAG_TTSD, "-----------------------");
1553                 SLOG(LOG_DEBUG, TAG_TTSD, "  ");
1554         } else {
1555                 SLOG(LOG_DEBUG, TAG_TTSD, "----- engine list -----");
1556                 SLOG(LOG_DEBUG, TAG_TTSD, "No Engine in directory");
1557                 SLOG(LOG_DEBUG, TAG_TTSD, "-----------------------");
1558         }
1559
1560         return 0;
1561 }
1562
1563
1564
1565
1566
1567
1568