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