8b45fc364600ebfe414d4d7a2fc0efe5ab6cae8a
[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                                 doc = xmlParseFile(STT_DEFAULT_CONFIG);
356                                 if (NULL == doc) {
357                                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to parse file error : %s", STT_DEFAULT_CONFIG);
358                                         xmlCleanupParser();
359                                         return -1;
360                                 }
361                                 is_default_open = true;
362                                 break;
363                         }
364                 }
365         }
366
367         cur = xmlDocGetRootElement(doc);
368         if (cur == NULL) {
369                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document"); //LCOV_EXCL_LINE
370                 xmlFreeDoc(doc);
371                 return -1;
372         }
373
374         if (xmlStrcmp(cur->name, (const xmlChar *) STT_TAG_CONFIG_BASE_TAG)) {
375                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT %s", STT_TAG_CONFIG_BASE_TAG); //LCOV_EXCL_LINE
376                 xmlFreeDoc(doc);
377                 return -1;
378         }
379
380         cur = cur->xmlChildrenNode;
381         if (cur == NULL) {
382                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document"); //LCOV_EXCL_LINE
383                 xmlFreeDoc(doc);
384                 return -1;
385         }
386
387         /* alloc engine info */
388         stt_config_s* temp;
389         temp = (stt_config_s*)calloc(1, sizeof(stt_config_s));
390         if (NULL == temp) {
391                 xmlFreeDoc(doc);
392                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to allocate memory"); //LCOV_EXCL_LINE
393                 return -1;
394         }
395
396         temp->engine_id = NULL;
397         temp->setting = NULL;
398         temp->language = NULL;
399
400         while (cur != NULL) {
401                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_ENGINE_ID)) {
402                         key = xmlNodeGetContent(cur);
403                         if (NULL != key) {
404                                 /*SLOG(LOG_DEBUG, stt_tag(), "Engine id : %s", (char *)key); */
405                                 if (NULL != temp->engine_id)    free(temp->engine_id);
406                                 temp->engine_id = strdup((char*)key);
407                                 xmlFree(key);
408                         } else {
409                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] engine id is NULL"); //LCOV_EXCL_LINE
410                         }
411                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_ENGINE_SETTING)) {
412                         key = xmlNodeGetContent(cur);
413                         if (NULL != key) {
414                                 /*SLOG(LOG_DEBUG, stt_tag(), "Setting path : %s", (char *)key); */
415                                 if (NULL != temp->setting)      free(temp->setting);
416                                 temp->setting = strdup((char*)key);
417                                 xmlFree(key);
418                         } else {
419                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] setting path is NULL"); //LCOV_EXCL_LINE
420                         }
421
422                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_AUTO_LANGUAGE)) {
423                         key = xmlNodeGetContent(cur);
424                         if (NULL != key) {
425                                 /*SLOG(LOG_DEBUG, stt_tag(), "Auto language : %s", (char *)key); */
426
427                                 if (0 == xmlStrcmp(key, (const xmlChar *)"on")) {
428                                         temp->auto_lang = true;
429                                 } else if (0 == xmlStrcmp(key, (const xmlChar *)"off")) {
430                                         temp->auto_lang = false;
431                                 } else {
432                                         SLOG(LOG_ERROR, stt_tag(), "Auto voice is wrong"); //LCOV_EXCL_LINE
433                                         temp->auto_lang = true;
434                                 }
435
436                                 xmlFree(key);
437                         } else {
438                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] auto language is NULL"); //LCOV_EXCL_LINE
439                         }
440                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_LANGUAGE)) {
441                         key = xmlNodeGetContent(cur);
442                         if (NULL != key) {
443                                 /*SLOG(LOG_DEBUG, stt_tag(), "language : %s", (char *)key); */
444                                 if (NULL != temp->language)     free(temp->language);
445                                 temp->language = strdup((char*)key);
446                                 xmlFree(key);
447                         } else {
448                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] language is NULL"); //LCOV_EXCL_LINE
449                         }
450                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_SILENCE_DETECTION)) {
451                         key = xmlNodeGetContent(cur);
452                         if (NULL != key) {
453                                 /*SLOG(LOG_DEBUG, stt_tag(), "silence-detection : %s", (char *)key); */
454
455                                 if (0 == xmlStrcmp(key, (const xmlChar *)"on"))
456                                         temp->silence_detection = true;
457                                 else
458                                         temp->silence_detection = false;
459
460                                 xmlFree(key);
461                         } else {
462                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] silence-detection is NULL"); //LCOV_EXCL_LINE
463                         }
464                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_CREDENTIAL)) {
465                         key = xmlNodeGetContent(cur);
466                         if (NULL != key) {
467                                 //SLOG(LOG_DEBUG, stt_tag(), "credential : %s", (char *)key);
468
469                                 if (0 == xmlStrcmp(key, (const xmlChar *)"true"))
470                                         temp->credential = true;
471                                 else
472                                         temp->credential = false;
473
474                                 xmlFree(key);
475                         } else {
476                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] credential is NULL"); //LCOV_EXCL_LINE
477                         }
478                 } else {
479
480                 }
481
482                 cur = cur->next;
483         }
484
485         *config_info = temp;
486         g_config_doc = doc;
487
488         if (is_default_open) {
489                 int retry_count = 0;
490                 int ret = -1;
491                 do {
492                         ret = xmlSaveFile(STT_CONFIG, g_config_doc);
493                         if (0 < ret)
494                                 break;
495                         retry_count++;
496                         usleep(10000);
497
498                         if (STT_RETRY_COUNT == retry_count) {
499                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Save result : %d", ret);
500                                 return -1;
501                         }
502                 } while (0 != ret);
503
504                 /* Set mode */
505                 if (0 > chmod(STT_CONFIG, 0600)) {
506                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to change file mode : %d", ret);
507                 }
508
509                 /* Set owner */
510                 if (0 > chown(STT_CONFIG, 5000, 5000)) {
511                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to change file owner : %d", ret);
512                 }
513                 SLOG(LOG_DEBUG, stt_tag(), "Default config is changed : pid(%d)", getpid());
514         }
515
516         return 0;
517 }
518
519 int stt_parser_unload_config(stt_config_s* config_info)
520 {
521         if (NULL != g_config_doc)       xmlFreeDoc(g_config_doc);
522         if (NULL != config_info) {
523                 if (NULL != config_info->engine_id) {
524                         free(config_info->engine_id);
525                         config_info->engine_id = NULL;
526                 }
527                 if (NULL != config_info->setting) {
528                         free(config_info->setting);
529                         config_info->setting = NULL;
530                 }
531                 if (NULL != config_info->language) {
532                         free(config_info->language);
533                         config_info->language = NULL;
534                 }
535
536                 free(config_info);
537         }
538
539         return 0;
540 }
541
542 int stt_parser_set_engine(const char* engine_id, const char* setting, const char* language, bool silence, bool credential)
543 {
544         if (NULL == g_config_doc || NULL == engine_id)
545                 return -1;
546
547         xmlNodePtr cur = NULL;
548         cur = xmlDocGetRootElement(g_config_doc);
549         if (cur == NULL) {
550                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
551                 return -1;
552         }
553
554         if (xmlStrcmp(cur->name, (const xmlChar *) STT_TAG_CONFIG_BASE_TAG)) {
555                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT %s", STT_TAG_CONFIG_BASE_TAG);
556                 return -1;
557         }
558
559         cur = cur->xmlChildrenNode;
560         if (cur == NULL) {
561                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
562                 return -1;
563         }
564
565         while (cur != NULL) {
566                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_ENGINE_ID)) {
567                         xmlNodeSetContent(cur, (const xmlChar *)engine_id);
568                 }
569
570                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_LANGUAGE)) {
571                         xmlNodeSetContent(cur, (const xmlChar *)language);
572                 }
573
574                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_ENGINE_SETTING)) {
575                         xmlNodeSetContent(cur, (const xmlChar *)setting);
576                 }
577
578                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_SILENCE_DETECTION)) {
579                         if (true == silence)
580                                 xmlNodeSetContent(cur, (const xmlChar *)"on");
581                         else
582                                 xmlNodeSetContent(cur, (const xmlChar *)"off");
583                 }
584
585                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_CREDENTIAL)) {
586                         if (true == credential)
587                                 xmlNodeSetContent(cur, (const xmlChar *)"true");
588                         else
589                                 xmlNodeSetContent(cur, (const xmlChar *)"false");
590                 }
591
592                 cur = cur->next;
593         }
594
595         int ret = xmlSaveFile(STT_CONFIG, g_config_doc);
596         SLOG(LOG_DEBUG, stt_tag(), "Save result : %d", ret);
597
598         return 0;
599 }
600
601 int stt_parser_set_language(const char* language)
602 {
603         if (NULL == g_config_doc || NULL == language)
604                 return -1;
605
606         xmlNodePtr cur = NULL;
607         cur = xmlDocGetRootElement(g_config_doc);
608         if (cur == NULL) {
609                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
610                 return -1;
611         }
612
613         if (xmlStrcmp(cur->name, (const xmlChar *) STT_TAG_CONFIG_BASE_TAG)) {
614                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT %s", STT_TAG_CONFIG_BASE_TAG);
615                 return -1;
616         }
617
618         cur = cur->xmlChildrenNode;
619         if (cur == NULL) {
620                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
621                 return -1;
622         }
623
624         while (cur != NULL) {
625                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_LANGUAGE)) {
626                         xmlNodeSetContent(cur, (const xmlChar *)language);
627                 }
628
629                 cur = cur->next;
630         }
631
632         int ret = xmlSaveFile(STT_CONFIG, g_config_doc);
633         SLOG(LOG_DEBUG, stt_tag(), "Save result : %d", ret);
634
635
636         return 0;
637 }
638
639 //LCOV_EXCL_START
640 int stt_parser_set_auto_lang(bool value)
641 {
642         if (NULL == g_config_doc)
643                 return -1;
644
645         xmlNodePtr cur = NULL;
646         cur = xmlDocGetRootElement(g_config_doc);
647         if (cur == NULL) {
648                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
649                 return -1;
650         }
651
652         if (xmlStrcmp(cur->name, (const xmlChar *) STT_TAG_CONFIG_BASE_TAG)) {
653                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT %s", STT_TAG_CONFIG_BASE_TAG);
654                 return -1;
655         }
656
657         cur = cur->xmlChildrenNode;
658         if (cur == NULL) {
659                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
660                 return -1;
661         }
662
663         while (cur != NULL) {
664                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_AUTO_LANGUAGE)) {
665                         if (true == value) {
666                                 xmlNodeSetContent(cur, (const xmlChar *)"on");
667                         } else if (false == value) {
668                                 xmlNodeSetContent(cur, (const xmlChar *)"off");
669                         } else {
670                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong value of auto voice");
671                                 return -1;
672                         }
673                         break;
674                 }
675                 cur = cur->next;
676         }
677
678         int ret = xmlSaveFile(STT_CONFIG, g_config_doc);
679         SLOG(LOG_DEBUG, stt_tag(), "Save result : %d", ret);
680
681         return 0;
682 }
683
684 int stt_parser_set_silence_detection(bool value)
685 {
686         if (NULL == g_config_doc)
687                 return -1;
688
689         xmlNodePtr cur = NULL;
690         cur = xmlDocGetRootElement(g_config_doc);
691         if (cur == NULL) {
692                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
693                 return -1;
694         }
695
696         if (xmlStrcmp(cur->name, (const xmlChar *) STT_TAG_CONFIG_BASE_TAG)) {
697                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT %s", STT_TAG_CONFIG_BASE_TAG);
698                 return -1;
699         }
700
701         cur = cur->xmlChildrenNode;
702         if (cur == NULL) {
703                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
704                 return -1;
705         }
706
707         while (cur != NULL) {
708                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_CONFIG_SILENCE_DETECTION)) {
709                         if (true == value)
710                                 xmlNodeSetContent(cur, (const xmlChar *)"on");
711                         else
712                                 xmlNodeSetContent(cur, (const xmlChar *)"off");
713                 }
714
715                 cur = cur->next;
716         }
717
718         int ret = xmlSaveFile(STT_CONFIG, g_config_doc);
719         SLOG(LOG_DEBUG, stt_tag(), "Save result : %d", ret);
720
721         return 0;
722 }
723 //LCOV_EXCL_STOP
724
725 int stt_parser_find_config_changed(char** engine, char** setting, int* auto_lang, char** language, int* silence, int* credential)
726 {
727         if (NULL == engine || NULL == language || NULL == silence || NULL == credential) {
728                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Input parameter is NULL"); //LCOV_EXCL_LINE
729                 return -1;
730         }
731
732         xmlDocPtr doc = NULL;
733         xmlNodePtr cur_new = NULL;
734         xmlNodePtr cur_old = NULL;
735
736         xmlChar *key_new;
737         xmlChar *key_old;
738
739         doc = xmlParseFile(STT_CONFIG);
740         if (doc == NULL) {
741                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to parse file error : %s", STT_CONFIG);
742                 return -1;
743         }
744
745         cur_new = xmlDocGetRootElement(doc);
746         cur_old = xmlDocGetRootElement(g_config_doc);
747         if (cur_new == NULL || cur_old == NULL) {
748                 //LCOV_EXCL_START
749                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
750                 xmlFreeDoc(doc);
751                 return -1;
752                 //LCOV_EXCL_STOP
753         }
754
755         if (xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_BASE_TAG) || xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_BASE_TAG)) {
756                 //LCOV_EXCL_START
757                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT %s", STT_TAG_CONFIG_BASE_TAG);
758                 xmlFreeDoc(doc);
759                 return -1;
760                 //LCOV_EXCL_STOP
761         }
762
763         cur_new = cur_new->xmlChildrenNode;
764         cur_old = cur_old->xmlChildrenNode;
765         if (cur_new == NULL || cur_old == NULL) {
766                 //LCOV_EXCL_START
767                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
768                 xmlFreeDoc(doc);
769                 return -1;
770                 //LCOV_EXCL_STOP
771         }
772
773         *engine = NULL;
774         *setting = NULL;
775         *language = NULL;
776
777         while (cur_new != NULL && cur_old != NULL) {
778                 if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_ENGINE_ID)) {
779                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_ENGINE_ID)) {
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 id(%s), New engine(%s)", (char*)key_old, (char*)key_new);
786                                                         if (NULL != *engine)    free(*engine);
787                                                         *engine = 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"); //LCOV_EXCL_LINE
795                         }
796                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_ENGINE_SETTING)) {
797                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_ENGINE_SETTING)) {
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 engine setting(%s), New engine setting(%s)", (char*)key_old, (char*)key_new); //LCOV_EXCL_LINE
804                                                         if (NULL != *setting)   free(*setting);
805                                                         *setting = strdup((char*)key_new);
806                                                 }
807                                                 xmlFree(key_new);
808                                         }
809                                         xmlFree(key_old);
810                                 }
811                         } else {
812                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Old config and new config are different"); //LCOV_EXCL_LINE
813                         }
814                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_AUTO_LANGUAGE)) {
815                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_AUTO_LANGUAGE)) {
816                                 key_old = xmlNodeGetContent(cur_old);
817                                 if (NULL != key_old) {
818                                         key_new = xmlNodeGetContent(cur_new);
819                                         if (NULL != key_new) {
820                                                 if (0 != xmlStrcmp(key_old, key_new)) {
821                                                         SLOG(LOG_DEBUG, stt_tag(), "Old auto lang(%s), New auto lang(%s)", (char*)key_old, (char*)key_new); //LCOV_EXCL_LINE
822                                                         if (0 == xmlStrcmp((const xmlChar*)"on", key_new)) {
823                                                                 *auto_lang = (int)true;
824                                                         } else {
825                                                                 *auto_lang = (int)false;
826                                                         }
827                                                 }
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"); //LCOV_EXCL_LINE
835                         }
836                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_LANGUAGE)) {
837                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_LANGUAGE)) {
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 language(%s), New language(%s)", (char*)key_old, (char*)key_new); //LCOV_EXCL_LINE
844                                                         if (NULL != *language)  free(*language);
845                                                         *language = strdup((char*)key_new);
846                                                 }
847                                                 xmlFree(key_new);
848                                         }
849                                         xmlFree(key_old);
850                                 }
851                         } else {
852                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] old config and new config are different"); //LCOV_EXCL_LINE
853                         }
854                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_SILENCE_DETECTION)) {
855                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_SILENCE_DETECTION)) {
856                                 key_old = xmlNodeGetContent(cur_old);
857                                 if (NULL != key_old) {
858                                         key_new = xmlNodeGetContent(cur_new);
859                                         if (NULL != key_new) {
860                                                 if (0 != xmlStrcmp(key_old, key_new)) {
861                                                         SLOG(LOG_DEBUG, stt_tag(), "Old silence(%s), New silence(%s)", (char*)key_old, (char*)key_new); //LCOV_EXCL_LINE
862                                                         if (0 == xmlStrcmp(key_new, (const xmlChar*)"on")) {
863                                                                 *silence = 1;
864                                                         } else {
865                                                                 *silence = 0;
866                                                         }
867                                                 }
868
869                                                 xmlFree(key_new);
870                                         }
871                                         xmlFree(key_old);
872                                 }
873                         } else {
874                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] old config and new config are different"); //LCOV_EXCL_LINE
875                         }
876                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)STT_TAG_CONFIG_CREDENTIAL)) {
877                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)STT_TAG_CONFIG_CREDENTIAL)) {
878                                 key_old = xmlNodeGetContent(cur_old);
879                                 if (NULL != key_old) {
880                                         key_new = xmlNodeGetContent(cur_new);
881                                         if (NULL != key_new) {
882                                                 if (0 != xmlStrcmp(key_old, key_new)) {
883                                                         SLOG(LOG_DEBUG, stt_tag(), "Old credential(%s), New credential(%s)", (char*)key_old, (char*)key_new); //LCOV_EXCL_LINE
884                                                         if (0 == xmlStrcmp(key_new, (const xmlChar*)"true")) {
885                                                                 *credential = 1;
886                                                         } else {
887                                                                 *credential = 0;
888                                                         }
889                                                 }
890                                                 xmlFree(key_new);
891                                         }
892                                         xmlFree(key_old);
893                                 }
894                         } else {
895                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] old config and new config are different"); //LCOV_EXCL_LINE
896                         }
897
898                 } else {
899
900                 }
901
902                 cur_new = cur_new->next;
903                 cur_old = cur_old->next;
904         }
905
906         xmlFreeDoc(g_config_doc);
907         g_config_doc = doc;
908
909         return 0;
910 }
911
912 /**
913 * time function
914 */
915 //LCOV_EXCL_START
916 int stt_parser_set_time_info(GSList* time_list)
917 {
918         if (0 == g_slist_length(time_list)) {
919                 SLOG(LOG_WARN, stt_tag(), "[WARNING] There is no time info to save");
920                 return -1;
921         }
922
923         if (-1 == remove(STT_TIME_INFO_PATH)) {
924                 SLOG(LOG_WARN, stt_tag(), "[PLAYER WARNING] Fail to remove file(%s)", STT_TIME_INFO_PATH);
925         }
926
927         xmlDocPtr doc = NULL;
928         xmlNodePtr cur = NULL;
929
930         doc = xmlNewDoc((const xmlChar*)"1.0");
931         if (doc == NULL) {
932                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Fail to make new doc");
933                 return -1;
934         }
935
936         cur = xmlNewNode(NULL, (const xmlChar*)STT_TAG_TIME_BASE_TAG);
937         xmlDocSetRootElement(doc, cur);
938
939         xmlNodePtr inode = NULL;
940         GSList *iter = NULL;
941         stt_result_time_info_s *data = NULL;
942         char temp_str[256];
943
944         snprintf(temp_str, 256, "%d", g_slist_length(time_list));
945
946         inode = xmlNewNode(NULL, (const xmlChar*)STT_TAG_TIME_INDEX);
947         xmlNewProp(inode, (const xmlChar*)STT_TAG_TIME_COUNT, (const xmlChar*)temp_str);
948         xmlAddChild(cur, inode);
949
950         /* Get a first item */
951         iter = g_slist_nth(time_list, 0);
952         while (NULL != iter) {
953                 data = iter->data;
954
955                 if (NULL == data) {
956                         SLOG(LOG_DEBUG, stt_tag(), "data is NULL");
957                         continue;
958                 }
959
960                 xmlNodePtr temp_node = NULL;
961
962                 SECURE_SLOG(LOG_DEBUG, stt_tag(), "[%d] i(%d) t(%s) s(%ld) e(%ld)",
963                         data->index, data->event, data->text, data->start_time, data->end_time);
964
965                 temp_node = xmlNewNode(NULL, (const xmlChar*)STT_TAG_TIME_TEXT);
966                 xmlNodeSetContent(temp_node, (const xmlChar*)data->text);
967                 xmlAddChild(inode, temp_node);
968
969                 temp_node = xmlNewNode(NULL, (const xmlChar*)STT_TAG_TIME_START);
970                 snprintf(temp_str, 256, "%ld", data->start_time);
971                 xmlNodeSetContent(temp_node, (const xmlChar*)temp_str);
972                 xmlAddChild(inode, temp_node);
973
974                 temp_node = xmlNewNode(NULL, (const xmlChar*)STT_TAG_TIME_END);
975                 snprintf(temp_str, 256, "%ld", data->end_time);
976                 xmlNodeSetContent(temp_node, (const xmlChar*)temp_str);
977                 xmlAddChild(inode, temp_node);
978
979                 /*Get next item*/
980                 iter = g_slist_next(iter);
981         }
982
983         int ret = xmlSaveFormatFile(STT_TIME_INFO_PATH, doc, 1);
984         SLOG(LOG_DEBUG, stt_tag(), "Save result : %d", ret);
985
986         xmlFreeDoc(doc);
987         return 0;
988 }
989 //LCOV_EXCL_STOP
990
991 void __stt_parser_time_info_free(void* data)
992 {
993         stt_result_time_info_s* time_info = (stt_result_time_info_s*)data;
994
995         if (NULL != time_info) {
996                 if (NULL != time_info->text) {
997                         free(time_info->text);
998                         time_info->text = NULL;
999                 }
1000
1001                 free(time_info);
1002         }
1003 }
1004
1005 int stt_parser_get_time_info(GSList** time_list)
1006 {
1007         if (NULL == time_list) {
1008                 SLOG(LOG_ERROR, stt_tag(), "Invalid parameter : text is NULL"); //LCOV_EXCL_LINE
1009                 return -1;
1010         }
1011
1012         xmlDocPtr doc = NULL;
1013         xmlNodePtr cur = NULL;
1014
1015         doc = xmlParseFile(STT_TIME_INFO_PATH);
1016         if (doc == NULL) {
1017                 SLOG(LOG_WARN, stt_tag(), "[WARNING] File is not exist"); //LCOV_EXCL_LINE
1018                 return -1;
1019         }
1020
1021         cur = xmlDocGetRootElement(doc);
1022         if (cur == NULL) {
1023                 //LCOV_EXCL_START
1024                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
1025                 xmlFreeDoc(doc);
1026                 return -1;
1027                 //LCOV_EXCL_STOP
1028         }
1029
1030         if (xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_TIME_BASE_TAG)) {
1031                 //LCOV_EXCL_START
1032                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] The wrong type, root node is NOT '%s'", STT_TAG_TIME_BASE_TAG);
1033                 xmlFreeDoc(doc);
1034                 return -1;
1035                 //LCOV_EXCL_STOP
1036         }
1037
1038         cur = cur->xmlChildrenNode;
1039         if (cur == NULL) {
1040                 //LCOV_EXCL_START
1041                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] Empty document");
1042                 xmlFreeDoc(doc);
1043                 return -1;
1044                 //LCOV_EXCL_STOP
1045         }
1046
1047         /* alloc time info */
1048         GSList *temp_time_list = NULL;
1049         xmlChar *key = NULL;
1050         int index = 0;
1051
1052         while (cur != NULL) {
1053                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)STT_TAG_TIME_INDEX)) {
1054                         key = xmlGetProp(cur, (const xmlChar*)STT_TAG_TIME_COUNT);
1055                         if (NULL == key) {
1056                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_TIME_COUNT); //LCOV_EXCL_LINE
1057
1058                                 if (NULL != temp_time_list) {
1059                                         g_slist_free_full(temp_time_list, __stt_parser_time_info_free);
1060                                         temp_time_list = NULL;
1061                                 }
1062                                 xmlFreeDoc(doc);
1063                                 return -1;
1064                         }
1065
1066                         SLOG(LOG_DEBUG, stt_tag(), "Count : %s", (char *)key);
1067
1068                         /* Get time count */
1069                         int count = 0;
1070                         count = atoi((char*)key);
1071                         xmlFree(key);
1072
1073                         if (count <= 0) {
1074                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] count is invalid : %d", count); //LCOV_EXCL_LINE
1075                                 break;
1076                         }
1077
1078                         xmlNodePtr time_node = NULL;
1079                         time_node = cur->xmlChildrenNode;
1080
1081                         int i = 0;
1082                         for (i = 0; i < count; i++) {
1083                                 /* text */
1084                                 time_node = time_node->next;
1085
1086                                 stt_result_time_info_s* temp_info;
1087                                 temp_info = (stt_result_time_info_s*)calloc(1, sizeof(stt_result_time_info_s));
1088
1089                                 if (NULL == temp_info) {
1090                                         SLOG(LOG_ERROR, stt_tag(), "[ERROR] Memory alloc error!!"); //LCOV_EXCL_LINE
1091
1092                                         if (NULL != temp_time_list) {
1093                                                 g_slist_free_full(temp_time_list, __stt_parser_time_info_free);
1094                                                 temp_time_list = NULL;
1095                                         }
1096                                         xmlFreeDoc(doc);
1097                                         return -1;
1098                                 }
1099
1100                                 temp_info->index = index;
1101                                 SLOG(LOG_DEBUG, stt_tag(), "index : %d", temp_info->index);
1102
1103                                 if (0 == i)             temp_info->event = 0;
1104                                 else if (count -1 == i) temp_info->event = 2;
1105                                 else                    temp_info->event = 1;
1106
1107                                 if (0 == xmlStrcmp(time_node->name, (const xmlChar *)STT_TAG_TIME_TEXT)) {
1108                                         key = xmlNodeGetContent(time_node);
1109                                         if (NULL != key) {
1110                                                 SLOG(LOG_DEBUG, stt_tag(), "text : %s", (char *)key); //LCOV_EXCL_LINE
1111                                                 temp_info->text = strdup((char*)key);
1112                                                 xmlFree(key);
1113                                         } else {
1114                                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_TIME_TEXT); //LCOV_EXCL_LINE
1115                                                 free(temp_info);
1116                                                 break;
1117                                         }
1118                                 }
1119
1120                                 /* text */
1121                                 time_node = time_node->next;
1122                                 time_node = time_node->next;
1123
1124                                 if (0 == xmlStrcmp(time_node->name, (const xmlChar *)STT_TAG_TIME_START)) {
1125                                         key = xmlNodeGetContent(time_node);
1126                                         if (NULL != key) {
1127                                                 SLOG(LOG_DEBUG, stt_tag(), "Start time : %s", (char *)key); //LCOV_EXCL_LINE
1128                                                 temp_info->start_time = atoi((char*)key);
1129                                                 xmlFree(key);
1130                                         } else {
1131                                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_TIME_START); //LCOV_EXCL_LINE
1132                                                 if (NULL != temp_info->text)    free(temp_info->text);
1133                                                 free(temp_info);
1134                                                 break;
1135                                         }
1136                                 }
1137
1138                                 /* text */
1139                                 time_node = time_node->next;
1140                                 time_node = time_node->next;
1141
1142                                 if (0 == xmlStrcmp(time_node->name, (const xmlChar *)STT_TAG_TIME_END)) {
1143                                         key = xmlNodeGetContent(time_node);
1144                                         if (NULL != key) {
1145                                                 SLOG(LOG_DEBUG, stt_tag(), "End time : %s", (char *)key); //LCOV_EXCL_LINE
1146                                                 temp_info->end_time = atoi((char*)key);
1147                                                 xmlFree(key);
1148                                         } else {
1149                                                 SLOG(LOG_ERROR, stt_tag(), "[ERROR] <%s> has no content", STT_TAG_TIME_END); //LCOV_EXCL_LINE
1150                                                 if (NULL != temp_info->text)    free(temp_info->text);
1151                                                 free(temp_info);
1152                                                 break;
1153                                         }
1154                                 }
1155
1156                                 time_node = time_node->next;
1157
1158                                 temp_time_list = g_slist_append(temp_time_list, temp_info);
1159                         } /* for */
1160                         index++;
1161                 } /* if */
1162                 cur = cur->next;
1163         }
1164
1165         xmlFreeDoc(doc);
1166
1167         *time_list = temp_time_list;
1168
1169         return 0;
1170 }
1171
1172 int stt_parser_clear_time_info()
1173 {
1174         if (-1 == remove(STT_TIME_INFO_PATH)) {
1175                 /* SLOG(LOG_WARN, stt_tag(), "[PLAYER WARNING] Fail to remove file(%s)", STT_TIME_INFO_PATH); */
1176         }
1177
1178         return 0;
1179 }