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