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