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