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