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