Clean up unnecessary header files
[platform/core/uifw/tts.git] / common / tts_config_parser.c
1 /*
2 *  Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved
3 *  Licensed under the Apache License, Version 2.0 (the "License");
4 *  you may not use this file except in compliance with the License.
5 *  You may obtain a copy of the License at
6 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14 #include <dlog.h>
15 #include <stdio.h>
16 #include <sys/stat.h>
17 #include <unistd.h>
18 #include <vconf.h>
19
20 #include "tts_config_parser.h"
21 #include "tts_defs.h"
22
23
24 #define TTS_TAG_ENGINE_BASE_TAG         "tts-engine"
25 #define TTS_TAG_ENGINE_NAME             "name"
26 #define TTS_TAG_ENGINE_ID               "id"
27 #define TTS_TAG_ENGINE_SETTING          "setting"
28 #define TTS_TAG_ENGINE_VOICE_SET        "voices"
29 #define TTS_TAG_ENGINE_VOICE            "voice"
30 #define TTS_TAG_ENGINE_VOICE_TYPE       "type"
31 #define TTS_TAG_ENGINE_PITCH_SUPPORT    "pitch-support"
32 #define TTS_TAG_ENGINE_TEXT_SIZE        "text-size"
33
34 #define TTS_TAG_CONFIG_BASE_TAG         "tts-config"
35 #define TTS_TAG_CONFIG_ENGINE_ID        "engine"
36 #define TTS_TAG_CONFIG_ENGINE_SETTING   "engine-setting"
37 #define TTS_TAG_CONFIG_AUTO_VOICE       "auto"
38 #define TTS_TAG_CONFIG_VOICE_TYPE       "voice-type"
39 #define TTS_TAG_CONFIG_LANGUAGE         "language"
40 #define TTS_TAG_CONFIG_SPEECH_RATE      "speech-rate"
41 #define TTS_TAG_CONFIG_PITCH            "pitch"
42 #define TTS_TAG_CONFIG_BACKGROUND_VOLUME_RATIO          "background-volume-ratio"
43 #define TTS_TAG_VOICE_TYPE_FEMALE       "female"
44 #define TTS_TAG_VOICE_TYPE_MALE         "male"
45 #define TTS_TAG_VOICE_TYPE_CHILD        "child"
46
47 #define TTS_MAX_TEXT_SIZE       2000
48
49 static xmlDocPtr g_config_doc = NULL;
50 char g_engine_id[128] = {0,};
51 char g_setting[128] = {0,};
52 char g_language[128] = {0,};
53
54 static tts_config_s* g_config_info = NULL;
55
56 static pthread_mutex_t g_config_info_mutex = PTHREAD_MUTEX_INITIALIZER;
57
58 int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info)
59 {
60         if (NULL == path || NULL == engine_info) {
61                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
62                 return -1;
63         }
64
65         // Avoid to parse non-xml file
66         char* file_ext = strrchr(path, '.');
67         if (NULL == ++file_ext || (file_ext && 0 != strncmp("xml", file_ext, strlen(file_ext)))) {
68                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] File extention is not XML type, file_ext(%s)", (file_ext) ? file_ext : "NULL");
69                 return -1;
70         }
71
72         bool isTextsize = false;
73         xmlDocPtr doc = NULL;
74         xmlNodePtr cur = NULL;
75         xmlChar *key = NULL;
76         xmlChar *attr = NULL;
77
78         if (0 == access(path, F_OK)) {
79                 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Success to access to %s", path);
80                 doc = xmlParseFile(path);
81                 if (doc == NULL) {
82                         SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse xml file");
83                         return -1;
84                 }
85         } else {
86                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to access to %s", path);
87                 return -1;
88         }
89
90         cur = xmlDocGetRootElement(doc);
91         if (cur == NULL) {
92                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document. doc path(%s, %p)", path, doc);
93                 xmlFreeDoc(doc);
94                 doc = NULL;
95                 return -1;
96         }
97
98         if (xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_BASE_TAG)) {
99                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] The wrong type, root node is NOT 'tts-engine'. doc path(%s, %p)", path, doc);
100                 xmlFreeDoc(doc);
101                 doc = NULL;
102                 return -1;
103         }
104
105         cur = cur->xmlChildrenNode;
106         if (cur == NULL) {
107                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document. doc path(%s, %p)", path, doc);
108                 xmlFreeDoc(doc);
109                 doc = NULL;
110                 return -1;
111         }
112
113         /* alloc engine info */
114         tts_engine_info_s* temp;
115         temp = (tts_engine_info_s*)calloc(1, sizeof(tts_engine_info_s));
116         if (NULL == temp) {
117                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Out of memory. doc path(%s, %p)", path, doc);
118                 xmlFreeDoc(doc);
119                 doc = NULL;
120                 return -1;
121         }
122
123         temp->name = NULL;
124         temp->uuid = NULL;
125         temp->voices = NULL;
126         temp->setting = NULL;
127         temp->pitch_support = false;
128         temp->text_size = 0;
129
130         while (cur != NULL) {
131                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_NAME)) {
132                         key = xmlNodeGetContent(cur);
133                         if (NULL != key) {
134                                 if (NULL != temp->name) {
135                                         free(temp->name);
136                                         temp->name = NULL;
137                                 }
138                                 temp->name = strdup((char*)key);
139                                 xmlFree(key);
140                                 key = NULL;
141                         } else {
142                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] <%s> has no content", TTS_TAG_ENGINE_NAME);
143                         }
144                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_ID)) {
145                         key = xmlNodeGetContent(cur);
146                         if (NULL != key) {
147                                 if (NULL != temp->uuid) {
148                                         free(temp->uuid);
149                                         temp->uuid = NULL;
150                                 }
151                                 temp->uuid = strdup((char*)key);
152                                 xmlFree(key);
153                                 key = NULL;
154                         } else {
155                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] <%s> has no content", TTS_TAG_ENGINE_ID);
156                         }
157                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_SETTING)) {
158                         key = xmlNodeGetContent(cur);
159                         if (NULL != key) {
160                                 if (NULL != temp->setting) {
161                                         free(temp->setting);
162                                         temp->setting = NULL;
163                                 }
164                                 temp->setting = strdup((char*)key);
165                                 xmlFree(key);
166                                 key = NULL;
167                         } else {
168                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] <%s> has no content", TTS_TAG_ENGINE_SETTING);
169                         }
170                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_VOICE_SET)) {
171                         xmlNodePtr voice_node = NULL;
172                         voice_node = cur->xmlChildrenNode;
173
174                         while (NULL != voice_node) {
175                                 if (0 == xmlStrcmp(voice_node->name, (const xmlChar *)TTS_TAG_ENGINE_VOICE)) {
176                                         tts_config_voice_s* temp_voice = (tts_config_voice_s*)calloc(1, sizeof(tts_config_voice_s));
177                                         if (NULL == temp_voice) {
178                                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Out of memory");
179                                                 break;
180                                         }
181
182                                         attr = xmlGetProp(voice_node, (const xmlChar*)TTS_TAG_ENGINE_VOICE_TYPE);
183                                         if (NULL != attr) {
184                                                 if (0 == xmlStrcmp(attr, (const xmlChar *)TTS_TAG_VOICE_TYPE_FEMALE)) {
185                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_FEMALE;
186                                                 } else if (0 == xmlStrcmp(attr, (const xmlChar *)TTS_TAG_VOICE_TYPE_MALE)) {
187                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_MALE;
188                                                 } else if (0 == xmlStrcmp(attr, (const xmlChar *)TTS_TAG_VOICE_TYPE_CHILD)) {
189                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_CHILD;
190                                                 } else {
191                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_USER_DEFINED;
192                                                 }
193                                                 xmlFree(attr);
194                                                 attr = NULL;
195                                         } else {
196                                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] <%s> has no content", TTS_TAG_ENGINE_VOICE_TYPE);
197                                                 free(temp_voice);
198                                                 temp_voice = NULL;
199                                                 continue;
200                                         }
201
202                                         key = xmlNodeGetContent(voice_node);
203                                         if (NULL != key) {
204                                                 if (NULL != temp_voice->language) {
205                                                         free(temp_voice->language);
206                                                         temp_voice->language = NULL;
207                                                 }
208                                                 temp_voice->language = strdup((char*)key);
209                                                 xmlFree(key);
210                                                 key = NULL;
211                                                 temp->voices = g_slist_append(temp->voices, temp_voice);
212                                         } else {
213                                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] <%s> has no content", TTS_TAG_ENGINE_VOICE);
214                                                 if (NULL != temp_voice) {
215                                                         free(temp_voice);
216                                                         temp_voice = NULL;
217                                                 }
218                                         }
219                                 }
220                                 voice_node = voice_node->next;
221                         }
222                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_PITCH_SUPPORT)) {
223                         key = xmlNodeGetContent(cur);
224                         if (NULL != key) {
225                                 if (0 == xmlStrcmp(key, (const xmlChar *)"true")) {
226                                         temp->pitch_support = true;
227                                 }
228                                 xmlFree(key);
229                                 key = NULL;
230                         } else {
231                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] <%s> has no content", TTS_TAG_ENGINE_PITCH_SUPPORT);
232                         }
233                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_TEXT_SIZE)) {
234                         isTextsize = true;
235                         key = xmlNodeGetContent(cur);
236                         if (NULL != key) {
237                                 temp->text_size = atoi((char*)key);
238                                 xmlFree(key);
239                         } else {
240                                 SLOG(LOG_INFO, TAG_TTSCONFIG, "[INFO] text size is unlimited.");
241                                 temp->text_size = 0;
242                         }
243                 }
244                 cur = cur->next;
245         }
246
247         if (false == isTextsize) {
248                 temp->text_size = TTS_MAX_TEXT_SIZE;
249         }
250
251         if (NULL != doc) {
252                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] doc path(%s, %p)", path, doc);
253                 xmlFreeDoc(doc);
254                 doc = NULL;
255         }
256
257         if (NULL == temp->uuid) {
258                 /* Invalid engine */
259                 SECURE_SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Invalid engine : %s", path);
260                 tts_parser_free_engine_info(temp);
261                 return -1;
262         }
263
264         *engine_info = temp;
265
266         return 0;
267 }
268
269 int tts_parser_free_engine_info(tts_engine_info_s* engine_info)
270 {
271         if (NULL == engine_info) {
272                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
273                 return -1;
274         }
275
276         if (NULL != engine_info->name) {
277                 free(engine_info->name);
278                 engine_info->name = NULL;
279         }
280         if (NULL != engine_info->uuid) {
281                 free(engine_info->uuid);
282                 engine_info->uuid = NULL;
283         }
284         if (NULL != engine_info->setting) {
285                 free(engine_info->setting);
286                 engine_info->setting = NULL;
287         }
288
289         tts_config_voice_s *temp_voice;
290         temp_voice = g_slist_nth_data(engine_info->voices, 0);
291
292         while (NULL != temp_voice) {
293                 if (NULL != temp_voice) {
294                         if (NULL != temp_voice->language) {
295                                 free(temp_voice->language);
296                                 temp_voice->language = NULL;
297                         }
298                         engine_info->voices = g_slist_remove(engine_info->voices, temp_voice);
299                         free(temp_voice);
300                         temp_voice = NULL;
301                 }
302
303                 temp_voice = g_slist_nth_data(engine_info->voices, 0);
304         }
305
306         if (NULL != engine_info) {
307                 free(engine_info);
308                 engine_info = NULL;
309         }
310
311         return 0;
312 }
313
314 int tts_parser_print_engine_info(tts_engine_info_s* engine_info)
315 {
316         if (NULL == engine_info) {
317                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
318                 return -1;
319         }
320
321         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "== get engine info ==");
322         SLOG(LOG_DEBUG, TAG_TTSCONFIG, " name : %s", engine_info->name);
323         SLOG(LOG_DEBUG, TAG_TTSCONFIG, " id   : %s", engine_info->uuid);
324         if (NULL != engine_info->setting)
325                 SLOG(LOG_DEBUG, TAG_TTSCONFIG, " setting : %s", engine_info->setting);
326
327         SLOG(LOG_DEBUG, TAG_TTSCONFIG, " voices");
328         GSList *iter = NULL;
329         tts_config_voice_s *temp_voice;
330
331         if (g_slist_length(engine_info->voices) > 0) {
332                 /* Get a first item */
333                 iter = g_slist_nth(engine_info->voices, 0);
334
335                 int i = 1;
336                 while (NULL != iter) {
337                         /*Get handle data from list*/
338                         temp_voice = iter->data;
339
340                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "  [%dth] type(%d) lang(%s)",
341                                 i, temp_voice->type, temp_voice->language);
342
343                         /*Get next item*/
344                         iter = g_slist_next(iter);
345                         i++;
346                 }
347         } else {
348                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "  Voice is NONE");
349         }
350
351         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "@@@");
352
353         return 0;
354 }
355
356 int tts_parser_load_config(void)
357 {
358         xmlDocPtr doc = NULL;
359         xmlNodePtr cur = NULL;
360         xmlChar *key;
361         bool is_default_open = false;
362
363         /* For Thread safety */
364         xmlInitParser();
365
366         if (0 != access(TTS_CONFIG, F_OK)) {
367                 doc = xmlParseFile(TTS_DEFAULT_CONFIG);
368                 if (doc == NULL) {
369                         SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse file error : %s", TTS_DEFAULT_CONFIG);
370                         xmlCleanupParser();
371                         return -1;
372                 }
373                 is_default_open = true;
374         } else {
375                 int retry_count = 0;
376
377                 while (NULL == doc) {
378                         doc = xmlParseFile(TTS_CONFIG);
379                         if (NULL != doc) {
380                                 break;
381                         }
382                         retry_count++;
383                         usleep(10000);
384
385                         if (TTS_RETRY_COUNT == retry_count) {
386                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse file error : %s", TTS_CONFIG);
387                                 doc = xmlParseFile(TTS_DEFAULT_CONFIG);
388                                 if (NULL == doc) {
389                                         SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse file error : %s", TTS_DEFAULT_CONFIG);
390                                         xmlCleanupParser();
391                                         return -1;
392                                 }
393                                 is_default_open = true;
394                                 break;
395                         }
396                 }
397         }
398
399         cur = xmlDocGetRootElement(doc);
400         if (cur == NULL) {
401                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document(%p)", doc);
402                 xmlFreeDoc(doc);
403                 doc = NULL;
404                 xmlCleanupParser();
405                 return -1;
406         }
407
408         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
409                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] The wrong type, root node is NOT %s. doc(%p)", TTS_TAG_CONFIG_BASE_TAG, doc);
410                 xmlFreeDoc(doc);
411                 doc = NULL;
412                 xmlCleanupParser();
413                 return -1;
414         }
415
416         cur = cur->xmlChildrenNode;
417         if (cur == NULL) {
418                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document(%p)", doc);
419                 xmlFreeDoc(doc);
420                 doc = NULL;
421                 xmlCleanupParser();
422                 return -1;
423         }
424
425         /* alloc engine info */
426         tts_config_s* temp;
427         temp = (tts_config_s*)calloc(1, sizeof(tts_config_s));
428         if (NULL == temp) {
429                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Out of memory(%p)", doc);
430                 xmlFreeDoc(doc);
431                 doc = NULL;
432                 xmlCleanupParser();
433                 return -1;
434         }
435
436         memset(g_engine_id, '\0', sizeof(g_engine_id));
437         memset(g_setting, '\0', sizeof(g_setting));
438         memset(g_language, '\0', sizeof(g_language));
439
440         temp->engine_id = g_engine_id;
441         temp->setting = g_setting;
442         temp->language = g_language;
443
444         while (cur != NULL) {
445                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_ID)) {
446                         if (is_default_open) {
447                                 char* engine_id = vconf_get_str(TTS_ENGINE_DB_DEFAULT);
448                                 if (engine_id) {
449                                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Set default engine id(%s)", engine_id);
450                                         strncpy(temp->engine_id, engine_id, sizeof(engine_id) - 1);
451                                         xmlNodeSetContent(cur, (const xmlChar *)engine_id);
452
453                                         free(engine_id);
454                                         engine_id = NULL;
455
456                                         cur = cur->next;
457                                         continue;
458                                 }
459                         }
460
461                         key = xmlNodeGetContent(cur);
462                         if (NULL != key) {
463                                 strncpy(temp->engine_id, (char*)key, sizeof(g_engine_id) - 1);
464                                 xmlFree(key);
465                                 key = NULL;
466                         } else {
467                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] engine id is NULL");
468                         }
469                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_SETTING)) {
470                         key = xmlNodeGetContent(cur);
471                         if (NULL != key) {
472                                 strncpy(temp->setting, (char*)key, sizeof(g_setting) - 1);
473                                 xmlFree(key);
474                                 key = NULL;
475                         } else {
476                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] setting path is NULL");
477                         }
478                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_AUTO_VOICE)) {
479                         key = xmlNodeGetContent(cur);
480                         if (NULL != key) {
481                                 if (0 == xmlStrcmp(key, (const xmlChar *)"on")) {
482                                         temp->auto_voice = true;
483                                 } else if (0 == xmlStrcmp(key, (const xmlChar *)"off")) {
484                                         temp->auto_voice = false;
485                                 } else {
486                                         SLOG(LOG_ERROR, TAG_TTSCONFIG, "Auto voice is wrong");
487                                         temp->auto_voice = true;
488                                 }
489
490                                 xmlFree(key);
491                                 key = NULL;
492                         } else {
493                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] voice type is NULL");
494                         }
495                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_VOICE_TYPE)) {
496                         key = xmlNodeGetContent(cur);
497                         if (NULL != key) {
498                                 if (0 == xmlStrcmp(key, (const xmlChar *)TTS_TAG_VOICE_TYPE_MALE)) {
499                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_MALE;
500                                 } else if (0 == xmlStrcmp(key, (const xmlChar *)TTS_TAG_VOICE_TYPE_FEMALE)) {
501                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_FEMALE;
502                                 } else if (0 == xmlStrcmp(key, (const xmlChar *)TTS_TAG_VOICE_TYPE_CHILD)) {
503                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_CHILD;
504                                 } else {
505                                         SLOG(LOG_WARN, TAG_TTSCONFIG, "Voice type is user defined");
506                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_USER_DEFINED;
507                                 }
508
509                                 xmlFree(key);
510                                 key = NULL;
511                         } else {
512                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] voice type is NULL");
513                         }
514                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_LANGUAGE)) {
515                         key = xmlNodeGetContent(cur);
516                         if (NULL != key) {
517                                 strncpy(temp->language, (char*)key, sizeof(g_language) - 1);
518                                 xmlFree(key);
519                                 key = NULL;
520                         } else {
521                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] engine uuid is NULL");
522                         }
523
524                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_SPEECH_RATE)) {
525                         key = xmlNodeGetContent(cur);
526                         if (NULL != key) {
527                                 temp->speech_rate = atoi((char*)key);
528                                 xmlFree(key);
529                         } else {
530                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] speech rate is NULL");
531                         }
532                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_PITCH)) {
533                         key = xmlNodeGetContent(cur);
534                         if (NULL != key) {
535                                 temp->pitch = atoi((char*)key);
536                                 xmlFree(key);
537                                 key = NULL;
538                         } else {
539                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Pitch is NULL");
540                         }
541                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_BACKGROUND_VOLUME_RATIO)) {
542                         key = xmlNodeGetContent(cur);
543                         if (NULL != key) {
544                                 temp->bg_volume_ratio = atof((char*)key);
545                                 xmlFree(key);
546                                 key = NULL;
547                         } else {
548                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Background volume ratio is NULL");
549                         }
550                 } else {
551
552                 }
553
554                 cur = cur->next;
555         }
556
557         g_config_info = temp;
558         g_config_doc = doc;
559
560         if (true == is_default_open) {
561                 int retry_count = 0;
562                 int ret = -1;
563                 do {
564                         ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
565                         if (0 < ret)
566                                 break;
567                         retry_count++;
568                         usleep(10000);
569
570                         if (TTS_RETRY_COUNT == retry_count) {
571                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Save result : %d", ret);
572                                 return -1;
573                         }
574                 } while (0 != ret);
575
576                 /* Set mode */
577                 if (0 > chmod(TTS_CONFIG, 0600)) {
578                         SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to change file mode : %d", ret);
579                 }
580
581                 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Default config is changed : pid(%d)", getpid());
582         }
583
584         return 0;
585 }
586
587 int tts_parser_unload_config(void)
588 {
589         if (NULL != g_config_doc) {
590                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] Free g_config_doc(%p)", g_config_doc);
591                 xmlFreeDoc(g_config_doc);
592                 g_config_doc = NULL;
593         }
594         pthread_mutex_lock(&g_config_info_mutex);
595         if (NULL != g_config_info) {
596                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] Free config_info(%p)", g_config_info);
597                 free(g_config_info);
598                 g_config_info = NULL;
599         }
600         pthread_mutex_unlock(&g_config_info_mutex);
601
602         xmlCleanupParser();
603         return 0;
604 }
605
606 int tts_parser_set_config_info(tts_config_s* config_info)
607 {
608         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Set config info");
609         if (NULL == config_info) {
610                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] config_info is NULL");
611                 return -1;
612         }
613         pthread_mutex_lock(&g_config_info_mutex);
614         if (NULL == g_config_info) {
615                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] g_config_info is NULL");
616                 pthread_mutex_unlock(&g_config_info_mutex);
617                 return -1;
618         }
619         memcpy(g_config_info, config_info, sizeof(tts_config_s));
620         pthread_mutex_unlock(&g_config_info_mutex);
621         return 0;
622 }
623
624 int tts_parser_get_config_info(tts_config_s* config_info)
625 {
626         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Get config info");
627         if (NULL == config_info) {
628                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] config_info is NULL");
629                 return -1;
630         }
631         pthread_mutex_lock(&g_config_info_mutex);
632         if (NULL == g_config_info) {
633                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] g_config_info is NULL");
634                 pthread_mutex_unlock(&g_config_info_mutex);
635                 return -1;
636         }
637         memcpy(config_info, g_config_info, sizeof(tts_config_s));
638         pthread_mutex_unlock(&g_config_info_mutex);
639         return 0;
640 }
641
642 int tts_parser_copy_xml(const char* original, const char* destination)
643 {
644         if (NULL == original || NULL == destination) {
645                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
646                 return -1;
647         }
648
649         xmlDocPtr doc = NULL;
650         if (0 == access(original, F_OK)) {
651                 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Success to access to %s", original);
652                 doc = xmlParseFile(original);
653                 if (doc == NULL) {
654                         SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse file error : %s", original);
655                         return -1;
656                 }
657         } else {
658                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to access to %s", original);
659                 return -1;
660         }
661
662         int ret = xmlSaveFile(destination, doc);
663         if (0 > ret) {
664                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Save result : %d", ret);
665         } else {
666                 static FILE* pFile;
667                 pFile = fopen(destination, "r");
668                 int fd = -1;
669                 if (NULL == pFile) {
670                         SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to open file %s", destination);
671                 } else {
672                         fd = fileno(pFile);
673                         fsync(fd);
674                         fclose(pFile);
675                         SLOG(LOG_INFO, TAG_TTSCONFIG, "[DEBUG] Success to fsync %s", destination);
676                 }
677                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] Success to save %s", destination);
678         }
679
680         /* Set mode */
681         if (0 > chmod(destination, 0600)) {
682                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to change file mode : %d", ret);
683         }
684
685         if (NULL != doc) {
686                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] doc(%p)", doc);
687                 xmlFreeDoc(doc);
688                 doc = NULL;
689         }
690
691         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[SUCCESS] Copying xml");
692
693         return 0;
694 }
695
696 static int __set_value_into_configuration(const char* key, const char* value)
697 {
698         if(NULL == key || NULL == value) {
699                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Parameter is NULL");
700         }
701
702         xmlNodePtr cur = NULL;
703         cur = xmlDocGetRootElement(g_config_doc);
704         if (cur == NULL) {
705                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document");
706                 return -1;
707         }
708
709         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
710                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
711                 return -1;
712         }
713
714         cur = cur->xmlChildrenNode;
715         if (cur == NULL) {
716                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document");
717                 return -1;
718         }
719
720         while (cur != NULL) {
721                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)key)) {
722                         xmlNodeSetContent(cur, (const xmlChar *)value);
723
724                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Set key(%s) : value(%s)", key, value);
725                         break;
726                 }
727
728                 cur = cur->next;
729         }
730
731         return 0;
732 }
733
734 static void __save_configuration(xmlDocPtr config_doc)
735 {
736         int ret = xmlSaveFile(TTS_CONFIG, config_doc);
737         if (0 > ret) {
738                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Save result : file(%s), ret(%d)", TTS_CONFIG, ret);
739         } else {
740                 static FILE* pFile;
741                 pFile = fopen(TTS_CONFIG, "r");
742                 int fd = -1;
743                 if (NULL == pFile) {
744                         SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to open file %s", TTS_CONFIG);
745                 } else {
746                         fd = fileno(pFile);
747                         fsync(fd);
748                         fclose(pFile);
749                         SLOG(LOG_INFO, TAG_TTSCONFIG, "[DEBUG] Success to fsync %s", TTS_CONFIG);
750                 }
751                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] Success to save %s", TTS_CONFIG);
752         }
753 }
754
755 static char* __convert_voice_type_into_char(tts_config_voice_type_e voice_type)
756 {
757         switch (voice_type) {
758         case TTS_CONFIG_VOICE_TYPE_MALE:
759                 return TTS_TAG_VOICE_TYPE_MALE;
760         case TTS_CONFIG_VOICE_TYPE_FEMALE:
761                 return TTS_TAG_VOICE_TYPE_FEMALE;
762         case TTS_CONFIG_VOICE_TYPE_CHILD:
763                 return TTS_TAG_VOICE_TYPE_CHILD;
764         default:
765                 return TTS_TAG_VOICE_TYPE_FEMALE;
766         }
767 }
768
769 int tts_parser_set_engine(const char* engine_id, const char* setting, const char* language, int type)
770 {
771         if (NULL == engine_id) {
772                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
773                 return -1;
774         }
775
776         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_ENGINE_ID, engine_id)) {
777                 return -1;
778         }
779
780         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_LANGUAGE, language)) {
781                 return -1;
782         }
783
784         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_ENGINE_SETTING, setting)) {
785                 return -1;
786         }
787
788         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_VOICE_TYPE, __convert_voice_type_into_char(type))) {
789                 return -1;
790         }
791
792         __save_configuration(g_config_doc);
793
794         return 0;
795 }
796
797 int tts_parser_set_voice(const char* language, int type)
798 {
799         if (NULL == language) {
800                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
801                 return -1;
802         }
803
804         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_LANGUAGE, language)) {
805                 return -1;
806         }
807
808         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_VOICE_TYPE, __convert_voice_type_into_char(type))) {
809                 return -1;
810         }
811
812         __save_configuration(g_config_doc);
813
814         return 0;
815 }
816
817 int tts_parser_set_auto_voice(bool value)
818 {
819         char* temp = value ? "on" : "off";
820         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_AUTO_VOICE, temp)) {
821                 return -1;
822         }
823
824         __save_configuration(g_config_doc);
825
826         return 0;
827 }
828
829 int tts_parser_set_speech_rate(int value)
830 {
831         char temp[10];
832         memset(temp, '\0', 10);
833         snprintf(temp, 10, "%d", value);
834
835         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_SPEECH_RATE, temp)) {
836                 return -1;
837         }
838
839         __save_configuration(g_config_doc);
840
841         return 0;
842 }
843
844 int tts_parser_set_pitch(int value)
845 {
846         char temp[10];
847         memset(temp, '\0', 10);
848         snprintf(temp, 10, "%d", value);
849
850         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_PITCH, temp)) {
851                 return -1;
852         }
853
854         __save_configuration(g_config_doc);
855
856         return 0;
857 }
858
859 int tts_parser_set_bg_volume_ratio(double value)
860 {
861         char temp[10];
862         memset(temp, '\0', 10);
863         snprintf(temp, 10, "%lf", value);
864
865         if (0 != __set_value_into_configuration(TTS_TAG_CONFIG_BACKGROUND_VOLUME_RATIO, temp)) {
866                 return -1;
867         }
868
869         __save_configuration(g_config_doc);
870
871         return 0;
872 }
873
874 int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voice, char** language, int* voice_type,
875                                    int* speech_rate, int* pitch, double* bg_volume_ratio)
876 {
877         if (NULL == engine || NULL == setting || NULL == language || NULL == voice_type || NULL == speech_rate) {
878                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Input parameter is NULL");
879                 return -1;
880         }
881
882         xmlDocPtr doc = NULL;
883         xmlNodePtr cur_new = NULL;
884         xmlNodePtr cur_old = NULL;
885
886         xmlChar *key_new;
887         xmlChar *key_old;
888
889         int retry_count = 0;
890         while (NULL == doc) {
891                 if (0 == access(TTS_CONFIG, F_OK)) {
892                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Success to access to %s", TTS_CONFIG);
893                         doc = xmlParseFile(TTS_CONFIG);
894                         if (NULL != doc) {
895                                 break;
896                         }
897                 }
898                 retry_count++;
899                 usleep(10000);
900
901                 if (TTS_RETRY_COUNT == retry_count) {
902                         SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse file error : %s", TTS_CONFIG);
903                         return -1;
904                 }
905         }
906
907         cur_new = xmlDocGetRootElement(doc);
908         cur_old = xmlDocGetRootElement(g_config_doc);
909         if (cur_new == NULL || cur_old == NULL) {
910                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document(%p)", doc);
911                 xmlFreeDoc(doc);
912                 doc = NULL;
913                 return -1;
914         }
915
916         if (xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_BASE_TAG) ||
917         xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_BASE_TAG)) {
918                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] The wrong type, root node is NOT %s. doc(%p)", TTS_TAG_CONFIG_BASE_TAG, doc);
919                 xmlFreeDoc(doc);
920                 doc = NULL;
921                 return -1;
922         }
923
924         cur_new = cur_new->xmlChildrenNode;
925         cur_old = cur_old->xmlChildrenNode;
926         if (cur_new == NULL || cur_old == NULL) {
927                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Empty document(%p)", doc);
928                 xmlFreeDoc(doc);
929                 doc = NULL;
930                 return -1;
931         }
932
933         while (cur_new != NULL && cur_old != NULL) {
934                 if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_ID)) {
935                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_ID)) {
936                                 key_old = xmlNodeGetContent(cur_old);
937                                 if (NULL != key_old) {
938                                         key_new = xmlNodeGetContent(cur_new);
939                                         if (NULL != key_new) {
940                                                 if (0 != xmlStrcmp(key_old, key_new)) {
941                                                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old engine id(%s), New engine(%s)",
942                                                                 (char*)key_old, (char*)key_new);
943                                                         if (NULL != *engine) {
944                                                                 free(*engine);
945                                                                 *engine = NULL;
946                                                         }
947                                                         *engine = strdup((char*)key_new);
948                                                 }
949                                                 xmlFree(key_new);
950                                                 key_new = NULL;
951                                         }
952                                         xmlFree(key_old);
953                                         key_old = NULL;
954                                 }
955                         } else {
956                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
957                         }
958                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_SETTING)) {
959                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_SETTING)) {
960                                 key_old = xmlNodeGetContent(cur_old);
961                                 if (NULL != key_old) {
962                                         key_new = xmlNodeGetContent(cur_new);
963                                         if (NULL != key_new) {
964                                                 if (0 != xmlStrcmp(key_old, key_new)) {
965                                                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old engine setting(%s), New engine setting(%s)",
966                                                                 (char*)key_old, (char*)key_new);
967                                                         if (NULL != *setting) {
968                                                                 free(*setting);
969                                                                 *setting = NULL;
970                                                         }
971                                                         *setting = strdup((char*)key_new);
972                                                 }
973                                                 xmlFree(key_new);
974                                                 key_new = NULL;
975                                         }
976                                         xmlFree(key_old);
977                                         key_old = NULL;
978                                 }
979                         } else {
980                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
981                         }
982                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_AUTO_VOICE)) {
983                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_AUTO_VOICE)) {
984                                 key_old = xmlNodeGetContent(cur_old);
985                                 if (NULL != key_old) {
986                                         key_new = xmlNodeGetContent(cur_new);
987                                         if (NULL != key_new) {
988                                                 if (0 != xmlStrcmp(key_old, key_new)) {
989                                                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old auto voice (%s), New auto voice(%s)",
990                                                                 (char*)key_old, (char*)key_new);
991                                                         if (0 == xmlStrcmp((const xmlChar*)"on", key_new)) {
992                                                                 *auto_voice = true;
993                                                         } else {
994                                                                 *auto_voice = false;
995                                                         }
996                                                 }
997                                                 xmlFree(key_new);
998                                                 key_new = NULL;
999                                         }
1000                                         xmlFree(key_old);
1001                                         key_old = NULL;
1002                                 }
1003                         } else {
1004                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
1005                         }
1006                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_LANGUAGE)) {
1007                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_LANGUAGE)) {
1008                                 key_old = xmlNodeGetContent(cur_old);
1009                                 if (NULL != key_old) {
1010                                         key_new = xmlNodeGetContent(cur_new);
1011                                         if (NULL != key_new) {
1012                                                 if (0 != xmlStrcmp(key_old, key_new)) {
1013                                                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old language(%s), New language(%s)",
1014                                                                 (char*)key_old, (char*)key_new);
1015                                                         if (NULL != *language) {
1016                                                                 free(*language);
1017                                                                 *language = NULL;
1018                                                         }
1019                                                         *language = strdup((char*)key_new);
1020                                                 }
1021                                                 xmlFree(key_new);
1022                                                 key_new = NULL;
1023                                         }
1024                                         xmlFree(key_old);
1025                                         key_old = NULL;
1026                                 }
1027                         } else {
1028                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
1029                         }
1030                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_VOICE_TYPE)) {
1031                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_VOICE_TYPE)) {
1032                                 key_old = xmlNodeGetContent(cur_old);
1033                                 if (NULL != key_old) {
1034                                         key_new = xmlNodeGetContent(cur_new);
1035                                         if (NULL != key_new) {
1036                                                 if (0 != xmlStrcmp(key_old, key_new)) {
1037                                                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old voice type(%s), New voice type(%s)",
1038                                                                 (char*)key_old, (char*)key_new);
1039                                                         if (0 == xmlStrcmp(key_new, (const xmlChar *)TTS_TAG_VOICE_TYPE_FEMALE)) {
1040                                                                 *voice_type = (int)TTS_CONFIG_VOICE_TYPE_FEMALE;
1041                                                         } else if (0 == xmlStrcmp(key_new, (const xmlChar *)TTS_TAG_VOICE_TYPE_MALE)) {
1042                                                                 *voice_type = (int)TTS_CONFIG_VOICE_TYPE_MALE;
1043                                                         } else if (0 == xmlStrcmp(key_new, (const xmlChar *)TTS_TAG_VOICE_TYPE_CHILD)) {
1044                                                                 *voice_type = (int)TTS_CONFIG_VOICE_TYPE_CHILD;
1045                                                         } else {
1046                                                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] New voice type is not valid");
1047                                                         }
1048                                                 }
1049                                                 xmlFree(key_new);
1050                                                 key_new = NULL;
1051                                         }
1052                                         xmlFree(key_old);
1053                                         key_old = NULL;
1054                                 }
1055                         } else {
1056                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
1057                         }
1058                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_SPEECH_RATE)) {
1059                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_SPEECH_RATE)) {
1060                                 key_old = xmlNodeGetContent(cur_old);
1061                                 if (NULL != key_old) {
1062                                         key_new = xmlNodeGetContent(cur_new);
1063                                         if (NULL != key_new) {
1064                                                 if (0 != xmlStrcmp(key_old, key_new)) {
1065                                                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old speech rate(%s), New speech rate(%s)",
1066                                                                 (char*)key_old, (char*)key_new);
1067                                                         *speech_rate = atoi((char*)key_new);
1068                                                 }
1069                                                 xmlFree(key_new);
1070                                                 key_new = NULL;
1071                                         }
1072                                         xmlFree(key_old);
1073                                         key_old = NULL;
1074                                 }
1075                         } else {
1076                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
1077                         }
1078                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_PITCH)) {
1079                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_PITCH)) {
1080                                 key_old = xmlNodeGetContent(cur_old);
1081                                 if (NULL != key_old) {
1082                                         key_new = xmlNodeGetContent(cur_new);
1083                                         if (NULL != key_new) {
1084                                                 if (0 != xmlStrcmp(key_old, key_new)) {
1085                                                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old pitch(%s), New pitch(%s)",
1086                                                                 (char*)key_old, (char*)key_new);
1087                                                         *pitch = atoi((char*)key_new);
1088                                                 }
1089                                                 xmlFree(key_new);
1090                                                 key_new = NULL;
1091                                         }
1092                                         xmlFree(key_old);
1093                                         key_old = NULL;
1094                                 }
1095                         } else {
1096                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
1097                         }
1098                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_BACKGROUND_VOLUME_RATIO)) {
1099                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_BACKGROUND_VOLUME_RATIO)) {
1100                                 key_old = xmlNodeGetContent(cur_old);
1101                                 if (NULL != key_old) {
1102                                         key_new = xmlNodeGetContent(cur_new);
1103                                         if (NULL != key_new) {
1104                                                 if (0 != xmlStrcmp(key_old, key_new)) {
1105                                                         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "Old bg volume ratio(%s), New bg volume ratio(%s)",
1106                                                                 (char*)key_old, (char*)key_new);
1107                                                         *bg_volume_ratio = atof((char*)key_new);
1108                                                 }
1109                                                 xmlFree(key_new);
1110                                                 key_new = NULL;
1111                                         }
1112                                         xmlFree(key_old);
1113                                         key_old = NULL;
1114                                 }
1115                         } else {
1116                                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] old config and new config are different");
1117                         }
1118                 } else {
1119
1120                 }
1121
1122                 cur_new = cur_new->next;
1123                 cur_old = cur_old->next;
1124         }
1125
1126         if (NULL != g_config_doc) {
1127                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] Free g_config_doc(%p)", g_config_doc);
1128                 xmlFreeDoc(g_config_doc);
1129                 g_config_doc = NULL;
1130         }
1131         g_config_doc = doc;
1132
1133         return 0;
1134 }
1135
1136 int tts_parser_reset()
1137 {
1138         SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Reset g_config_doc as %s", TTS_DEFAULT_CONFIG);
1139
1140         if (NULL != g_config_doc) {
1141                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[DEBUG] Free g_config_doc(%p)", g_config_doc);
1142                 xmlFreeDoc(g_config_doc);
1143                 g_config_doc = NULL;
1144         }
1145
1146         g_config_doc = xmlParseFile(TTS_DEFAULT_CONFIG);
1147         if (NULL == g_config_doc) {
1148                 SLOG(LOG_ERROR, TAG_TTSCONFIG, "[ERROR] Fail to parse %s", TTS_DEFAULT_CONFIG);
1149                 return -1;
1150         }
1151
1152         char* engine_id = vconf_get_str(TTS_ENGINE_DB_DEFAULT);
1153         if (engine_id) {
1154                 int ret = __set_value_into_configuration(TTS_TAG_CONFIG_ENGINE_ID, engine_id);
1155                 SLOG(LOG_DEBUG, TAG_TTSCONFIG, "[DEBUG] Set engine ID into xml. engine_id(%s), ret(%d/%s)", engine_id, ret, get_error_message(ret));
1156                 free(engine_id);
1157         }
1158         __save_configuration(g_config_doc);
1159
1160         return 0;
1161 }