Fix dbus delay when requesting hello
[platform/core/uifw/stt.git] / common / stt_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 <sys/stat.h>
16 #include <unistd.h>
17 #include <vconf.h>
18
19 #include "stt_defs.h"
20 #include "stt_config_parser.h"
21
22
23 #define STT_TAG_ENGINE_BASE_TAG         "stt-engine"
24 #define STT_TAG_ENGINE_NAME             "name"
25 #define STT_TAG_ENGINE_ID               "id"
26 #define STT_TAG_ENGINE_SETTING          "setting"
27 #define STT_TAG_ENGINE_AGREEMENT        "agreement"
28 #define STT_TAG_ENGINE_DEFAULT          "default"
29 #define STT_TAG_ENGINE_LANGUAGE_SET     "languages"
30 #define STT_TAG_ENGINE_LANGUAGE         "lang"
31 #define STT_TAG_ENGINE_SILENCE_SUPPORT  "silence-detection-support"
32 #define STT_TAG_ENGINE_CREDENTIAL_NEED  "app-credential-need"
33
34 #define STT_TAG_CONFIG_BASE_TAG         "stt-config"
35 #define STT_TAG_CONFIG_ENGINE_ID        "engine"
36 #define STT_TAG_CONFIG_ENGINE_SETTING   "engine-setting"
37 #define STT_TAG_CONFIG_AUTO_LANGUAGE    "auto"
38 #define STT_TAG_CONFIG_LANGUAGE         "language"
39 #define STT_TAG_CONFIG_SILENCE_DETECTION "silence-detection"
40 #define STT_TAG_CONFIG_CREDENTIAL       "credential"
41
42
43 #define STT_TAG_TIME_BASE_TAG           "stt-time"
44 #define STT_TAG_TIME_INDEX              "index"
45 #define STT_TAG_TIME_COUNT              "count"
46 #define STT_TAG_TIME_TIME_INFO          "time-info"
47 #define STT_TAG_TIME_TEXT               "text-info"
48 #define STT_TAG_TIME_START              "start"
49 #define STT_TAG_TIME_END                "end"
50
51 extern const char* stt_tag();
52
53 static xmlDocPtr g_config_doc = NULL;
54
55 int stt_parser_get_engine_info(const char* path, stt_engine_info_s** engine_info)
56 {
57         if (NULL == path || NULL == engine_info) {
58                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Input parameter is NULL");
59                 return -1;
60         }
61
62         xmlDocPtr doc = NULL;
63         xmlNodePtr cur = NULL;
64         xmlChar *key;
65
66         doc = xmlParseFile(path);
67         if (doc == NULL) {
68                 return -1;
69         }
70
71         cur = xmlDocGetRootElement(doc);
72         if (cur == NULL) {
73                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
74                 xmlFreeDoc(doc);
75                 return -1;
76         }
77
78         if (xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_ENGINE_BASE_TAG)) {
79                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT 'stt-engine'");
80                 xmlFreeDoc(doc);
81                 return -1;
82         }
83
84         cur = cur->xmlChildrenNode;
85         if (cur == NULL) {
86                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
87                 xmlFreeDoc(doc);
88                 return -1;
89         }
90
91         /* alloc engine info */
92         stt_engine_info_s* temp;
93         temp = (stt_engine_info_s*)calloc(1, sizeof(stt_engine_info_s));
94         if (NULL == temp) {
95                 xmlFreeDoc(doc);
96                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to allocate memory");
97                 return -1;
98         }
99
100         temp->name = NULL;
101         temp->uuid = NULL;
102         temp->setting = NULL;
103         temp->agreement = NULL;
104         temp->default_lang = NULL;
105         temp->languages = NULL;
106         temp->support_silence_detection = false;
107         temp->need_credential = false;
108
109         bool is_default_lang_set = false;
110
111         while (cur != NULL) {
112                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_ENGINE_NAME)) {
113                         key = xmlNodeGetContent(cur);
114                         if (NULL != key) {
115                                 /* SLOG(LOG_DEBUG, stt_tag(), "Engine name : %s", (char *)key); */
116                                 if (NULL != temp->name) free(temp->name);
117                                 temp->name = strdup((char*)key);
118                                 xmlFree(key);
119                         } else {
120                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_ENGINE_NAME);
121                         }
122                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_ENGINE_ID)) {
123                         key = xmlNodeGetContent(cur);
124                         if (NULL != key) {
125                                 /* SLOG(LOG_DEBUG, stt_tag(), "Engine uuid : %s", (char *)key); */
126                                 if (NULL != temp->uuid) free(temp->uuid);
127                                 temp->uuid = strdup((char*)key);
128                                 xmlFree(key);
129                         } else {
130                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_ENGINE_ID);
131                         }
132                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_ENGINE_SETTING)) {
133                         key = xmlNodeGetContent(cur);
134                         if (NULL != key) {
135                                 SLOG(LOG_DEBUG, stt_tag(), "Engine setting : %s", (char *)key);
136                                 if (NULL != temp->setting)      free(temp->setting);
137                                 temp->setting = strdup((char*)key);
138                                 xmlFree(key);
139                         } else {
140                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_ENGINE_SETTING);
141                         }
142                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_ENGINE_AGREEMENT)) {
143                         key = xmlNodeGetContent(cur);
144                         if (NULL != key) {
145                                 SLOG(LOG_DEBUG, stt_tag(), "Engine agreement : %s", (char *)key);
146                                 if (NULL != temp->agreement)    free(temp->agreement);
147                                 temp->agreement = strdup((char*)key);
148                                 xmlFree(key);
149                         } else {
150                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_ENGINE_AGREEMENT);
151                         }
152                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_ENGINE_DEFAULT)) {
153                         key = xmlNodeGetContent(cur);
154                         if (NULL != key) {
155                                 SLOG(LOG_DEBUG, stt_tag(), "Engine agreement : %s", (char *)key);
156                                 if (NULL != temp->default_lang) free(temp->default_lang);
157                                 temp->default_lang = strdup((char*)key);
158
159                                 is_default_lang_set = true;
160                                 xmlFree(key);
161                         } else {
162                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_ENGINE_DEFAULT);
163                         }
164                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_ENGINE_LANGUAGE_SET)) {
165                         xmlNodePtr lang_node = NULL;
166                         char* temp_lang = NULL;
167
168                         lang_node = cur->xmlChildrenNode;
169
170                         while (lang_node != NULL) {
171                                 if (0 == xmlStrcmp(lang_node->name, (const xmlChar *)STT_TAG_ENGINE_LANGUAGE)) {
172                                         key = xmlNodeGetContent(lang_node);
173                                         if (NULL != key) {
174                                                 /* SLOG(LOG_DEBUG, stt_tag(), "language : %s", (char *)key); */
175                                                 temp_lang = strdup((char*)key);
176                                                 temp->languages = g_slist_append(temp->languages, temp_lang);
177
178                                                 if (false == is_default_lang_set) {
179                                                         if (NULL != temp->default_lang) free(temp->default_lang);
180                                                         temp->default_lang = strdup((char*)key);
181
182                                                         is_default_lang_set = true;
183                                                 }
184                                                 xmlFree(key);
185                                         } else {
186                                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_ENGINE_LANGUAGE);
187                                         }
188                                 }
189
190                                 lang_node = lang_node->next;
191                         }
192                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_ENGINE_SILENCE_SUPPORT)) {
193                         key = xmlNodeGetContent(cur);
194                         if (NULL != key) {
195                                 /*SLOG(LOG_DEBUG, stt_tag(), "silence-detection-support : %s", (char *)key); */
196
197                                 if (0 == xmlStrcmp(key, (const xmlChar *)"true"))
198                                         temp->support_silence_detection = true;
199                                 else
200                                         temp->support_silence_detection = false;
201
202                                 xmlFree(key);
203                         } else {
204                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_ENGINE_SILENCE_SUPPORT);
205                         }
206                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_ENGINE_CREDENTIAL_NEED)) {
207                         key = xmlNodeGetContent(cur);
208                         if (NULL != key) {
209                                 //SLOG(LOG_DEBUG, stt_tag(), "app-credential-need : %s", (char *)key);
210
211                                 if (0 == xmlStrcmp(key, (const xmlChar *)"true"))
212                                         temp->need_credential = true;
213                                 else
214                                         temp->need_credential = false;
215
216                                 xmlFree(key);
217                         } else {
218                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_ENGINE_CREDENTIAL_NEED);
219                         }
220                 } else {
221
222                 }
223
224                 cur = cur->next;
225         }
226
227         xmlFreeDoc(doc);
228
229         if (NULL == temp->name || NULL == temp->uuid) {
230                 /* Invalid engine */
231                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Invalid engine : %s", path);
232                 stt_parser_free_engine_info(temp);
233                 return -1;
234         }
235
236         *engine_info = temp;
237
238         return 0;
239 }
240
241 int stt_parser_free_engine_info(stt_engine_info_s* engine_info)
242 {
243         if (NULL == engine_info) {
244                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Input parameter is NULL");
245                 return -1;
246         }
247
248         if (NULL != engine_info->name)          free(engine_info->name);
249         if (NULL != engine_info->uuid)          free(engine_info->uuid);
250         if (NULL != engine_info->setting)       free(engine_info->setting);
251         if (NULL != engine_info->agreement)     free(engine_info->agreement);
252
253         int count = g_slist_length(engine_info->languages);
254
255         int i ;
256         char *temp_lang;
257
258         for (i = 0; i < count ; i++) {
259                 temp_lang = g_slist_nth_data(engine_info->languages, 0);
260
261                 if (NULL != temp_lang) {
262                         engine_info->languages = g_slist_remove(engine_info->languages, temp_lang);
263
264                         if (NULL != temp_lang)
265                                 free(temp_lang);
266                 }
267         }
268
269         if (NULL != engine_info)        free(engine_info);
270
271         return 0;
272 }
273
274 int stt_parser_print_engine_info(stt_engine_info_s* engine_info)
275 {
276         if (NULL == engine_info)
277                 return -1;
278
279         SLOG(LOG_DEBUG, stt_tag(), "== get engine info ==");
280         SLOG(LOG_DEBUG, stt_tag(), " name : %s", engine_info->name);
281         SLOG(LOG_DEBUG, stt_tag(), " id   : %s", engine_info->uuid);
282         if (NULL != engine_info->setting)       SLOG(LOG_DEBUG, stt_tag(), " setting : %s", engine_info->setting);
283
284         SLOG(LOG_DEBUG, stt_tag(), " languages");
285         GSList *iter = NULL;
286         char* lang;
287         if (g_slist_length(engine_info->languages) > 0) {
288                 /* Get a first item */
289                 iter = g_slist_nth(engine_info->languages, 0);
290
291                 int i = 1;
292                 while (NULL != iter) {
293                         /*Get handle data from list*/
294                         lang = iter->data;
295
296                         SLOG(LOG_DEBUG, stt_tag(), "  [%dth] %s", i, lang);
297
298                         /*Get next item*/
299                         iter = g_slist_next(iter);
300                         i++;
301                 }
302         } else {
303                 SLOG(LOG_ERROR, stt_tag(), "  language is NONE");
304         }
305         SLOG(LOG_DEBUG, stt_tag(), " silence support : %s", engine_info->support_silence_detection ? "true" : "false");
306         SLOG(LOG_DEBUG, stt_tag(), " credential need : %s", engine_info->need_credential ? "true" : "false");
307         SLOG(LOG_DEBUG, stt_tag(), "=====================");
308
309         return 0;
310 }
311
312 int stt_parser_load_config(stt_config_s** config_info)
313 {
314         if (NULL == config_info) {
315                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Input parameter is NULL");
316                 return -1;
317         }
318
319         xmlDocPtr doc = NULL;
320         xmlNodePtr cur = NULL;
321         xmlChar *key;
322         bool is_default_open = false;
323
324         if (0 != access(STT_CONFIG, F_OK)) {
325                 doc = xmlParseFile(STT_DEFAULT_CONFIG);
326                 if (doc == NULL) {
327                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to parse file error : %s", STT_DEFAULT_CONFIG);
328                         xmlCleanupParser();
329                         return -1;
330                 }
331                 is_default_open = true;
332         } else {
333                 int retry_count = 0;
334
335                 while (NULL == doc) {
336                         doc = xmlParseFile(STT_CONFIG);
337                         if (NULL != doc) {
338                                 break;
339                         }
340                         retry_count++;
341                         usleep(10000);
342
343                         if (STT_RETRY_COUNT == retry_count) {
344                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to parse file error : %s", STT_CONFIG);
345                                 doc = xmlParseFile(STT_DEFAULT_CONFIG);
346                                 if (NULL == doc) {
347                                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to parse file error : %s", STT_DEFAULT_CONFIG);
348                                         xmlCleanupParser();
349                                         return -1;
350                                 }
351                                 is_default_open = true;
352                                 break;
353                         }
354                 }
355         }
356
357         cur = xmlDocGetRootElement(doc);
358         if (cur == NULL) {
359                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
360                 xmlFreeDoc(doc);
361                 return -1;
362         }
363
364         if (xmlStrcmp(cur->name, (const xmlChar *) STT_TAG_CONFIG_BASE_TAG)) {
365                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT %s", STT_TAG_CONFIG_BASE_TAG);
366                 xmlFreeDoc(doc);
367                 return -1;
368         }
369
370         cur = cur->xmlChildrenNode;
371         if (cur == NULL) {
372                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
373                 xmlFreeDoc(doc);
374                 return -1;
375         }
376
377         /* alloc engine info */
378         stt_config_s* temp;
379         temp = (stt_config_s*)calloc(1, sizeof(stt_config_s));
380         if (NULL == temp) {
381                 xmlFreeDoc(doc);
382                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to allocate memory");
383                 return -1;
384         }
385
386         temp->engine_id = NULL;
387         temp->setting = NULL;
388         temp->language = NULL;
389
390         while (cur != NULL) {
391                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_ENGINE_ID)) {
392                         key = xmlNodeGetContent(cur);
393                         if (NULL != key) {
394                                 /*SLOG(LOG_DEBUG, stt_tag(), "Engine id : %s", (char *)key); */
395                                 if (NULL != temp->engine_id)    free(temp->engine_id);
396                                 temp->engine_id = strdup((char*)key);
397                                 xmlFree(key);
398                         } else {
399                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] engine id is NULL");
400                         }
401                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_ENGINE_SETTING)) {
402                         key = xmlNodeGetContent(cur);
403                         if (NULL != key) {
404                                 /*SLOG(LOG_DEBUG, stt_tag(), "Setting path : %s", (char *)key); */
405                                 if (NULL != temp->setting)      free(temp->setting);
406                                 temp->setting = strdup((char*)key);
407                                 xmlFree(key);
408                         } else {
409                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] setting path is NULL");
410                         }
411
412                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_AUTO_LANGUAGE)) {
413                         key = xmlNodeGetContent(cur);
414                         if (NULL != key) {
415                                 /*SLOG(LOG_DEBUG, stt_tag(), "Auto language : %s", (char *)key); */
416
417                                 if (0 == xmlStrcmp(key, (const xmlChar *)"on")) {
418                                         temp->auto_lang = true;
419                                 } else if (0 == xmlStrcmp(key, (const xmlChar *)"off")) {
420                                         temp->auto_lang = false;
421                                 } else {
422                                         SLOG(LOG_ERROR, stt_tag(), "Auto voice is wrong");
423                                         temp->auto_lang = true;
424                                 }
425
426                                 xmlFree(key);
427                         } else {
428                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] auto langauge is NULL");
429                         }
430                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_LANGUAGE)) {
431                         key = xmlNodeGetContent(cur);
432                         if (NULL != key) {
433                                 /*SLOG(LOG_DEBUG, stt_tag(), "language : %s", (char *)key); */
434                                 if (NULL != temp->language)     free(temp->language);
435                                 temp->language = strdup((char*)key);
436                                 xmlFree(key);
437                         } else {
438                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] language is NULL");
439                         }
440                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_SILENCE_DETECTION)) {
441                         key = xmlNodeGetContent(cur);
442                         if (NULL != key) {
443                                 /*SLOG(LOG_DEBUG, stt_tag(), "silence-detection : %s", (char *)key); */
444
445                                 if (0 == xmlStrcmp(key, (const xmlChar *)"on"))
446                                         temp->silence_detection = true;
447                                 else
448                                         temp->silence_detection = false;
449
450                                 xmlFree(key);
451                         } else {
452                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] silence-detection is NULL");
453                         }
454                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_CREDENTIAL)) {
455                         key = xmlNodeGetContent(cur);
456                         if (NULL != key) {
457                                 //SLOG(LOG_DEBUG, stt_tag(), "credential : %s", (char *)key);
458
459                                 if (0 == xmlStrcmp(key, (const xmlChar *)"true"))
460                                         temp->credential = true;
461                                 else
462                                         temp->credential = false;
463
464                                 xmlFree(key);
465                         } else {
466                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] credential is NULL");
467                         }
468                 } else {
469
470                 }
471
472                 cur = cur->next;
473         }
474
475         *config_info = temp;
476         g_config_doc = doc;
477
478         if (is_default_open) {
479                 int retry_count = 0;
480                 int ret = -1;
481                 do {
482                         ret = xmlSaveFile(STT_CONFIG, g_config_doc);
483                         if (0 < ret)
484                                 break;
485                         retry_count++;
486                         usleep(10000);
487
488                         if (STT_RETRY_COUNT == retry_count) {
489                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Save result : %d", ret);
490                                 return -1;
491                         }
492                 } while (0 != ret);
493
494                 /* Set mode */
495                 if (0 > chmod(STT_CONFIG, 0600)) {
496                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to change file mode : %d", ret);
497                 }
498
499                 /* Set owner */
500                 if (0 > chown(STT_CONFIG, 5000, 5000)) {
501                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to change file owner : %d", ret);
502                 }
503                 SLOG(LOG_DEBUG, stt_tag(), "Default config is changed : pid(%d)", getpid());
504         }
505
506         return 0;
507 }
508
509 int stt_parser_unload_config(stt_config_s* config_info)
510 {
511         if (NULL != g_config_doc)       xmlFreeDoc(g_config_doc);
512         if (NULL != config_info) {
513                 if (NULL != config_info->engine_id) {
514                         free(config_info->engine_id);
515                         config_info->engine_id = NULL;
516                 }
517                 if (NULL != config_info->setting) {
518                         free(config_info->setting);
519                         config_info->setting = NULL;
520                 }
521                 if (NULL != config_info->language) {
522                         free(config_info->language);
523                         config_info->language = NULL;
524                 }
525
526                 free(config_info);
527         }
528
529         return 0;
530 }
531
532 int stt_parser_set_engine(const char* engine_id, const char* setting, const char* language, bool silence, bool credential)
533 {
534         if (NULL == g_config_doc || NULL == engine_id)
535                 return -1;
536
537         xmlNodePtr cur = NULL;
538         cur = xmlDocGetRootElement(g_config_doc);
539         if (cur == NULL) {
540                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
541                 return -1;
542         }
543
544         if (xmlStrcmp(cur->name, (const xmlChar *) STT_TAG_CONFIG_BASE_TAG)) {
545                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT %s", STT_TAG_CONFIG_BASE_TAG);
546                 return -1;
547         }
548
549         cur = cur->xmlChildrenNode;
550         if (cur == NULL) {
551                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
552                 return -1;
553         }
554
555         while (cur != NULL) {
556                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_ENGINE_ID)) {
557                         xmlNodeSetContent(cur, (const xmlChar *)engine_id);
558                 }
559
560                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_LANGUAGE)) {
561                         xmlNodeSetContent(cur, (const xmlChar *)language);
562                 }
563
564                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_ENGINE_SETTING)) {
565                         xmlNodeSetContent(cur, (const xmlChar *)setting);
566                 }
567
568                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_SILENCE_DETECTION)) {
569                         if (true == silence)
570                                 xmlNodeSetContent(cur, (const xmlChar *)"on");
571                         else
572                                 xmlNodeSetContent(cur, (const xmlChar *)"off");
573                 }
574
575                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_CREDENTIAL)) {
576                         if (true == credential)
577                                 xmlNodeSetContent(cur, (const xmlChar *)"true");
578                         else
579                                 xmlNodeSetContent(cur, (const xmlChar *)"false");
580                 }
581
582                 cur = cur->next;
583         }
584
585         int ret = xmlSaveFile(STT_CONFIG, g_config_doc);
586         SLOG(LOG_DEBUG, stt_tag(), "Save result : %d", ret);
587
588         return 0;
589 }
590
591 int stt_parser_set_language(const char* language)
592 {
593         if (NULL == g_config_doc || NULL == language)
594                 return -1;
595
596         xmlNodePtr cur = NULL;
597         cur = xmlDocGetRootElement(g_config_doc);
598         if (cur == NULL) {
599                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
600                 return -1;
601         }
602
603         if (xmlStrcmp(cur->name, (const xmlChar *) STT_TAG_CONFIG_BASE_TAG)) {
604                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT %s", STT_TAG_CONFIG_BASE_TAG);
605                 return -1;
606         }
607
608         cur = cur->xmlChildrenNode;
609         if (cur == NULL) {
610                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
611                 return -1;
612         }
613
614         while (cur != NULL) {
615                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_LANGUAGE)) {
616                         xmlNodeSetContent(cur, (const xmlChar *)language);
617                 }
618
619                 cur = cur->next;
620         }
621
622         int ret = xmlSaveFile(STT_CONFIG, g_config_doc);
623         SLOG(LOG_DEBUG, stt_tag(), "Save result : %d", ret);
624
625
626         return 0;
627 }
628
629 int stt_parser_set_auto_lang(bool value)
630 {
631         if (NULL == g_config_doc)
632                 return -1;
633
634         xmlNodePtr cur = NULL;
635         cur = xmlDocGetRootElement(g_config_doc);
636         if (cur == NULL) {
637                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
638                 return -1;
639         }
640
641         if (xmlStrcmp(cur->name, (const xmlChar *) STT_TAG_CONFIG_BASE_TAG)) {
642                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT %s", STT_TAG_CONFIG_BASE_TAG);
643                 return -1;
644         }
645
646         cur = cur->xmlChildrenNode;
647         if (cur == NULL) {
648                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
649                 return -1;
650         }
651
652         while (cur != NULL) {
653                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_AUTO_LANGUAGE)) {
654                         if (true == value) {
655                                 xmlNodeSetContent(cur, (const xmlChar *)"on");
656                         } else if (false == value) {
657                                 xmlNodeSetContent(cur, (const xmlChar *)"off");
658                         } else {
659                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong value of auto voice");
660                                 return -1;
661                         }
662                         break;
663                 }
664                 cur = cur->next;
665         }
666
667         int ret = xmlSaveFile(STT_CONFIG, g_config_doc);
668         SLOG(LOG_DEBUG, stt_tag(), "Save result : %d", ret);
669
670         return 0;
671 }
672
673 int stt_parser_set_silence_detection(bool value)
674 {
675         if (NULL == g_config_doc)
676                 return -1;
677
678         xmlNodePtr cur = NULL;
679         cur = xmlDocGetRootElement(g_config_doc);
680         if (cur == NULL) {
681                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
682                 return -1;
683         }
684
685         if (xmlStrcmp(cur->name, (const xmlChar *) STT_TAG_CONFIG_BASE_TAG)) {
686                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT %s", STT_TAG_CONFIG_BASE_TAG);
687                 return -1;
688         }
689
690         cur = cur->xmlChildrenNode;
691         if (cur == NULL) {
692                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
693                 return -1;
694         }
695
696         while (cur != NULL) {
697                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_SILENCE_DETECTION)) {
698                         if (true == value)
699                                 xmlNodeSetContent(cur, (const xmlChar *)"on");
700                         else
701                                 xmlNodeSetContent(cur, (const xmlChar *)"off");
702                 }
703
704                 cur = cur->next;
705         }
706
707         int ret = xmlSaveFile(STT_CONFIG, g_config_doc);
708         SLOG(LOG_DEBUG, stt_tag(), "Save result : %d", ret);
709
710         return 0;
711 }
712
713 int stt_parser_find_config_changed(char** engine, char** setting, int* auto_lang, char** language, int* silence, int* credential)
714 {
715         if (NULL == engine || NULL == language || NULL == silence || NULL == credential) {
716                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Input parameter is NULL");
717                 return -1;
718         }
719
720         xmlDocPtr doc = NULL;
721         xmlNodePtr cur_new = NULL;
722         xmlNodePtr cur_old = NULL;
723
724         xmlChar *key_new;
725         xmlChar *key_old;
726
727         doc = xmlParseFile(STT_CONFIG);
728         if (doc == NULL) {
729                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to parse file error : %s", STT_CONFIG);
730                 return -1;
731         }
732
733         cur_new = xmlDocGetRootElement(doc);
734         cur_old = xmlDocGetRootElement(g_config_doc);
735         if (cur_new == NULL || cur_old == NULL) {
736                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
737                 xmlFreeDoc(doc);
738                 return -1;
739         }
740
741         if (xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_BASE_TAG) || xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_BASE_TAG)) {
742                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT %s", STT_TAG_CONFIG_BASE_TAG);
743                 xmlFreeDoc(doc);
744                 return -1;
745         }
746
747         cur_new = cur_new->xmlChildrenNode;
748         cur_old = cur_old->xmlChildrenNode;
749         if (cur_new == NULL || cur_old == NULL) {
750                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
751                 xmlFreeDoc(doc);
752                 return -1;
753         }
754
755         *engine = NULL;
756         *setting = NULL;
757         *language = NULL;
758
759         while (cur_new != NULL && cur_old != NULL) {
760                 if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_ENGINE_ID)) {
761                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_ENGINE_ID)) {
762                                 key_old = xmlNodeGetContent(cur_old);
763                                 if (NULL != key_old) {
764                                         key_new = xmlNodeGetContent(cur_new);
765                                         if (NULL != key_new) {
766                                                 if (0 != xmlStrcmp(key_old, key_new)) {
767                                                         SLOG(LOG_DEBUG, stt_tag(), "Old engine id(%s), New engine(%s)", (char*)key_old, (char*)key_new);
768                                                         if (NULL != *engine)    free(*engine);
769                                                         *engine = strdup((char*)key_new);
770                                                 }
771                                                 xmlFree(key_new);
772                                         }
773                                         xmlFree(key_old);
774                                 }
775                         } else {
776                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Old config and new config are different");
777                         }
778                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_ENGINE_SETTING)) {
779                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_ENGINE_SETTING)) {
780                                 key_old = xmlNodeGetContent(cur_old);
781                                 if (NULL != key_old) {
782                                         key_new = xmlNodeGetContent(cur_new);
783                                         if (NULL != key_new) {
784                                                 if (0 != xmlStrcmp(key_old, key_new)) {
785                                                         SLOG(LOG_DEBUG, stt_tag(), "Old engine setting(%s), New engine setting(%s)", (char*)key_old, (char*)key_new);
786                                                         if (NULL != *setting)   free(*setting);
787                                                         *setting = strdup((char*)key_new);
788                                                 }
789                                                 xmlFree(key_new);
790                                         }
791                                         xmlFree(key_old);
792                                 }
793                         } else {
794                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Old config and new config are different");
795                         }
796                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_AUTO_LANGUAGE)) {
797                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_AUTO_LANGUAGE)) {
798                                 key_old = xmlNodeGetContent(cur_old);
799                                 if (NULL != key_old) {
800                                         key_new = xmlNodeGetContent(cur_new);
801                                         if (NULL != key_new) {
802                                                 if (0 != xmlStrcmp(key_old, key_new)) {
803                                                         SLOG(LOG_DEBUG, stt_tag(), "Old auto lang(%s), New auto lang(%s)", (char*)key_old, (char*)key_new);
804                                                         if (0 == xmlStrcmp((const xmlChar*)"on", key_new)) {
805                                                                 *auto_lang = (int)true;
806                                                         } else {
807                                                                 *auto_lang = (int)false;
808                                                         }
809                                                 }
810
811                                                 xmlFree(key_new);
812                                         }
813                                         xmlFree(key_old);
814                                 }
815                         } else {
816                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] old config and new config are different");
817                         }
818                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_LANGUAGE)) {
819                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_LANGUAGE)) {
820                                 key_old = xmlNodeGetContent(cur_old);
821                                 if (NULL != key_old) {
822                                         key_new = xmlNodeGetContent(cur_new);
823                                         if (NULL != key_new) {
824                                                 if (0 != xmlStrcmp(key_old, key_new)) {
825                                                         SLOG(LOG_DEBUG, stt_tag(), "Old language(%s), New language(%s)", (char*)key_old, (char*)key_new);
826                                                         if (NULL != *language)  free(*language);
827                                                         *language = strdup((char*)key_new);
828                                                 }
829                                                 xmlFree(key_new);
830                                         }
831                                         xmlFree(key_old);
832                                 }
833                         } else {
834                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] old config and new config are different");
835                         }
836                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_SILENCE_DETECTION)) {
837                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_SILENCE_DETECTION)) {
838                                 key_old = xmlNodeGetContent(cur_old);
839                                 if (NULL != key_old) {
840                                         key_new = xmlNodeGetContent(cur_new);
841                                         if (NULL != key_new) {
842                                                 if (0 != xmlStrcmp(key_old, key_new)) {
843                                                         SLOG(LOG_DEBUG, stt_tag(), "Old silence(%s), New silence(%s)", (char*)key_old, (char*)key_new);
844                                                         if (0 == xmlStrcmp(key_new, (const xmlChar*)"on")) {
845                                                                 *silence = 1;
846                                                         } else {
847                                                                 *silence = 0;
848                                                         }
849                                                 }
850
851                                                 xmlFree(key_new);
852                                         }
853                                         xmlFree(key_old);
854                                 }
855                         } else {
856                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] old config and new config are different");
857                         }
858                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_CREDENTIAL)) {
859                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_CREDENTIAL)) {
860                                 key_old = xmlNodeGetContent(cur_old);
861                                 if (NULL != key_old) {
862                                         key_new = xmlNodeGetContent(cur_new);
863                                         if (NULL != key_new) {
864                                                 if (0 != xmlStrcmp(key_old, key_new)) {
865                                                         SLOG(LOG_DEBUG, stt_tag(), "Old credential(%s), New credential(%s)", (char*)key_old, (char*)key_new);
866                                                         if (0 == xmlStrcmp(key_new, (const xmlChar*)"true")) {
867                                                                 *credential = 1;
868                                                         } else {
869                                                                 *credential = 0;
870                                                         }
871                                                 }
872                                                 xmlFree(key_new);
873                                         }
874                                         xmlFree(key_old);
875                                 }
876                         } else {
877                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] old config and new config are different");
878                         }
879
880                 } else {
881
882                 }
883
884                 cur_new = cur_new->next;
885                 cur_old = cur_old->next;
886         }
887
888         xmlFreeDoc(g_config_doc);
889         g_config_doc = doc;
890
891         return 0;
892 }
893
894 /**
895 * time function
896 */
897
898 int stt_parser_set_time_info(GSList* time_list)
899 {
900         if (0 == g_slist_length(time_list)) {
901                 SLOG(LOG_WARN, stt_tag(), "[WARNING] There is no time info to save");
902                 return -1;
903         }
904
905         if (-1 == remove(STT_TIME_INFO_PATH)) {
906                 SLOG(LOG_WARN, stt_tag(), "[PLAYER WARNING] Fail to remove file(%s)", STT_TIME_INFO_PATH);
907         }
908
909         xmlDocPtr doc = NULL;
910         xmlNodePtr cur = NULL;
911
912         doc = xmlNewDoc((const xmlChar*)"1.0");
913         if (doc == NULL) {
914                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to make new doc");
915                 return -1;
916         }
917
918         cur = xmlNewNode(NULL, (const xmlChar*)STT_TAG_TIME_BASE_TAG);
919         xmlDocSetRootElement(doc, cur);
920
921         xmlNodePtr inode = NULL;
922         GSList *iter = NULL;
923         stt_result_time_info_s *data = NULL;
924         char temp_str[256];
925
926         snprintf(temp_str, 256, "%d", g_slist_length(time_list));
927
928         inode = xmlNewNode(NULL, (const xmlChar*)STT_TAG_TIME_INDEX);
929         xmlNewProp(inode, (const xmlChar*)STT_TAG_TIME_COUNT, (const xmlChar*)temp_str);
930         xmlAddChild(cur, inode);
931
932         /* Get a first item */
933         iter = g_slist_nth(time_list, 0);
934         while (NULL != iter) {
935                 data = iter->data;
936
937                 if (NULL == data) {
938                         SLOG(LOG_DEBUG, stt_tag(), "data is NULL");
939                         continue;
940                 }
941
942                 xmlNodePtr temp_node = NULL;
943
944                 SECURE_SLOG(LOG_DEBUG, stt_tag(), "[%d] i(%d) t(%s) s(%ld) e(%ld)",
945                         data->index, data->event, data->text, data->start_time, data->end_time);
946
947                 temp_node = xmlNewNode(NULL, (const xmlChar*)STT_TAG_TIME_TEXT);
948                 xmlNodeSetContent(temp_node, (const xmlChar*)data->text);
949                 xmlAddChild(inode, temp_node);
950
951                 temp_node = xmlNewNode(NULL, (const xmlChar*)STT_TAG_TIME_START);
952                 snprintf(temp_str, 256, "%ld", data->start_time);
953                 xmlNodeSetContent(temp_node, (const xmlChar*)temp_str);
954                 xmlAddChild(inode, temp_node);
955
956                 temp_node = xmlNewNode(NULL, (const xmlChar*)STT_TAG_TIME_END);
957                 snprintf(temp_str, 256, "%ld", data->end_time);
958                 xmlNodeSetContent(temp_node, (const xmlChar*)temp_str);
959                 xmlAddChild(inode, temp_node);
960
961                 /*Get next item*/
962                 iter = g_slist_next(iter);
963         }
964
965         int ret = xmlSaveFormatFile(STT_TIME_INFO_PATH, doc, 1);
966         SLOG(LOG_DEBUG, stt_tag(), "Save result : %d", ret);
967
968         xmlFreeDoc(doc);
969         return 0;
970 }
971
972 void __stt_parser_time_info_free(void* data)
973 {
974         stt_result_time_info_s* time_info = (stt_result_time_info_s*)data;
975
976         if (NULL != time_info) {
977                 if (NULL != time_info->text) {
978                         free(time_info->text);
979                         time_info->text = NULL;
980                 }
981
982                 free(time_info);
983         }
984 }
985
986 int stt_parser_get_time_info(GSList** time_list)
987 {
988         if (NULL == time_list) {
989                 SLOG(LOG_ERROR, stt_tag(), "Invalid paramter : text is NULL");
990                 return -1;
991         }
992
993         xmlDocPtr doc = NULL;
994         xmlNodePtr cur = NULL;
995
996         doc = xmlParseFile(STT_TIME_INFO_PATH);
997         if (doc == NULL) {
998                 SLOG(LOG_WARN, stt_tag(), "[WARNING] File is not exist");
999                 return -1;
1000         }
1001
1002         cur = xmlDocGetRootElement(doc);
1003         if (cur == NULL) {
1004                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
1005                 xmlFreeDoc(doc);
1006                 return -1;
1007         }
1008
1009         if (xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_TIME_BASE_TAG)) {
1010                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT '%s'", STT_TAG_TIME_BASE_TAG);
1011                 xmlFreeDoc(doc);
1012                 return -1;
1013         }
1014
1015         cur = cur->xmlChildrenNode;
1016         if (cur == NULL) {
1017                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
1018                 xmlFreeDoc(doc);
1019                 return -1;
1020         }
1021
1022         /* alloc time info */
1023         GSList *temp_time_list = NULL;
1024         xmlChar *key = NULL;
1025         int index = 0;
1026
1027         while (cur != NULL) {
1028                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_TIME_INDEX)) {
1029                         key = xmlGetProp(cur, (const xmlChar*)STT_TAG_TIME_COUNT);
1030                         if (NULL == key) {
1031                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_TIME_COUNT);
1032
1033                                 if (NULL != temp_time_list) {
1034                                         g_slist_free_full(temp_time_list, __stt_parser_time_info_free);
1035                                         temp_time_list = NULL;
1036                                 }
1037                                 xmlFreeDoc(doc);
1038                                 return -1;
1039                         }
1040
1041                         SLOG(LOG_DEBUG, stt_tag(), "Count : %s", (char *)key);
1042
1043                         /* Get time count */
1044                         int count = 0;
1045                         count = atoi((char*)key);
1046                         xmlFree(key);
1047
1048                         if (count <= 0) {
1049                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] count is invalid : %d", count);
1050                                 break;
1051                         }
1052
1053                         xmlNodePtr time_node = NULL;
1054                         time_node = cur->xmlChildrenNode;
1055
1056                         int i = 0;
1057                         for (i = 0; i < count; i++) {
1058                                 /* text */
1059                                 time_node = time_node->next;
1060
1061                                 stt_result_time_info_s* temp_info;
1062                                 temp_info = (stt_result_time_info_s*)calloc(1, sizeof(stt_result_time_info_s));
1063
1064                                 if (NULL == temp_info) {
1065                                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Memory alloc error!!");
1066
1067                                         if (NULL != temp_time_list) {
1068                                                 g_slist_free_full(temp_time_list, __stt_parser_time_info_free);
1069                                                 temp_time_list = NULL;
1070                                         }
1071                                         xmlFreeDoc(doc);
1072                                         return -1;
1073                                 }
1074
1075                                 temp_info->index = index;
1076                                 SLOG(LOG_DEBUG, stt_tag(), "index : %d", temp_info->index);
1077
1078                                 if (0 == i)             temp_info->event = 0;
1079                                 else if (count -1 == i) temp_info->event = 2;
1080                                 else                    temp_info->event = 1;
1081
1082                                 if (0 == xmlStrcmp(time_node->name, (const xmlChar *)STT_TAG_TIME_TEXT)) {
1083                                         key = xmlNodeGetContent(time_node);
1084                                         if (NULL != key) {
1085                                                 SLOG(LOG_DEBUG, stt_tag(), "text : %s", (char *)key);
1086                                                 temp_info->text = strdup((char*)key);
1087                                                 xmlFree(key);
1088                                         } else {
1089                                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_TIME_TEXT);
1090                                                 free(temp_info);
1091                                                 break;
1092                                         }
1093                                 }
1094
1095                                 /* text */
1096                                 time_node = time_node->next;
1097                                 time_node = time_node->next;
1098
1099                                 if (0 == xmlStrcmp(time_node->name, (const xmlChar *)STT_TAG_TIME_START)) {
1100                                         key = xmlNodeGetContent(time_node);
1101                                         if (NULL != key) {
1102                                                 SLOG(LOG_DEBUG, stt_tag(), "Start time : %s", (char *)key);
1103                                                 temp_info->start_time = atoi((char*)key);
1104                                                 xmlFree(key);
1105                                         } else {
1106                                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_TIME_START);
1107                                                 if (NULL != temp_info->text)    free(temp_info->text);
1108                                                 free(temp_info);
1109                                                 break;
1110                                         }
1111                                 }
1112
1113                                 /* text */
1114                                 time_node = time_node->next;
1115                                 time_node = time_node->next;
1116
1117                                 if (0 == xmlStrcmp(time_node->name, (const xmlChar *)STT_TAG_TIME_END)) {
1118                                         key = xmlNodeGetContent(time_node);
1119                                         if (NULL != key) {
1120                                                 SLOG(LOG_DEBUG, stt_tag(), "End time : %s", (char *)key);
1121                                                 temp_info->end_time = atoi((char*)key);
1122                                                 xmlFree(key);
1123                                         } else {
1124                                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_TIME_END);
1125                                                 if (NULL != temp_info->text)    free(temp_info->text);
1126                                                 free(temp_info);
1127                                                 break;
1128                                         }
1129                                 }
1130
1131                                 time_node = time_node->next;
1132
1133                                 temp_time_list = g_slist_append(temp_time_list, temp_info);
1134                         } /* for */
1135                         index++;
1136                 } /* if */
1137                 cur = cur->next;
1138         }
1139
1140         xmlFreeDoc(doc);
1141
1142         *time_list = temp_time_list;
1143
1144         return 0;
1145 }
1146
1147 int stt_parser_clear_time_info()
1148 {
1149         if (-1 == remove(STT_TIME_INFO_PATH)) {
1150                 /* SLOG(LOG_WARN, stt_tag(), "[PLAYER WARNING] Fail to remove file(%s)", STT_TIME_INFO_PATH); */
1151         }
1152
1153         return 0;
1154 }